All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/12] Introducing Exynos ChipId driver
       [not found] <CGME20170330131417epcas1p48a7f41b90177294b7918ecf31df130d1@epcas1p4.samsung.com>
@ 2017-03-30 13:16   ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

Each Exynos SoC has ChipID block which can give information about SoC's
product Id and revision number.

This patch series introduces Exynos Chipid SoC driver. At the same time
it reduces dependency of mach-exynos files from plat-samsung, by removing
soc_is_exynosMMMM and samsung_rev API. Instead of it now we can use
soc_device_match API.

Until now we are using static mapping of Exynos Chipid and using this
static mapping to know about SoC name and revision via soc_is_exynosMMMM
macro. This is quite cumbersome and every time new ARMv7 based Exynos SoC
supports lands in mainline a bunch of such new macros needs to be added.
Quite long back during support of Exynos5260 it has been discussed to
solve this problem.

To solve this issue this patchset replaces use of soc_is_exynosMMMM by
either of_machine_is_compatible or soc_device_match depending upon usecase.

I have tested this patch series on Exynos4210 based Origen board for normal
SMP boot.

Although I submitted this series as a whole of 12 patchsets, following are
dependency details among the patches.

Patch 1/12 to 3/12 can be taken without any dependency on other patches.
Patch 4/12 to 6/12 can be taken witout any dependency on other patches.
Patch 7/12 to 12/12 has dependency on patches 1/12 to 6/12

Revision 8 and it's discussion can be found here:
 - https://www.spinics.net/lists/arm-kernel/msg548384.html

Revision 7 and it's discussion can be found here:
 - https://www.spinics.net/lists/arm-kernel/msg540790.html

Revision 6 and it's discussion can be found here:
 - https://lkml.org/lkml/2016/5/25/101

Revision 5 and it's discussion can be found here:
 - http://lists.infradead.org/pipermail/linux-arm-kernel/2014-December/310046.html

Revision 4 and it's discussion can be found here:
 - https://lkml.org/lkml/2014/12/3/115

Changes since v8:
 - Reordered patch sequences so that independent patches can be taken
   without any dependency issues among the patches.
 - Broken down patche Patch v8 5/8 into three patches as per suggestion
   from Krzysztof.
 - Addressed concerns raised from Andrzej and Bartlomiej.
 - Fixed mask values for exynos4 based SoCs.
 - Rebased patches on latest krzk/for-next
 - Addressed various comments from Krzysztof 

Changes since v7:
 - Added ARM64 based Exynos7 and Exynos5433 support in chipid driver.
 - Removed Exynos4415 support from chipid driver, as exynos4415 has been removed from tree
 - Added patch to enable chipid driver for ARM64 based Exynos platform
 - Addressed review comments from Arnd for firmware.c, platsmp.c and pm.c files/
 - Splitted changes in firmware.c, platsmp.c and pm.c in separate patches 
   for better code review
 - Included suggested code improvement in exynos-chipid.c from Marek Szyprowski

Chances since v6:
 - Removed platform driver from chipid, instead use early_init to register soc_device
 - Removed export functions from exynos chipid driver
 - Replace soc_is_exynosMMMM via either of_machine_is_compatible or soc_device_match in
   files in arm/mach-exynos folder
 - This patchset depends on the following patch series by Geert Uytterhoeven. This series
   includes patch which introduces soc_device_match.
   http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1261739.html
 - Rebased on latest krzk/for-next branch and retested.

Change since v5:
 - Addressed Rob's review comments.
 - Rebased on latest krzk/for-next branch and retested.

Changes since v4:
 - Removed custom sysfs entries as they were not providing any new information
   as pointed out by Arnd.
 - Removed functions exporting product_id and revision, instead we will export
   exynos_chipid_info structure. It will be helpful when we need to provide more
   fields of chipid outside of chipid, as commented by Yadwinder
 - Converted all funcions as __init. 

Change since v3: 
 - This patch set contains 5/6 and 6/6 patch from v3 series.
 - Made EXYNOS_CHIPID config option non-user selectable,
   as suggested by Tomasz Figa.
 - Made uniform macro for EXYNOS4/5_SOC_MASK as EXYNOS_SOC_MASK as
   suggested by Tomasz Figa.
 - Made local variables static in chipid driver.
 - Added existing SoC's product id's.
 - Added platform driver support.

Changes since v2:
 - Reorganized patches as suggested by Tomasz Figa.
 - Addressed review comments of Tomasz Figa in i2c-s3c2410.c file.


Pankaj Dubey (12):
  ARM: EXYNOS: refactor firmware specific routines
  ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
  ARM: EXYNOS: remove secondary startup initialization from
    smp_prepare_cpus
  soc: samsung: add exynos chipid driver support
  ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
  ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
  ARM: EXYNOS: introduce soc specific pm ops
  ARM: EXYNOS: move exynos_boot_vector_{addr,flag} ops to
    exynos_s2r_data
  ARM: EXYNOS: introduce exynos_cpu_info struct
  ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
  ARM: EXYNOS: move cpu_restart as a SoC specific hook to
    exynos_cpu_info
  ARM: EXYNOS: refactor of mach-exynos to use chipid information

 arch/arm/mach-exynos/Kconfig                 |   1 +
 arch/arm/mach-exynos/common.h                |  97 -----------
 arch/arm/mach-exynos/exynos.c                |  44 ++---
 arch/arm/mach-exynos/firmware.c              | 114 +++++++++---
 arch/arm/mach-exynos/platsmp.c               | 249 +++++++++++++++++++++------
 arch/arm/mach-exynos/pm.c                    | 200 ++++++++++++++++++---
 arch/arm/plat-samsung/cpu.c                  |  14 --
 arch/arm/plat-samsung/include/plat/cpu.h     |   2 -
 arch/arm/plat-samsung/include/plat/map-s5p.h |   2 -
 arch/arm64/Kconfig.platforms                 |   1 +
 drivers/soc/samsung/Kconfig                  |   5 +
 drivers/soc/samsung/Makefile                 |   1 +
 drivers/soc/samsung/exynos-chipid.c          | 109 ++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h  |   3 +
 14 files changed, 587 insertions(+), 255 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-chipid.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 00/12] Introducing Exynos ChipId driver
@ 2017-03-30 13:16   ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

Each Exynos SoC has ChipID block which can give information about SoC's
product Id and revision number.

This patch series introduces Exynos Chipid SoC driver. At the same time
it reduces dependency of mach-exynos files from plat-samsung, by removing
soc_is_exynosMMMM and samsung_rev API. Instead of it now we can use
soc_device_match API.

Until now we are using static mapping of Exynos Chipid and using this
static mapping to know about SoC name and revision via soc_is_exynosMMMM
macro. This is quite cumbersome and every time new ARMv7 based Exynos SoC
supports lands in mainline a bunch of such new macros needs to be added.
Quite long back during support of Exynos5260 it has been discussed to
solve this problem.

To solve this issue this patchset replaces use of soc_is_exynosMMMM by
either of_machine_is_compatible or soc_device_match depending upon usecase.

I have tested this patch series on Exynos4210 based Origen board for normal
SMP boot.

Although I submitted this series as a whole of 12 patchsets, following are
dependency details among the patches.

Patch 1/12 to 3/12 can be taken without any dependency on other patches.
Patch 4/12 to 6/12 can be taken witout any dependency on other patches.
Patch 7/12 to 12/12 has dependency on patches 1/12 to 6/12

Revision 8 and it's discussion can be found here:
 - https://www.spinics.net/lists/arm-kernel/msg548384.html

Revision 7 and it's discussion can be found here:
 - https://www.spinics.net/lists/arm-kernel/msg540790.html

Revision 6 and it's discussion can be found here:
 - https://lkml.org/lkml/2016/5/25/101

Revision 5 and it's discussion can be found here:
 - http://lists.infradead.org/pipermail/linux-arm-kernel/2014-December/310046.html

Revision 4 and it's discussion can be found here:
 - https://lkml.org/lkml/2014/12/3/115

Changes since v8:
 - Reordered patch sequences so that independent patches can be taken
   without any dependency issues among the patches.
 - Broken down patche Patch v8 5/8 into three patches as per suggestion
   from Krzysztof.
 - Addressed concerns raised from Andrzej and Bartlomiej.
 - Fixed mask values for exynos4 based SoCs.
 - Rebased patches on latest krzk/for-next
 - Addressed various comments from Krzysztof 

Changes since v7:
 - Added ARM64 based Exynos7 and Exynos5433 support in chipid driver.
 - Removed Exynos4415 support from chipid driver, as exynos4415 has been removed from tree
 - Added patch to enable chipid driver for ARM64 based Exynos platform
 - Addressed review comments from Arnd for firmware.c, platsmp.c and pm.c files/
 - Splitted changes in firmware.c, platsmp.c and pm.c in separate patches 
   for better code review
 - Included suggested code improvement in exynos-chipid.c from Marek Szyprowski

Chances since v6:
 - Removed platform driver from chipid, instead use early_init to register soc_device
 - Removed export functions from exynos chipid driver
 - Replace soc_is_exynosMMMM via either of_machine_is_compatible or soc_device_match in
   files in arm/mach-exynos folder
 - This patchset depends on the following patch series by Geert Uytterhoeven. This series
   includes patch which introduces soc_device_match.
   http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1261739.html
 - Rebased on latest krzk/for-next branch and retested.

Change since v5:
 - Addressed Rob's review comments.
 - Rebased on latest krzk/for-next branch and retested.

Changes since v4:
 - Removed custom sysfs entries as they were not providing any new information
   as pointed out by Arnd.
 - Removed functions exporting product_id and revision, instead we will export
   exynos_chipid_info structure. It will be helpful when we need to provide more
   fields of chipid outside of chipid, as commented by Yadwinder
 - Converted all funcions as __init. 

Change since v3: 
 - This patch set contains 5/6 and 6/6 patch from v3 series.
 - Made EXYNOS_CHIPID config option non-user selectable,
   as suggested by Tomasz Figa.
 - Made uniform macro for EXYNOS4/5_SOC_MASK as EXYNOS_SOC_MASK as
   suggested by Tomasz Figa.
 - Made local variables static in chipid driver.
 - Added existing SoC's product id's.
 - Added platform driver support.

Changes since v2:
 - Reorganized patches as suggested by Tomasz Figa.
 - Addressed review comments of Tomasz Figa in i2c-s3c2410.c file.


Pankaj Dubey (12):
  ARM: EXYNOS: refactor firmware specific routines
  ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
  ARM: EXYNOS: remove secondary startup initialization from
    smp_prepare_cpus
  soc: samsung: add exynos chipid driver support
  ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
  ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
  ARM: EXYNOS: introduce soc specific pm ops
  ARM: EXYNOS: move exynos_boot_vector_{addr,flag} ops to
    exynos_s2r_data
  ARM: EXYNOS: introduce exynos_cpu_info struct
  ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
  ARM: EXYNOS: move cpu_restart as a SoC specific hook to
    exynos_cpu_info
  ARM: EXYNOS: refactor of mach-exynos to use chipid information

 arch/arm/mach-exynos/Kconfig                 |   1 +
 arch/arm/mach-exynos/common.h                |  97 -----------
 arch/arm/mach-exynos/exynos.c                |  44 ++---
 arch/arm/mach-exynos/firmware.c              | 114 +++++++++---
 arch/arm/mach-exynos/platsmp.c               | 249 +++++++++++++++++++++------
 arch/arm/mach-exynos/pm.c                    | 200 ++++++++++++++++++---
 arch/arm/plat-samsung/cpu.c                  |  14 --
 arch/arm/plat-samsung/include/plat/cpu.h     |   2 -
 arch/arm/plat-samsung/include/plat/map-s5p.h |   2 -
 arch/arm64/Kconfig.platforms                 |   1 +
 drivers/soc/samsung/Kconfig                  |   5 +
 drivers/soc/samsung/Makefile                 |   1 +
 drivers/soc/samsung/exynos-chipid.c          | 109 ++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h  |   3 +
 14 files changed, 587 insertions(+), 255 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-chipid.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines
       [not found]   ` <CGME20170330131419epcas5p4ac36250d3a9225643e327e60f47956c2@epcas5p4.samsung.com>
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

To remove dependency on soc_is_exynosMMMM macros and remove multiple
checks for such macros, let's refactor code in firmware.c file.
SoC specific firmware_ops are separated and registered during
exynos_firmware_init based on matching machine compatible.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/firmware.c | 114 +++++++++++++++++++++++++++++++---------
 1 file changed, 89 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index e81a78b..b04c47a 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -35,6 +35,25 @@ static void exynos_save_cp15(void)
 	     : : "cc");
 }
 
+static int exynos3250_do_idle(unsigned long mode)
+{
+	switch (mode) {
+	case FW_DO_IDLE_AFTR:
+		writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
+			       sysram_ns_base_addr + 0x24);
+		writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
+		flush_cache_all();
+		exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
+				SMC_POWERSTATE_IDLE, 0);
+		exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
+				SMC_POWERSTATE_IDLE, 0);
+		break;
+	case FW_DO_IDLE_SLEEP:
+		exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+	}
+	return 0;
+}
+
 static int exynos_do_idle(unsigned long mode)
 {
 	switch (mode) {
@@ -44,14 +63,7 @@ static int exynos_do_idle(unsigned long mode)
 		writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
 			       sysram_ns_base_addr + 0x24);
 		writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
-		if (soc_is_exynos3250()) {
-			flush_cache_all();
-			exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
-				   SMC_POWERSTATE_IDLE, 0);
-			exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
-				   SMC_POWERSTATE_IDLE, 0);
-		} else
-			exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
+		exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
 		break;
 	case FW_DO_IDLE_SLEEP:
 		exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
@@ -59,28 +71,25 @@ static int exynos_do_idle(unsigned long mode)
 	return 0;
 }
 
-static int exynos_cpu_boot(int cpu)
+static int exynos4212_cpu_boot(int cpu)
 {
 	/*
-	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
-	 * because Exynos3250 removes WFE in secure mode.
-	 */
-	if (soc_is_exynos3250())
-		return 0;
-
-	/*
 	 * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
 	 * But, Exynos4212 has only one secondary CPU so second parameter
 	 * isn't used for informing secure firmware about CPU id.
 	 */
-	if (soc_is_exynos4212())
-		cpu = 0;
+	cpu = 0;
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}
 
+static int exynos_cpu_boot(int cpu)
+{
 	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
 	return 0;
 }
 
-static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+static int exynos4412_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
 {
 	void __iomem *boot_reg;
 
@@ -94,14 +103,24 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
 	 * additional offset for every CPU, with Exynos4412 being the only
 	 * exception.
 	 */
-	if (soc_is_exynos4412())
-		boot_reg += 4 * cpu;
+	boot_reg += 4 * cpu;
+	writel_relaxed(boot_addr, boot_reg);
+	return 0;
+}
+
+static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+{
+	void __iomem *boot_reg;
+
+	if (!sysram_ns_base_addr)
+		return -ENODEV;
 
+	boot_reg = sysram_ns_base_addr + 0x1c;
 	writel_relaxed(boot_addr, boot_reg);
 	return 0;
 }
 
-static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
+static int exynos4412_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
 {
 	void __iomem *boot_reg;
 
@@ -109,10 +128,19 @@ static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
 		return -ENODEV;
 
 	boot_reg = sysram_ns_base_addr + 0x1c;
+	boot_reg += 4 * cpu;
+	*boot_addr = readl_relaxed(boot_reg);
+	return 0;
+}
+
+static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
+{
+	void __iomem *boot_reg;
 
-	if (soc_is_exynos4412())
-		boot_reg += 4 * cpu;
+	if (!sysram_ns_base_addr)
+		return -ENODEV;
 
+	boot_reg = sysram_ns_base_addr + 0x1c;
 	*boot_addr = readl_relaxed(boot_reg);
 	return 0;
 }
@@ -148,6 +176,32 @@ static int exynos_resume(void)
 	return 0;
 }
 
+static const struct firmware_ops exynos3250_firmware_ops = {
+	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos3250_do_idle : NULL,
+	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
+	.get_cpu_boot_addr	= exynos_get_cpu_boot_addr,
+	.suspend		= IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+	.resume			= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
+static const struct firmware_ops exynos4212_firmware_ops = {
+	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
+	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
+	.get_cpu_boot_addr	= exynos_get_cpu_boot_addr,
+	.cpu_boot		= exynos4212_cpu_boot,
+	.suspend		= IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+	.resume			= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
+static const struct firmware_ops exynos4412_firmware_ops = {
+	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
+	.set_cpu_boot_addr	= exynos4412_set_cpu_boot_addr,
+	.get_cpu_boot_addr	= exynos4412_get_cpu_boot_addr,
+	.cpu_boot		= exynos_cpu_boot,
+	.suspend		= IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+	.resume			= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
 static const struct firmware_ops exynos_firmware_ops = {
 	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
 	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
@@ -198,6 +252,7 @@ void __init exynos_firmware_init(void)
 {
 	struct device_node *nd;
 	const __be32 *addr;
+	const struct firmware_ops *ops;
 
 	nd = of_find_compatible_node(NULL, NULL,
 					"samsung,secure-firmware");
@@ -212,7 +267,16 @@ void __init exynos_firmware_init(void)
 
 	pr_info("Running under secure firmware.\n");
 
-	register_firmware_ops(&exynos_firmware_ops);
+	if (of_machine_is_compatible("samsung,exynos3250"))
+		ops = &exynos3250_firmware_ops;
+	else if (of_machine_is_compatible("samsung,exynos4212"))
+		ops = &exynos4212_firmware_ops;
+	else if (of_machine_is_compatible("samsung,exynos4412"))
+		ops = &exynos4412_firmware_ops;
+	else
+		ops = &exynos_firmware_ops;
+
+	register_firmware_ops(ops);
 
 	/*
 	 * Exynos 4 SoCs (based on Cortex A9 and equipped with L2C-310),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

To remove dependency on soc_is_exynosMMMM macros and remove multiple
checks for such macros, let's refactor code in firmware.c file.
SoC specific firmware_ops are separated and registered during
exynos_firmware_init based on matching machine compatible.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/firmware.c | 114 +++++++++++++++++++++++++++++++---------
 1 file changed, 89 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index e81a78b..b04c47a 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -35,6 +35,25 @@ static void exynos_save_cp15(void)
 	     : : "cc");
 }
 
+static int exynos3250_do_idle(unsigned long mode)
+{
+	switch (mode) {
+	case FW_DO_IDLE_AFTR:
+		writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
+			       sysram_ns_base_addr + 0x24);
+		writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
+		flush_cache_all();
+		exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
+				SMC_POWERSTATE_IDLE, 0);
+		exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
+				SMC_POWERSTATE_IDLE, 0);
+		break;
+	case FW_DO_IDLE_SLEEP:
+		exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+	}
+	return 0;
+}
+
 static int exynos_do_idle(unsigned long mode)
 {
 	switch (mode) {
@@ -44,14 +63,7 @@ static int exynos_do_idle(unsigned long mode)
 		writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
 			       sysram_ns_base_addr + 0x24);
 		writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
-		if (soc_is_exynos3250()) {
-			flush_cache_all();
-			exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
-				   SMC_POWERSTATE_IDLE, 0);
-			exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
-				   SMC_POWERSTATE_IDLE, 0);
-		} else
-			exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
+		exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
 		break;
 	case FW_DO_IDLE_SLEEP:
 		exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
@@ -59,28 +71,25 @@ static int exynos_do_idle(unsigned long mode)
 	return 0;
 }
 
-static int exynos_cpu_boot(int cpu)
+static int exynos4212_cpu_boot(int cpu)
 {
 	/*
-	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
-	 * because Exynos3250 removes WFE in secure mode.
-	 */
-	if (soc_is_exynos3250())
-		return 0;
-
-	/*
 	 * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
 	 * But, Exynos4212 has only one secondary CPU so second parameter
 	 * isn't used for informing secure firmware about CPU id.
 	 */
-	if (soc_is_exynos4212())
-		cpu = 0;
+	cpu = 0;
+	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+	return 0;
+}
 
+static int exynos_cpu_boot(int cpu)
+{
 	exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
 	return 0;
 }
 
-static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+static int exynos4412_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
 {
 	void __iomem *boot_reg;
 
@@ -94,14 +103,24 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
 	 * additional offset for every CPU, with Exynos4412 being the only
 	 * exception.
 	 */
-	if (soc_is_exynos4412())
-		boot_reg += 4 * cpu;
+	boot_reg += 4 * cpu;
+	writel_relaxed(boot_addr, boot_reg);
+	return 0;
+}
+
+static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+{
+	void __iomem *boot_reg;
+
+	if (!sysram_ns_base_addr)
+		return -ENODEV;
 
+	boot_reg = sysram_ns_base_addr + 0x1c;
 	writel_relaxed(boot_addr, boot_reg);
 	return 0;
 }
 
-static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
+static int exynos4412_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
 {
 	void __iomem *boot_reg;
 
@@ -109,10 +128,19 @@ static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
 		return -ENODEV;
 
 	boot_reg = sysram_ns_base_addr + 0x1c;
+	boot_reg += 4 * cpu;
+	*boot_addr = readl_relaxed(boot_reg);
+	return 0;
+}
+
+static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
+{
+	void __iomem *boot_reg;
 
-	if (soc_is_exynos4412())
-		boot_reg += 4 * cpu;
+	if (!sysram_ns_base_addr)
+		return -ENODEV;
 
+	boot_reg = sysram_ns_base_addr + 0x1c;
 	*boot_addr = readl_relaxed(boot_reg);
 	return 0;
 }
@@ -148,6 +176,32 @@ static int exynos_resume(void)
 	return 0;
 }
 
+static const struct firmware_ops exynos3250_firmware_ops = {
+	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos3250_do_idle : NULL,
+	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
+	.get_cpu_boot_addr	= exynos_get_cpu_boot_addr,
+	.suspend		= IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+	.resume			= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
+static const struct firmware_ops exynos4212_firmware_ops = {
+	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
+	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
+	.get_cpu_boot_addr	= exynos_get_cpu_boot_addr,
+	.cpu_boot		= exynos4212_cpu_boot,
+	.suspend		= IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+	.resume			= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
+static const struct firmware_ops exynos4412_firmware_ops = {
+	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
+	.set_cpu_boot_addr	= exynos4412_set_cpu_boot_addr,
+	.get_cpu_boot_addr	= exynos4412_get_cpu_boot_addr,
+	.cpu_boot		= exynos_cpu_boot,
+	.suspend		= IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
+	.resume			= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
+};
+
 static const struct firmware_ops exynos_firmware_ops = {
 	.do_idle		= IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
 	.set_cpu_boot_addr	= exynos_set_cpu_boot_addr,
@@ -198,6 +252,7 @@ void __init exynos_firmware_init(void)
 {
 	struct device_node *nd;
 	const __be32 *addr;
+	const struct firmware_ops *ops;
 
 	nd = of_find_compatible_node(NULL, NULL,
 					"samsung,secure-firmware");
@@ -212,7 +267,16 @@ void __init exynos_firmware_init(void)
 
 	pr_info("Running under secure firmware.\n");
 
-	register_firmware_ops(&exynos_firmware_ops);
+	if (of_machine_is_compatible("samsung,exynos3250"))
+		ops = &exynos3250_firmware_ops;
+	else if (of_machine_is_compatible("samsung,exynos4212"))
+		ops = &exynos4212_firmware_ops;
+	else if (of_machine_is_compatible("samsung,exynos4412"))
+		ops = &exynos4412_firmware_ops;
+	else
+		ops = &exynos_firmware_ops;
+
+	register_firmware_ops(ops);
 
 	/*
 	 * Exynos 4 SoCs (based on Cortex A9 and equipped with L2C-310),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
       [not found]   ` <CGME20170330131421epcas5p40b0ad9c1003d3ab807667ae2b05d25bc@epcas5p4.samsung.com>
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
driver, so let's remove/minimize usage of any such helper function usage
from pm.c.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
 include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 1a7e5b5..4a73b02 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
 }
 
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
-static void exynos_set_wakeupmask(long mask)
+static void exynos_set_wakeupmask(void)
 {
-	pmu_raw_writel(mask, S5P_WAKEUP_MASK);
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250")) {
+		pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
 		pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
+	} else
+		pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
 }
 
 static void exynos_cpu_set_boot_vector(long flags)
@@ -141,7 +143,7 @@ static int exynos_aftr_finisher(unsigned long flags)
 {
 	int ret;
 
-	exynos_set_wakeupmask(soc_is_exynos3250() ? 0x40003ffe : 0x0000ff3e);
+	exynos_set_wakeupmask();
 	/* Set value of power down register for aftr mode */
 	exynos_sys_powerdown_conf(SYS_AFTR);
 
@@ -162,7 +164,7 @@ void exynos_enter_aftr(void)
 
 	cpu_pm_enter();
 
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		exynos_set_boot_flag(cpuid, C2_STATE);
 
 	exynos_pm_central_suspend();
@@ -184,7 +186,7 @@ void exynos_enter_aftr(void)
 
 	exynos_pm_central_resume();
 
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		exynos_clear_boot_flag(cpuid, C2_STATE);
 
 	cpu_pm_exit();
@@ -255,7 +257,7 @@ static int exynos_cpu0_enter_aftr(void)
 		while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
 			cpu_relax();
 
-		if (soc_is_exynos3250()) {
+		if (of_machine_is_compatible("samsung,exynos3250")) {
 			while (!pmu_raw_readl(S5P_PMU_SPARE2) &&
 			       !atomic_read(&cpu1_wakeup))
 				cpu_relax();
@@ -277,7 +279,7 @@ static int exynos_cpu0_enter_aftr(void)
 
 			call_firmware_op(cpu_boot, 1);
 
-			if (soc_is_exynos3250())
+			if (of_machine_is_compatible("samsung,exynos3250"))
 				dsb_sev();
 			else
 				arch_send_wakeup_ipi_mask(cpumask_of(1));
@@ -289,7 +291,7 @@ static int exynos_cpu0_enter_aftr(void)
 
 static int exynos_wfi_finisher(unsigned long flags)
 {
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		flush_cache_all();
 	cpu_do_idle();
 
@@ -311,7 +313,7 @@ static int exynos_cpu1_powerdown(void)
 	 */
 	exynos_cpu_power_down(1);
 
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		pmu_raw_writel(0, S5P_PMU_SPARE2);
 
 	ret = cpu_suspend(0, exynos_wfi_finisher);
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 49df0a01..3a7e63f 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -50,6 +50,9 @@
 #define S5P_WAKEUP_MASK				0x0608
 #define S5P_WAKEUP_MASK2				0x0614
 
+#define EXYNOS_WAKEUP_MASK_VAL			0x0000FF3E
+#define EXYNOS3_WAKEUP_MASK_VAL			0x40003FFE
+
 #define S5P_INFORM0				0x0800
 #define S5P_INFORM1				0x0804
 #define S5P_INFORM5				0x0814
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
driver, so let's remove/minimize usage of any such helper function usage
from pm.c.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
 include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 1a7e5b5..4a73b02 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
 }
 
 /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
-static void exynos_set_wakeupmask(long mask)
+static void exynos_set_wakeupmask(void)
 {
-	pmu_raw_writel(mask, S5P_WAKEUP_MASK);
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250")) {
+		pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
 		pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
+	} else
+		pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
 }
 
 static void exynos_cpu_set_boot_vector(long flags)
@@ -141,7 +143,7 @@ static int exynos_aftr_finisher(unsigned long flags)
 {
 	int ret;
 
-	exynos_set_wakeupmask(soc_is_exynos3250() ? 0x40003ffe : 0x0000ff3e);
+	exynos_set_wakeupmask();
 	/* Set value of power down register for aftr mode */
 	exynos_sys_powerdown_conf(SYS_AFTR);
 
@@ -162,7 +164,7 @@ void exynos_enter_aftr(void)
 
 	cpu_pm_enter();
 
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		exynos_set_boot_flag(cpuid, C2_STATE);
 
 	exynos_pm_central_suspend();
@@ -184,7 +186,7 @@ void exynos_enter_aftr(void)
 
 	exynos_pm_central_resume();
 
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		exynos_clear_boot_flag(cpuid, C2_STATE);
 
 	cpu_pm_exit();
@@ -255,7 +257,7 @@ static int exynos_cpu0_enter_aftr(void)
 		while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
 			cpu_relax();
 
-		if (soc_is_exynos3250()) {
+		if (of_machine_is_compatible("samsung,exynos3250")) {
 			while (!pmu_raw_readl(S5P_PMU_SPARE2) &&
 			       !atomic_read(&cpu1_wakeup))
 				cpu_relax();
@@ -277,7 +279,7 @@ static int exynos_cpu0_enter_aftr(void)
 
 			call_firmware_op(cpu_boot, 1);
 
-			if (soc_is_exynos3250())
+			if (of_machine_is_compatible("samsung,exynos3250"))
 				dsb_sev();
 			else
 				arch_send_wakeup_ipi_mask(cpumask_of(1));
@@ -289,7 +291,7 @@ static int exynos_cpu0_enter_aftr(void)
 
 static int exynos_wfi_finisher(unsigned long flags)
 {
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		flush_cache_all();
 	cpu_do_idle();
 
@@ -311,7 +313,7 @@ static int exynos_cpu1_powerdown(void)
 	 */
 	exynos_cpu_power_down(1);
 
-	if (soc_is_exynos3250())
+	if (of_machine_is_compatible("samsung,exynos3250"))
 		pmu_raw_writel(0, S5P_PMU_SPARE2);
 
 	ret = cpu_suspend(0, exynos_wfi_finisher);
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index 49df0a01..3a7e63f 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -50,6 +50,9 @@
 #define S5P_WAKEUP_MASK				0x0608
 #define S5P_WAKEUP_MASK2				0x0614
 
+#define EXYNOS_WAKEUP_MASK_VAL			0x0000FF3E
+#define EXYNOS3_WAKEUP_MASK_VAL			0x40003FFE
+
 #define S5P_INFORM0				0x0800
 #define S5P_INFORM1				0x0804
 #define S5P_INFORM5				0x0814
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus
       [not found]   ` <CGME20170330131424epcas5p4fccfab06e5d77d70d09c3835c3332ee5@epcas5p4.samsung.com>
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

We are taking care of setting secondary cpu boot address in
exynos_boot_secondary just before sending ipi to secondary CPUs,
so we can safely remove this setting from smp_prepare_cpus.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 5a03bff..cb6d199 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -387,38 +387,12 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
 	exynos_sysram_init();
 
 	exynos_set_delayed_reset_assertion(true);
 
 	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
 		scu_enable(scu_base_addr());
-
-	/*
-	 * Write the address of secondary startup into the
-	 * system-wide flags register. The boot monitor waits
-	 * until it receives a soft interrupt, and then the
-	 * secondary CPU branches to this address.
-	 *
-	 * Try using firmware operation first and fall back to
-	 * boot register if it fails.
-	 */
-	for (i = 1; i < max_cpus; ++i) {
-		unsigned long boot_addr;
-		u32 mpidr;
-		u32 core_id;
-		int ret;
-
-		mpidr = cpu_logical_map(i);
-		core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
-		boot_addr = __pa_symbol(exynos4_secondary_startup);
-
-		ret = exynos_set_boot_addr(core_id, boot_addr);
-		if (ret)
-			break;
-	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

We are taking care of setting secondary cpu boot address in
exynos_boot_secondary just before sending ipi to secondary CPUs,
so we can safely remove this setting from smp_prepare_cpus.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 5a03bff..cb6d199 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -387,38 +387,12 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
 	exynos_sysram_init();
 
 	exynos_set_delayed_reset_assertion(true);
 
 	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
 		scu_enable(scu_base_addr());
-
-	/*
-	 * Write the address of secondary startup into the
-	 * system-wide flags register. The boot monitor waits
-	 * until it receives a soft interrupt, and then the
-	 * secondary CPU branches to this address.
-	 *
-	 * Try using firmware operation first and fall back to
-	 * boot register if it fails.
-	 */
-	for (i = 1; i < max_cpus; ++i) {
-		unsigned long boot_addr;
-		u32 mpidr;
-		u32 core_id;
-		int ret;
-
-		mpidr = cpu_logical_map(i);
-		core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
-		boot_addr = __pa_symbol(exynos4_secondary_startup);
-
-		ret = exynos_set_boot_addr(core_id, boot_addr);
-		if (ret)
-			break;
-	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
       [not found]   ` <CGME20170330131427epcas5p4c3d238022dc75694ad3baa8a1018ea04@epcas5p4.samsung.com>
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey, Grant Likely, Rob Herring, Linus Walleij

Exynos SoCs have Chipid, for identification of product IDs and SoC
revisions. This patch intends to provide initialization code for all
these functionalities, at the same time it provides some sysfs entries
for accessing these information to user-space.

This driver uses existing binding for exynos-chipid.

CC: Grant Likely <grant.likely@linaro.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
[m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/soc/samsung/Kconfig         |   5 ++
 drivers/soc/samsung/Makefile        |   1 +
 drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+)
 create mode 100644 drivers/soc/samsung/exynos-chipid.c

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 8b25bd5..a90a4ad 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
 
 if SOC_SAMSUNG
 
+config EXYNOS_CHIPID
+	bool "Exynos Chipid controller driver" if COMPILE_TEST
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	select SOC_BUS
+
 config EXYNOS_PMU
 	bool "Exynos PMU controller driver" if COMPILE_TEST
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 4d7694a..be3b6bb 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
 
 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
new file mode 100644
index 0000000..1e9fb6b
--- /dev/null
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * EXYNOS - CHIP ID support
+ * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#define EXYNOS_SUBREV_MASK	(0xF << 4)
+#define EXYNOS_MAINREV_MASK	(0xF << 0)
+#define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
+
+static const struct exynos_soc_id {
+	const char *name;
+	unsigned int id;
+	unsigned int mask;
+} soc_ids[] = {
+	{ "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
+	{ "EXYNOS4210", 0x43210000, 0xFFFFF000 },
+	{ "EXYNOS4212", 0x43220000, 0xFFFFF000 },
+	{ "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
+	{ "EXYNOS5250", 0x43520000, 0xFFFFF000 },
+	{ "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
+	{ "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
+	{ "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
+	{ "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
+	{ "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
+	{ "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
+	{ "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
+};
+
+static const char * __init product_id_to_soc_id(unsigned int product_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
+		if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
+			return soc_ids[i].name;
+	return "UNKNOWN";
+}
+
+int __init exynos_chipid_early_init(void)
+{
+	struct soc_device_attribute *soc_dev_attr;
+	void __iomem *exynos_chipid_base;
+	struct soc_device *soc_dev;
+	struct device_node *root;
+	struct device_node *np;
+	struct device *dev;
+	u32 product_id;
+	u32 revision;
+
+	/* look up for chipid node */
+	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
+	if (!np)
+		return -ENODEV;
+
+	exynos_chipid_base = of_iomap(np, 0);
+	of_node_put(np);
+
+	if (!exynos_chipid_base) {
+		pr_err("%s: failed to map chipid\n", np->name);
+		return -ENOMEM;
+	}
+
+	product_id = readl_relaxed(exynos_chipid_base);
+	revision = product_id & EXYNOS_REV_MASK;
+	iounmap(exynos_chipid_base);
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return -ENODEV;
+
+	soc_dev_attr->family = "Samsung Exynos";
+
+	root = of_find_node_by_path("/");
+	of_property_read_string(root, "model", &soc_dev_attr->machine);
+	of_node_put(root);
+
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
+	soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
+
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(soc_dev)) {
+		kfree(soc_dev_attr->revision);
+		kfree_const(soc_dev_attr->soc_id);
+		kfree(soc_dev_attr);
+		return PTR_ERR(soc_dev);
+	}
+	dev = soc_device_to_device(soc_dev);
+
+	dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+			soc_dev_attr->soc_id, product_id, revision);
+
+	return 0;
+}
+early_initcall(exynos_chipid_early_init);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

Exynos SoCs have Chipid, for identification of product IDs and SoC
revisions. This patch intends to provide initialization code for all
these functionalities, at the same time it provides some sysfs entries
for accessing these information to user-space.

This driver uses existing binding for exynos-chipid.

CC: Grant Likely <grant.likely@linaro.org>
CC: Rob Herring <robh+dt@kernel.org>
CC: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
[m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/soc/samsung/Kconfig         |   5 ++
 drivers/soc/samsung/Makefile        |   1 +
 drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+)
 create mode 100644 drivers/soc/samsung/exynos-chipid.c

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 8b25bd5..a90a4ad 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
 
 if SOC_SAMSUNG
 
+config EXYNOS_CHIPID
+	bool "Exynos Chipid controller driver" if COMPILE_TEST
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	select SOC_BUS
+
 config EXYNOS_PMU
 	bool "Exynos PMU controller driver" if COMPILE_TEST
 	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 4d7694a..be3b6bb 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
 
 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
new file mode 100644
index 0000000..1e9fb6b
--- /dev/null
+++ b/drivers/soc/samsung/exynos-chipid.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * EXYNOS - CHIP ID support
+ * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#define EXYNOS_SUBREV_MASK	(0xF << 4)
+#define EXYNOS_MAINREV_MASK	(0xF << 0)
+#define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
+
+static const struct exynos_soc_id {
+	const char *name;
+	unsigned int id;
+	unsigned int mask;
+} soc_ids[] = {
+	{ "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
+	{ "EXYNOS4210", 0x43210000, 0xFFFFF000 },
+	{ "EXYNOS4212", 0x43220000, 0xFFFFF000 },
+	{ "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
+	{ "EXYNOS5250", 0x43520000, 0xFFFFF000 },
+	{ "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
+	{ "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
+	{ "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
+	{ "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
+	{ "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
+	{ "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
+	{ "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
+};
+
+static const char * __init product_id_to_soc_id(unsigned int product_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
+		if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
+			return soc_ids[i].name;
+	return "UNKNOWN";
+}
+
+int __init exynos_chipid_early_init(void)
+{
+	struct soc_device_attribute *soc_dev_attr;
+	void __iomem *exynos_chipid_base;
+	struct soc_device *soc_dev;
+	struct device_node *root;
+	struct device_node *np;
+	struct device *dev;
+	u32 product_id;
+	u32 revision;
+
+	/* look up for chipid node */
+	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
+	if (!np)
+		return -ENODEV;
+
+	exynos_chipid_base = of_iomap(np, 0);
+	of_node_put(np);
+
+	if (!exynos_chipid_base) {
+		pr_err("%s: failed to map chipid\n", np->name);
+		return -ENOMEM;
+	}
+
+	product_id = readl_relaxed(exynos_chipid_base);
+	revision = product_id & EXYNOS_REV_MASK;
+	iounmap(exynos_chipid_base);
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return -ENODEV;
+
+	soc_dev_attr->family = "Samsung Exynos";
+
+	root = of_find_node_by_path("/");
+	of_property_read_string(root, "model", &soc_dev_attr->machine);
+	of_node_put(root);
+
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
+	soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
+
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR(soc_dev)) {
+		kfree(soc_dev_attr->revision);
+		kfree_const(soc_dev_attr->soc_id);
+		kfree(soc_dev_attr);
+		return PTR_ERR(soc_dev);
+	}
+	dev = soc_device_to_device(soc_dev);
+
+	dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+			soc_dev_attr->soc_id, product_id, revision);
+
+	return 0;
+}
+early_initcall(exynos_chipid_early_init);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 05/12] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
       [not found]   ` <CGME20170330131429epcas5p414565c5a9f2c38f3f6660b72f9ad68a2@epcas5p4.samsung.com>
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

As now we have chipid driver to initialize SoC related information
let's include it in build by default.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 0a99140..30a9948 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -16,6 +16,7 @@ menuconfig ARCH_EXYNOS
 	select ARM_AMBA
 	select ARM_GIC
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_CHIPID
 	select EXYNOS_THERMAL
 	select EXYNOS_PMU
 	select EXYNOS_SROM
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 05/12] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
@ 2017-03-30 13:16       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

As now we have chipid driver to initialize SoC related information
let's include it in build by default.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 arch/arm/mach-exynos/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 0a99140..30a9948 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -16,6 +16,7 @@ menuconfig ARCH_EXYNOS
 	select ARM_AMBA
 	select ARM_GIC
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_CHIPID
 	select EXYNOS_THERMAL
 	select EXYNOS_PMU
 	select EXYNOS_SROM
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 06/12] ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
       [not found]   ` <CGME20170330131431epcas5p447a730e1bb194162f262a819ae665efb@epcas5p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

This patch enables exynos_chipid driver for ARCH_EXYNOS
based SoC.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 9cdaecd..b238204 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -54,6 +54,7 @@ config ARCH_BRCMSTB
 config ARCH_EXYNOS
 	bool "ARMv8 based Samsung Exynos SoC family"
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_CHIPID
 	select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
 	select EXYNOS_PMU
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 06/12] ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

This patch enables exynos_chipid driver for ARCH_EXYNOS
based SoC.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 9cdaecd..b238204 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -54,6 +54,7 @@ config ARCH_BRCMSTB
 config ARCH_EXYNOS
 	bool "ARMv8 based Samsung Exynos SoC family"
 	select COMMON_CLK_SAMSUNG
+	select EXYNOS_CHIPID
 	select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
 	select EXYNOS_PMU
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
       [not found]   ` <CGME20170330131434epcas1p4e42fe06bae3456c39e0f93a2f8ae4bc0@epcas1p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

For s2r various Exynos SoC needs different programming sequence and data.
Currently this is handled by adding lots of soc_is_exynosMMM checks in the
code, in an attempt to remove the dependency of such helper functions
specific to each SoC, let's separate these programming sequence by
introducing a new struct exynos_s2r_data. This struct will contain
different function hooks and data for differentiating these programming
sequences based on SoC's soc_id and revision parameters which can be
matched by using generic API "soc_device_match".

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/pm.c | 122 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 116 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 4a73b02..fa24098 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
+#include <linux/sys_soc.h>
 
 #include <asm/firmware.h>
 #include <asm/smp_scu.h>
@@ -30,6 +31,12 @@
 
 #include "common.h"
 
+struct exynos_s2r_data {
+	void (*enter_aftr)(void);
+};
+
+static const struct exynos_s2r_data *s2r_data;
+
 static inline void __iomem *exynos_boot_vector_addr(void)
 {
 	if (samsung_rev() == EXYNOS4210_REV_1_1)
@@ -160,13 +167,26 @@ static int exynos_aftr_finisher(unsigned long flags)
 
 void exynos_enter_aftr(void)
 {
+	if (s2r_data && s2r_data->enter_aftr)
+		s2r_data->enter_aftr();
+}
+
+static void exynos3_enter_aftr(void)
+{
 	unsigned int cpuid = smp_processor_id();
 
 	cpu_pm_enter();
+	exynos_set_boot_flag(cpuid, C2_STATE);
+	exynos_pm_central_suspend();
+	cpu_suspend(0, exynos_aftr_finisher);
+	exynos_pm_central_resume();
+	exynos_clear_boot_flag(cpuid, C2_STATE);
+	cpu_pm_exit();
+}
 
-	if (of_machine_is_compatible("samsung,exynos3250"))
-		exynos_set_boot_flag(cpuid, C2_STATE);
-
+static void exynos4_enter_aftr(void)
+{
+	cpu_pm_enter();
 	exynos_pm_central_suspend();
 
 	if (of_machine_is_compatible("samsung,exynos4212") ||
@@ -185,13 +205,103 @@ void exynos_enter_aftr(void)
 	}
 
 	exynos_pm_central_resume();
+	cpu_pm_exit();
+}
 
-	if (of_machine_is_compatible("samsung,exynos3250"))
-		exynos_clear_boot_flag(cpuid, C2_STATE);
-
+static void exynos5_enter_aftr(void)
+{
+	cpu_pm_enter();
+	exynos_pm_central_suspend();
+	cpu_suspend(0, exynos_aftr_finisher);
+	exynos_pm_central_resume();
 	cpu_pm_exit();
 }
 
+static const struct exynos_s2r_data exynos_common_s2r_data = {
+	.enter_aftr		= exynos5_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos3250_s2r_data = {
+	.enter_aftr		= exynos3_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
+	.enter_aftr		= exynos4_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
+	.enter_aftr		= exynos4_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos4x12_s2r_data = {
+	.enter_aftr		= exynos4_enter_aftr,
+};
+
+static const struct soc_device_attribute exynos_soc_revision[] __initconst = {
+	{
+		.soc_id = "EXYNOS3250",
+		.data = &exynos3250_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4210",
+		.revision = "11",
+		.data = &exynos4210_rev11_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4210",
+		.revision = "10",
+		.data = &exynos4210_rev10_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4212",
+		.data = &exynos4x12_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4412",
+		.data = &exynos4x12_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5250",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5260",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5440",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5410",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5420",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5800",
+		.data = &exynos_common_s2r_data
+	},
+};
+
+int __init exynos_s2r_init(void)
+{
+	const struct soc_device_attribute *match;
+
+	match = soc_device_match(exynos_soc_revision);
+
+	if (match)
+		s2r_data = (const struct exynos_s2r_data *) match->data;
+
+	if (!s2r_data)
+		return -ENODEV;
+
+	return 0;
+}
+arch_initcall(exynos_s2r_init);
+
 #if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
 static atomic_t cpu1_wakeup = ATOMIC_INIT(0);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

For s2r various Exynos SoC needs different programming sequence and data.
Currently this is handled by adding lots of soc_is_exynosMMM checks in the
code, in an attempt to remove the dependency of such helper functions
specific to each SoC, let's separate these programming sequence by
introducing a new struct exynos_s2r_data. This struct will contain
different function hooks and data for differentiating these programming
sequences based on SoC's soc_id and revision parameters which can be
matched by using generic API "soc_device_match".

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/pm.c | 122 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 116 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 4a73b02..fa24098 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
+#include <linux/sys_soc.h>
 
 #include <asm/firmware.h>
 #include <asm/smp_scu.h>
@@ -30,6 +31,12 @@
 
 #include "common.h"
 
+struct exynos_s2r_data {
+	void (*enter_aftr)(void);
+};
+
+static const struct exynos_s2r_data *s2r_data;
+
 static inline void __iomem *exynos_boot_vector_addr(void)
 {
 	if (samsung_rev() == EXYNOS4210_REV_1_1)
@@ -160,13 +167,26 @@ static int exynos_aftr_finisher(unsigned long flags)
 
 void exynos_enter_aftr(void)
 {
+	if (s2r_data && s2r_data->enter_aftr)
+		s2r_data->enter_aftr();
+}
+
+static void exynos3_enter_aftr(void)
+{
 	unsigned int cpuid = smp_processor_id();
 
 	cpu_pm_enter();
+	exynos_set_boot_flag(cpuid, C2_STATE);
+	exynos_pm_central_suspend();
+	cpu_suspend(0, exynos_aftr_finisher);
+	exynos_pm_central_resume();
+	exynos_clear_boot_flag(cpuid, C2_STATE);
+	cpu_pm_exit();
+}
 
-	if (of_machine_is_compatible("samsung,exynos3250"))
-		exynos_set_boot_flag(cpuid, C2_STATE);
-
+static void exynos4_enter_aftr(void)
+{
+	cpu_pm_enter();
 	exynos_pm_central_suspend();
 
 	if (of_machine_is_compatible("samsung,exynos4212") ||
@@ -185,13 +205,103 @@ void exynos_enter_aftr(void)
 	}
 
 	exynos_pm_central_resume();
+	cpu_pm_exit();
+}
 
-	if (of_machine_is_compatible("samsung,exynos3250"))
-		exynos_clear_boot_flag(cpuid, C2_STATE);
-
+static void exynos5_enter_aftr(void)
+{
+	cpu_pm_enter();
+	exynos_pm_central_suspend();
+	cpu_suspend(0, exynos_aftr_finisher);
+	exynos_pm_central_resume();
 	cpu_pm_exit();
 }
 
+static const struct exynos_s2r_data exynos_common_s2r_data = {
+	.enter_aftr		= exynos5_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos3250_s2r_data = {
+	.enter_aftr		= exynos3_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
+	.enter_aftr		= exynos4_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
+	.enter_aftr		= exynos4_enter_aftr,
+};
+
+static const struct exynos_s2r_data exynos4x12_s2r_data = {
+	.enter_aftr		= exynos4_enter_aftr,
+};
+
+static const struct soc_device_attribute exynos_soc_revision[] __initconst = {
+	{
+		.soc_id = "EXYNOS3250",
+		.data = &exynos3250_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4210",
+		.revision = "11",
+		.data = &exynos4210_rev11_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4210",
+		.revision = "10",
+		.data = &exynos4210_rev10_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4212",
+		.data = &exynos4x12_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS4412",
+		.data = &exynos4x12_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5250",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5260",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5440",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5410",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5420",
+		.data = &exynos_common_s2r_data
+	},
+	{
+		.soc_id = "EXYNOS5800",
+		.data = &exynos_common_s2r_data
+	},
+};
+
+int __init exynos_s2r_init(void)
+{
+	const struct soc_device_attribute *match;
+
+	match = soc_device_match(exynos_soc_revision);
+
+	if (match)
+		s2r_data = (const struct exynos_s2r_data *) match->data;
+
+	if (!s2r_data)
+		return -ENODEV;
+
+	return 0;
+}
+arch_initcall(exynos_s2r_init);
+
 #if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
 static atomic_t cpu1_wakeup = ATOMIC_INIT(0);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr,flag} ops to exynos_s2r_data
       [not found]   ` <CGME20170330131436epcas1p4a4f8bf7b64b4a5ff9ee692adc4e7d001@epcas1p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

Various Exynos SoC needs different boot addresses and flags. Currently we
are handling this difference by adding lots of soc_is_exynosMMM checks in
the code, in an attempt to remove the dependency of such helper functions
specific to each SoC, let's separate helper functions for these helper
functions by moving them into SoC specific hooks in struct exynos_s2r_data.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/pm.c | 60 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index fa24098..c3fa537 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -32,26 +32,56 @@
 #include "common.h"
 
 struct exynos_s2r_data {
+	void __iomem* (*boot_vector_addr)(void);
+	void __iomem* (*boot_vector_flag)(void);
 	void (*enter_aftr)(void);
 };
 
 static const struct exynos_s2r_data *s2r_data;
 
-static inline void __iomem *exynos_boot_vector_addr(void)
+static void __iomem *exynos_boot_vector_addr(void)
+{
+	if (s2r_data && s2r_data->boot_vector_addr)
+		return s2r_data->boot_vector_addr();
+
+	return NULL;
+}
+
+static inline void __iomem *exynos4210_rev11_boot_vector_addr(void)
+{
+	return pmu_base_addr + S5P_INFORM7;
+}
+
+static inline void __iomem *exynos4210_rev10_boot_vector_addr(void)
+{
+	return sysram_base_addr + 0x24;
+}
+
+static inline void __iomem *exynos_common_boot_vector_addr(void)
 {
-	if (samsung_rev() == EXYNOS4210_REV_1_1)
-		return pmu_base_addr + S5P_INFORM7;
-	else if (samsung_rev() == EXYNOS4210_REV_1_0)
-		return sysram_base_addr + 0x24;
 	return pmu_base_addr + S5P_INFORM0;
 }
 
-static inline void __iomem *exynos_boot_vector_flag(void)
+static void __iomem *exynos_boot_vector_flag(void)
+{
+	if (s2r_data && s2r_data->boot_vector_flag)
+		return s2r_data->boot_vector_flag();
+
+	return NULL;
+}
+
+static inline void __iomem *exynos4210_rev11_boot_vector_flag(void)
+{
+	return pmu_base_addr + S5P_INFORM6;
+}
+
+static inline void __iomem *exynos4210_rev10_boot_vector_flag(void)
+{
+	return sysram_base_addr + 0x20;
+}
+
+static inline void __iomem *exynos_common_boot_vector_flag(void)
 {
-	if (samsung_rev() == EXYNOS4210_REV_1_1)
-		return pmu_base_addr + S5P_INFORM6;
-	else if (samsung_rev() == EXYNOS4210_REV_1_0)
-		return sysram_base_addr + 0x20;
 	return pmu_base_addr + S5P_INFORM1;
 }
 
@@ -218,22 +248,32 @@ static void exynos5_enter_aftr(void)
 }
 
 static const struct exynos_s2r_data exynos_common_s2r_data = {
+	.boot_vector_addr	= exynos_common_boot_vector_addr,
+	.boot_vector_flag	= exynos_common_boot_vector_flag,
 	.enter_aftr		= exynos5_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos3250_s2r_data = {
+	.boot_vector_addr	= exynos_common_boot_vector_addr,
+	.boot_vector_flag	= exynos_common_boot_vector_flag,
 	.enter_aftr		= exynos3_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
+	.boot_vector_addr	= exynos4210_rev11_boot_vector_addr,
+	.boot_vector_flag	= exynos4210_rev11_boot_vector_flag,
 	.enter_aftr		= exynos4_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
+	.boot_vector_addr	= exynos4210_rev10_boot_vector_addr,
+	.boot_vector_flag	= exynos4210_rev10_boot_vector_flag,
 	.enter_aftr		= exynos4_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos4x12_s2r_data = {
+	.boot_vector_addr	= exynos_common_boot_vector_addr,
+	.boot_vector_flag	= exynos_common_boot_vector_flag,
 	.enter_aftr		= exynos4_enter_aftr,
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} ops to exynos_s2r_data
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

Various Exynos SoC needs different boot addresses and flags. Currently we
are handling this difference by adding lots of soc_is_exynosMMM checks in
the code, in an attempt to remove the dependency of such helper functions
specific to each SoC, let's separate helper functions for these helper
functions by moving them into SoC specific hooks in struct exynos_s2r_data.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/pm.c | 60 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index fa24098..c3fa537 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -32,26 +32,56 @@
 #include "common.h"
 
 struct exynos_s2r_data {
+	void __iomem* (*boot_vector_addr)(void);
+	void __iomem* (*boot_vector_flag)(void);
 	void (*enter_aftr)(void);
 };
 
 static const struct exynos_s2r_data *s2r_data;
 
-static inline void __iomem *exynos_boot_vector_addr(void)
+static void __iomem *exynos_boot_vector_addr(void)
+{
+	if (s2r_data && s2r_data->boot_vector_addr)
+		return s2r_data->boot_vector_addr();
+
+	return NULL;
+}
+
+static inline void __iomem *exynos4210_rev11_boot_vector_addr(void)
+{
+	return pmu_base_addr + S5P_INFORM7;
+}
+
+static inline void __iomem *exynos4210_rev10_boot_vector_addr(void)
+{
+	return sysram_base_addr + 0x24;
+}
+
+static inline void __iomem *exynos_common_boot_vector_addr(void)
 {
-	if (samsung_rev() == EXYNOS4210_REV_1_1)
-		return pmu_base_addr + S5P_INFORM7;
-	else if (samsung_rev() == EXYNOS4210_REV_1_0)
-		return sysram_base_addr + 0x24;
 	return pmu_base_addr + S5P_INFORM0;
 }
 
-static inline void __iomem *exynos_boot_vector_flag(void)
+static void __iomem *exynos_boot_vector_flag(void)
+{
+	if (s2r_data && s2r_data->boot_vector_flag)
+		return s2r_data->boot_vector_flag();
+
+	return NULL;
+}
+
+static inline void __iomem *exynos4210_rev11_boot_vector_flag(void)
+{
+	return pmu_base_addr + S5P_INFORM6;
+}
+
+static inline void __iomem *exynos4210_rev10_boot_vector_flag(void)
+{
+	return sysram_base_addr + 0x20;
+}
+
+static inline void __iomem *exynos_common_boot_vector_flag(void)
 {
-	if (samsung_rev() == EXYNOS4210_REV_1_1)
-		return pmu_base_addr + S5P_INFORM6;
-	else if (samsung_rev() == EXYNOS4210_REV_1_0)
-		return sysram_base_addr + 0x20;
 	return pmu_base_addr + S5P_INFORM1;
 }
 
@@ -218,22 +248,32 @@ static void exynos5_enter_aftr(void)
 }
 
 static const struct exynos_s2r_data exynos_common_s2r_data = {
+	.boot_vector_addr	= exynos_common_boot_vector_addr,
+	.boot_vector_flag	= exynos_common_boot_vector_flag,
 	.enter_aftr		= exynos5_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos3250_s2r_data = {
+	.boot_vector_addr	= exynos_common_boot_vector_addr,
+	.boot_vector_flag	= exynos_common_boot_vector_flag,
 	.enter_aftr		= exynos3_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
+	.boot_vector_addr	= exynos4210_rev11_boot_vector_addr,
+	.boot_vector_flag	= exynos4210_rev11_boot_vector_flag,
 	.enter_aftr		= exynos4_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
+	.boot_vector_addr	= exynos4210_rev10_boot_vector_addr,
+	.boot_vector_flag	= exynos4210_rev10_boot_vector_flag,
 	.enter_aftr		= exynos4_enter_aftr,
 };
 
 static const struct exynos_s2r_data exynos4x12_s2r_data = {
+	.boot_vector_addr	= exynos_common_boot_vector_addr,
+	.boot_vector_flag	= exynos_common_boot_vector_flag,
 	.enter_aftr		= exynos4_enter_aftr,
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
       [not found]   ` <CGME20170330131438epcas1p459ce93da17fcd05249eddaef18d5021e@epcas1p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

Various Exynos SoC has different CPU related information, such as CPU
boot register, programming sequence making CPU up/down. Currently this
is handled by adding lots of soc_is_exynosMMM checks in the code, in
an attempt to remove the dependency of such helper functions specific to
each SoC, let's separate this information pertaining to CPU by introducing
a new "struct exynos_cpu_info". This struct will contain differences
associated with CPU on various Exynos SoC. This can be matched by using
generic API "soc_device_match".

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 135 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index cb6d199..ff369b9 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -19,6 +19,7 @@
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <linux/of_address.h>
+#include <linux/sys_soc.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 
 #include <asm/cacheflush.h>
@@ -33,6 +34,16 @@
 
 extern void exynos4_secondary_startup(void);
 
+/*
+ * struct exynos_cpu_info - Exynos CPU related info/operations
+ * @cpu_boot_reg: computes cpu boot address for requested cpu
+ */
+struct exynos_cpu_info {
+	void __iomem* (*cpu_boot_reg)(u32 cpu);
+};
+
+static const struct exynos_cpu_info *cpu_info;
+
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void cpu_leave_lowpower(u32 core_id)
 {
@@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
 		S5P_CORE_LOCAL_PWR_EN);
 }
 
-static void __iomem *cpu_boot_reg_base(void)
+static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
 {
-	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
-		return pmu_base_addr + S5P_INFORM5;
-	return sysram_base_addr;
+	void __iomem *boot_reg = pmu_base_addr;
+
+	if (!boot_reg)
+		return IOMEM_ERR_PTR(-ENODEV);
+
+	boot_reg += S5P_INFORM5;
+
+	return boot_reg;
 }
 
-static inline void __iomem *cpu_boot_reg(int cpu)
+static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
 {
-	void __iomem *boot_reg;
+	void __iomem *boot_reg = sysram_base_addr;
 
-	boot_reg = cpu_boot_reg_base();
 	if (!boot_reg)
 		return IOMEM_ERR_PTR(-ENODEV);
-	if (soc_is_exynos4412())
-		boot_reg += 4*cpu;
-	else if (soc_is_exynos5420() || soc_is_exynos5800())
-		boot_reg += 4;
+
+	boot_reg += 4*cpu;
+
 	return boot_reg;
 }
 
+static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
+{
+	void __iomem *boot_reg = sysram_base_addr;
+
+	if (!sysram_base_addr)
+		return IOMEM_ERR_PTR(-ENODEV);
+
+	boot_reg += 4;
+
+	return boot_reg;
+}
+
+static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
+{
+	if (!sysram_base_addr)
+		return IOMEM_ERR_PTR(-ENODEV);
+
+	return sysram_base_addr;
+}
+
+static inline void __iomem *cpu_boot_reg(int cpu)
+{
+	if (cpu_info && cpu_info->cpu_boot_reg)
+		return cpu_info->cpu_boot_reg(cpu);
+	return NULL;
+}
+
 /*
  * Set wake up by local power mode and execute software reset for given core.
  *
@@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
 	return ret;
 }
 
+static const struct exynos_cpu_info exynos3250_cpu_info = {
+	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos5420_cpu_info = {
+	.cpu_boot_reg = exynos5420_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
+	.cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos4412_cpu_info = {
+	.cpu_boot_reg = exynos4412_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos_common_cpu_info = {
+	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+};
+
+static const struct soc_device_attribute exynos_soc_revision[] = {
+	{
+		.soc_id = "EXYNOS4210",
+		.revision = "11",
+		.data = &exynos4210_rev11_cpu_info
+	}, {
+		.soc_id = "EXYNOS4210",
+		.revision = "10",
+		.data = &exynos_common_cpu_info
+	}
+};
+
+static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
+	{
+		.compatible = "samsung,exynos3250",
+		.data = &exynos3250_cpu_info
+	}, {
+		.compatible = "samsung,exynos4212",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos4412",
+		.data = &exynos4412_cpu_info
+	}, {
+		.compatible = "samsung,exynos5250",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5260",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5410",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5420",
+		.data = &exynos5420_cpu_info
+	}, {
+		.compatible = "samsung,exynos5440",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5800",
+		.data = &exynos5420_cpu_info
+	},
+	{ /*sentinel*/ },
+};
+
 static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
+	const struct soc_device_attribute *match;
 	u32 mpidr = cpu_logical_map(cpu);
 	u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 	int ret = -ENOSYS;
 
+	if (of_machine_is_compatible("samsung,exynos4210")) {
+		match = soc_device_match(exynos_soc_revision);
+		if (match)
+			cpu_info = (const struct exynos_cpu_info *) match->data;
+	}
+
 	/*
 	 * Set synchronisation state between this boot processor
 	 * and the secondary one
@@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
+	const struct of_device_id *match;
+	struct device_node *np;
+
+	if (!of_machine_is_compatible("samsung,exynos4210")) {
+		np = of_find_matching_node_and_match(NULL,
+				exynos_pmu_of_device_ids, &match);
+		if (!np)
+			pr_err("failed to find supported CPU\n");
+		else
+			cpu_info = (const struct exynos_cpu_info *) match->data;
+	}
+
 	exynos_sysram_init();
 
 	exynos_set_delayed_reset_assertion(true);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

Various Exynos SoC has different CPU related information, such as CPU
boot register, programming sequence making CPU up/down. Currently this
is handled by adding lots of soc_is_exynosMMM checks in the code, in
an attempt to remove the dependency of such helper functions specific to
each SoC, let's separate this information pertaining to CPU by introducing
a new "struct exynos_cpu_info". This struct will contain differences
associated with CPU on various Exynos SoC. This can be matched by using
generic API "soc_device_match".

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 135 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index cb6d199..ff369b9 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -19,6 +19,7 @@
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <linux/of_address.h>
+#include <linux/sys_soc.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 
 #include <asm/cacheflush.h>
@@ -33,6 +34,16 @@
 
 extern void exynos4_secondary_startup(void);
 
+/*
+ * struct exynos_cpu_info - Exynos CPU related info/operations
+ * @cpu_boot_reg: computes cpu boot address for requested cpu
+ */
+struct exynos_cpu_info {
+	void __iomem* (*cpu_boot_reg)(u32 cpu);
+};
+
+static const struct exynos_cpu_info *cpu_info;
+
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void cpu_leave_lowpower(u32 core_id)
 {
@@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
 		S5P_CORE_LOCAL_PWR_EN);
 }
 
-static void __iomem *cpu_boot_reg_base(void)
+static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
 {
-	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
-		return pmu_base_addr + S5P_INFORM5;
-	return sysram_base_addr;
+	void __iomem *boot_reg = pmu_base_addr;
+
+	if (!boot_reg)
+		return IOMEM_ERR_PTR(-ENODEV);
+
+	boot_reg += S5P_INFORM5;
+
+	return boot_reg;
 }
 
-static inline void __iomem *cpu_boot_reg(int cpu)
+static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
 {
-	void __iomem *boot_reg;
+	void __iomem *boot_reg = sysram_base_addr;
 
-	boot_reg = cpu_boot_reg_base();
 	if (!boot_reg)
 		return IOMEM_ERR_PTR(-ENODEV);
-	if (soc_is_exynos4412())
-		boot_reg += 4*cpu;
-	else if (soc_is_exynos5420() || soc_is_exynos5800())
-		boot_reg += 4;
+
+	boot_reg += 4*cpu;
+
 	return boot_reg;
 }
 
+static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
+{
+	void __iomem *boot_reg = sysram_base_addr;
+
+	if (!sysram_base_addr)
+		return IOMEM_ERR_PTR(-ENODEV);
+
+	boot_reg += 4;
+
+	return boot_reg;
+}
+
+static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
+{
+	if (!sysram_base_addr)
+		return IOMEM_ERR_PTR(-ENODEV);
+
+	return sysram_base_addr;
+}
+
+static inline void __iomem *cpu_boot_reg(int cpu)
+{
+	if (cpu_info && cpu_info->cpu_boot_reg)
+		return cpu_info->cpu_boot_reg(cpu);
+	return NULL;
+}
+
 /*
  * Set wake up by local power mode and execute software reset for given core.
  *
@@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
 	return ret;
 }
 
+static const struct exynos_cpu_info exynos3250_cpu_info = {
+	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos5420_cpu_info = {
+	.cpu_boot_reg = exynos5420_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
+	.cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos4412_cpu_info = {
+	.cpu_boot_reg = exynos4412_cpu_boot_reg,
+};
+
+static const struct exynos_cpu_info exynos_common_cpu_info = {
+	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+};
+
+static const struct soc_device_attribute exynos_soc_revision[] = {
+	{
+		.soc_id = "EXYNOS4210",
+		.revision = "11",
+		.data = &exynos4210_rev11_cpu_info
+	}, {
+		.soc_id = "EXYNOS4210",
+		.revision = "10",
+		.data = &exynos_common_cpu_info
+	}
+};
+
+static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
+	{
+		.compatible = "samsung,exynos3250",
+		.data = &exynos3250_cpu_info
+	}, {
+		.compatible = "samsung,exynos4212",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos4412",
+		.data = &exynos4412_cpu_info
+	}, {
+		.compatible = "samsung,exynos5250",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5260",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5410",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5420",
+		.data = &exynos5420_cpu_info
+	}, {
+		.compatible = "samsung,exynos5440",
+		.data = &exynos_common_cpu_info
+	}, {
+		.compatible = "samsung,exynos5800",
+		.data = &exynos5420_cpu_info
+	},
+	{ /*sentinel*/ },
+};
+
 static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	unsigned long timeout;
+	const struct soc_device_attribute *match;
 	u32 mpidr = cpu_logical_map(cpu);
 	u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
 	int ret = -ENOSYS;
 
+	if (of_machine_is_compatible("samsung,exynos4210")) {
+		match = soc_device_match(exynos_soc_revision);
+		if (match)
+			cpu_info = (const struct exynos_cpu_info *) match->data;
+	}
+
 	/*
 	 * Set synchronisation state between this boot processor
 	 * and the secondary one
@@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
 {
+	const struct of_device_id *match;
+	struct device_node *np;
+
+	if (!of_machine_is_compatible("samsung,exynos4210")) {
+		np = of_find_matching_node_and_match(NULL,
+				exynos_pmu_of_device_ids, &match);
+		if (!np)
+			pr_err("failed to find supported CPU\n");
+		else
+			cpu_info = (const struct exynos_cpu_info *) match->data;
+	}
+
 	exynos_sysram_init();
 
 	exynos_set_delayed_reset_assertion(true);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
       [not found]   ` <CGME20170330131440epcas1p4f27192272761aa593b6cf083453e8adc@epcas1p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

Various Exynos SoC handles CPU power_up and power_down operation
differently. To handle this difference until now we were using
soc_is_exynosMMM helper functions, in an attempt to remove the dependency
of such helper functions specific to each SoC, let's move power_{down,up}
functionality as a SoC specific function pointer hooks in
struct exynos_cpu_info.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 61 +++++++++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index ff369b9..6f08b15 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -37,9 +37,13 @@ extern void exynos4_secondary_startup(void);
 /*
  * struct exynos_cpu_info - Exynos CPU related info/operations
  * @cpu_boot_reg: computes cpu boot address for requested cpu
+ * @cpu_power_down: handles cpu power down routine for requested cpu
+ * @cpu_power_up: handles cpu power up routine for requested cpu
  */
 struct exynos_cpu_info {
 	void __iomem* (*cpu_boot_reg)(u32 cpu);
+	void (*cpu_power_down)(u32 cpu);
+	void (*cpu_power_up)(u32 cpu);
 };
 
 static const struct exynos_cpu_info *cpu_info;
@@ -92,19 +96,29 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-/**
- * exynos_core_power_down : power down the specified cpu
+/*
+ * exynos_core_power_down - power down the specified cpu
  * @cpu : the cpu to power down
- *
- * Power down the specified cpu. The sequence must be finished by a
- * call to cpu_do_idle()
- *
+ * The sequence must be finished by a call to cpu_do_idle()
  */
 void exynos_cpu_power_down(int cpu)
 {
+	if (cpu_info && cpu_info->cpu_power_down)
+		cpu_info->cpu_power_down(cpu);
+}
+
+static void exynos_common_cpu_power_down(u32 cpu)
+{
 	u32 core_conf;
 
-	if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
+	core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+	core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
+	pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+}
+
+static void exynos5420_cpu_power_down(u32 cpu)
+{
+	if (cpu == 0) {
 		/*
 		 * Bypass power down for CPU0 during suspend. Check for
 		 * the SYS_PWR_REG value to decide if we are suspending
@@ -116,24 +130,31 @@ void exynos_cpu_power_down(int cpu)
 			return;
 	}
 
-	core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
-	core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
-	pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+	exynos_common_cpu_power_down(cpu);
 }
 
-/**
+/*
  * exynos_cpu_power_up : power up the specified cpu
  * @cpu : the cpu to power up
- *
- * Power up the specified cpu
  */
 void exynos_cpu_power_up(int cpu)
 {
+	if (cpu_info && cpu_info->cpu_power_up)
+		cpu_info->cpu_power_up(cpu);
+}
+
+static void exynos_common_cpu_power_up(u32 cpu)
+{
 	u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
+	pmu_raw_writel(core_conf,
+			EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+}
 
-	if (soc_is_exynos3250())
-		core_conf |= S5P_CORE_AUTOWAKEUP_EN;
+static void exynos3250_cpu_power_up(u32 cpu)
+{
+	u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
 
+	core_conf |= S5P_CORE_AUTOWAKEUP_EN;
 	pmu_raw_writel(core_conf,
 			EXYNOS_ARM_CORE_CONFIGURATION(cpu));
 }
@@ -339,22 +360,32 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
 
 static const struct exynos_cpu_info exynos3250_cpu_info = {
 	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos3250_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos5420_cpu_info = {
 	.cpu_boot_reg = exynos5420_cpu_boot_reg,
+	.cpu_power_down = exynos5420_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
 	.cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos4412_cpu_info = {
 	.cpu_boot_reg = exynos4412_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos_common_cpu_info = {
 	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct soc_device_attribute exynos_soc_revision[] = {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 10/12] ARM: EXYNOS: move power_{down, up} to per SoC struct exynos_cpu_info
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

Various Exynos SoC handles CPU power_up and power_down operation
differently. To handle this difference until now we were using
soc_is_exynosMMM helper functions, in an attempt to remove the dependency
of such helper functions specific to each SoC, let's move power_{down,up}
functionality as a SoC specific function pointer hooks in
struct exynos_cpu_info.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 61 +++++++++++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index ff369b9..6f08b15 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -37,9 +37,13 @@ extern void exynos4_secondary_startup(void);
 /*
  * struct exynos_cpu_info - Exynos CPU related info/operations
  * @cpu_boot_reg: computes cpu boot address for requested cpu
+ * @cpu_power_down: handles cpu power down routine for requested cpu
+ * @cpu_power_up: handles cpu power up routine for requested cpu
  */
 struct exynos_cpu_info {
 	void __iomem* (*cpu_boot_reg)(u32 cpu);
+	void (*cpu_power_down)(u32 cpu);
+	void (*cpu_power_up)(u32 cpu);
 };
 
 static const struct exynos_cpu_info *cpu_info;
@@ -92,19 +96,29 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-/**
- * exynos_core_power_down : power down the specified cpu
+/*
+ * exynos_core_power_down - power down the specified cpu
  * @cpu : the cpu to power down
- *
- * Power down the specified cpu. The sequence must be finished by a
- * call to cpu_do_idle()
- *
+ * The sequence must be finished by a call to cpu_do_idle()
  */
 void exynos_cpu_power_down(int cpu)
 {
+	if (cpu_info && cpu_info->cpu_power_down)
+		cpu_info->cpu_power_down(cpu);
+}
+
+static void exynos_common_cpu_power_down(u32 cpu)
+{
 	u32 core_conf;
 
-	if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
+	core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+	core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
+	pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+}
+
+static void exynos5420_cpu_power_down(u32 cpu)
+{
+	if (cpu == 0) {
 		/*
 		 * Bypass power down for CPU0 during suspend. Check for
 		 * the SYS_PWR_REG value to decide if we are suspending
@@ -116,24 +130,31 @@ void exynos_cpu_power_down(int cpu)
 			return;
 	}
 
-	core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
-	core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
-	pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+	exynos_common_cpu_power_down(cpu);
 }
 
-/**
+/*
  * exynos_cpu_power_up : power up the specified cpu
  * @cpu : the cpu to power up
- *
- * Power up the specified cpu
  */
 void exynos_cpu_power_up(int cpu)
 {
+	if (cpu_info && cpu_info->cpu_power_up)
+		cpu_info->cpu_power_up(cpu);
+}
+
+static void exynos_common_cpu_power_up(u32 cpu)
+{
 	u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
+	pmu_raw_writel(core_conf,
+			EXYNOS_ARM_CORE_CONFIGURATION(cpu));
+}
 
-	if (soc_is_exynos3250())
-		core_conf |= S5P_CORE_AUTOWAKEUP_EN;
+static void exynos3250_cpu_power_up(u32 cpu)
+{
+	u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
 
+	core_conf |= S5P_CORE_AUTOWAKEUP_EN;
 	pmu_raw_writel(core_conf,
 			EXYNOS_ARM_CORE_CONFIGURATION(cpu));
 }
@@ -339,22 +360,32 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
 
 static const struct exynos_cpu_info exynos3250_cpu_info = {
 	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos3250_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos5420_cpu_info = {
 	.cpu_boot_reg = exynos5420_cpu_boot_reg,
+	.cpu_power_down = exynos5420_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
 	.cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos4412_cpu_info = {
 	.cpu_boot_reg = exynos4412_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct exynos_cpu_info exynos_common_cpu_info = {
 	.cpu_boot_reg = exynos_common_cpu_boot_reg,
+	.cpu_power_down = exynos_common_cpu_power_down,
+	.cpu_power_up = exynos_common_cpu_power_up,
 };
 
 static const struct soc_device_attribute exynos_soc_revision[] = {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 11/12] ARM: EXYNOS: move cpu_restart as a SoC specific hook to exynos_cpu_info
       [not found]   ` <CGME20170330131442epcas5p4f2be72cb3ec506847d8e832675e682c4@epcas5p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

To handle differences in cpu_restart functionality among various Exynos SoC
let's move cpu_restart as a SoC specific function hook to exynos_cpu_info.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 6f08b15..af9332c 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -39,11 +39,13 @@ extern void exynos4_secondary_startup(void);
  * @cpu_boot_reg: computes cpu boot address for requested cpu
  * @cpu_power_down: handles cpu power down routine for requested cpu
  * @cpu_power_up: handles cpu power up routine for requested cpu
+ * @cpu_restart: handles cpu restart routine for requested cpu
  */
 struct exynos_cpu_info {
 	void __iomem* (*cpu_boot_reg)(u32 cpu);
 	void (*cpu_power_down)(u32 cpu);
 	void (*cpu_power_up)(u32 cpu);
+	void (*cpu_restart)(u32 cpu);
 };
 
 static const struct exynos_cpu_info *cpu_info;
@@ -252,16 +254,19 @@ static inline void __iomem *cpu_boot_reg(int cpu)
 }
 
 /*
- * Set wake up by local power mode and execute software reset for given core.
- *
+ * exynos_core_restart : restart the specified cpu
+ * @core_id : the cpu to be restarted
  * Currently this is needed only when booting secondary CPU on Exynos3250.
  */
 void exynos_core_restart(u32 core_id)
 {
-	u32 val;
+	if (cpu_info && cpu_info->cpu_restart)
+		cpu_info->cpu_restart(core_id);
+}
 
-	if (!of_machine_is_compatible("samsung,exynos3250"))
-		return;
+static void exynos3250_core_restart(u32 core_id)
+{
+	u32 val;
 
 	while (!pmu_raw_readl(S5P_PMU_SPARE2))
 		udelay(10);
@@ -362,6 +367,7 @@ static const struct exynos_cpu_info exynos3250_cpu_info = {
 	.cpu_boot_reg = exynos_common_cpu_boot_reg,
 	.cpu_power_down = exynos_common_cpu_power_down,
 	.cpu_power_up = exynos3250_cpu_power_up,
+	.cpu_restart = exynos3250_core_restart,
 };
 
 static const struct exynos_cpu_info exynos5420_cpu_info = {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 11/12] ARM: EXYNOS: move cpu_restart as a SoC specific hook to exynos_cpu_info
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

To handle differences in cpu_restart functionality among various Exynos SoC
let's move cpu_restart as a SoC specific function hook to exynos_cpu_info.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/platsmp.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 6f08b15..af9332c 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -39,11 +39,13 @@ extern void exynos4_secondary_startup(void);
  * @cpu_boot_reg: computes cpu boot address for requested cpu
  * @cpu_power_down: handles cpu power down routine for requested cpu
  * @cpu_power_up: handles cpu power up routine for requested cpu
+ * @cpu_restart: handles cpu restart routine for requested cpu
  */
 struct exynos_cpu_info {
 	void __iomem* (*cpu_boot_reg)(u32 cpu);
 	void (*cpu_power_down)(u32 cpu);
 	void (*cpu_power_up)(u32 cpu);
+	void (*cpu_restart)(u32 cpu);
 };
 
 static const struct exynos_cpu_info *cpu_info;
@@ -252,16 +254,19 @@ static inline void __iomem *cpu_boot_reg(int cpu)
 }
 
 /*
- * Set wake up by local power mode and execute software reset for given core.
- *
+ * exynos_core_restart : restart the specified cpu
+ * @core_id : the cpu to be restarted
  * Currently this is needed only when booting secondary CPU on Exynos3250.
  */
 void exynos_core_restart(u32 core_id)
 {
-	u32 val;
+	if (cpu_info && cpu_info->cpu_restart)
+		cpu_info->cpu_restart(core_id);
+}
 
-	if (!of_machine_is_compatible("samsung,exynos3250"))
-		return;
+static void exynos3250_core_restart(u32 core_id)
+{
+	u32 val;
 
 	while (!pmu_raw_readl(S5P_PMU_SPARE2))
 		udelay(10);
@@ -362,6 +367,7 @@ static const struct exynos_cpu_info exynos3250_cpu_info = {
 	.cpu_boot_reg = exynos_common_cpu_boot_reg,
 	.cpu_power_down = exynos_common_cpu_power_down,
 	.cpu_power_up = exynos3250_cpu_power_up,
+	.cpu_restart = exynos3250_core_restart,
 };
 
 static const struct exynos_cpu_info exynos5420_cpu_info = {
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
       [not found]   ` <CGME20170330131444epcas5p45051cf7e6ec7a993c2c9f84254b89a19@epcas5p4.samsung.com>
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, m.szyprowski, kgene, m.reichl, a.hajda, cwchoi00,
	javier, Pankaj Dubey

Since now we have chipid driver in place and all dependencies of
soc_is_exynosMMMM macros have been address, lets remove all such
macros. Also remove static mapping of chipid SFR in exynos.c and
related helper functions.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/common.h                | 97 ----------------------------
 arch/arm/mach-exynos/exynos.c                | 44 +++----------
 arch/arm/mach-exynos/platsmp.c               |  2 +-
 arch/arm/plat-samsung/cpu.c                  | 14 ----
 arch/arm/plat-samsung/include/plat/cpu.h     |  2 -
 arch/arm/plat-samsung/include/plat/map-s5p.h |  2 -
 6 files changed, 11 insertions(+), 150 deletions(-)

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 9424a8a..9d76cf8 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -14,102 +14,6 @@
 
 #include <linux/platform_data/cpuidle-exynos.h>
 
-#define EXYNOS3250_SOC_ID	0xE3472000
-#define EXYNOS3_SOC_MASK	0xFFFFF000
-
-#define EXYNOS4210_CPU_ID	0x43210000
-#define EXYNOS4212_CPU_ID	0x43220000
-#define EXYNOS4412_CPU_ID	0xE4412200
-#define EXYNOS4_CPU_MASK	0xFFFE0000
-
-#define EXYNOS5250_SOC_ID	0x43520000
-#define EXYNOS5410_SOC_ID	0xE5410000
-#define EXYNOS5420_SOC_ID	0xE5420000
-#define EXYNOS5440_SOC_ID	0xE5440000
-#define EXYNOS5800_SOC_ID	0xE5422000
-#define EXYNOS5_SOC_MASK	0xFFFFF000
-
-extern unsigned long samsung_cpu_id;
-
-#define IS_SAMSUNG_CPU(name, id, mask)		\
-static inline int is_samsung_##name(void)	\
-{						\
-	return ((samsung_cpu_id & mask) == (id & mask));	\
-}
-
-IS_SAMSUNG_CPU(exynos3250, EXYNOS3250_SOC_ID, EXYNOS3_SOC_MASK)
-IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK)
-IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
-IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
-IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
-
-#if defined(CONFIG_SOC_EXYNOS3250)
-# define soc_is_exynos3250()	is_samsung_exynos3250()
-#else
-# define soc_is_exynos3250()	0
-#endif
-
-#if defined(CONFIG_CPU_EXYNOS4210)
-# define soc_is_exynos4210()	is_samsung_exynos4210()
-#else
-# define soc_is_exynos4210()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS4212)
-# define soc_is_exynos4212()	is_samsung_exynos4212()
-#else
-# define soc_is_exynos4212()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS4412)
-# define soc_is_exynos4412()	is_samsung_exynos4412()
-#else
-# define soc_is_exynos4412()	0
-#endif
-
-#define EXYNOS4210_REV_0	(0x0)
-#define EXYNOS4210_REV_1_0	(0x10)
-#define EXYNOS4210_REV_1_1	(0x11)
-
-#if defined(CONFIG_SOC_EXYNOS5250)
-# define soc_is_exynos5250()	is_samsung_exynos5250()
-#else
-# define soc_is_exynos5250()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5410)
-# define soc_is_exynos5410()	is_samsung_exynos5410()
-#else
-# define soc_is_exynos5410()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5420)
-# define soc_is_exynos5420()	is_samsung_exynos5420()
-#else
-# define soc_is_exynos5420()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5440)
-# define soc_is_exynos5440()	is_samsung_exynos5440()
-#else
-# define soc_is_exynos5440()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5800)
-# define soc_is_exynos5800()	is_samsung_exynos5800()
-#else
-# define soc_is_exynos5800()	0
-#endif
-
-#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4212() || \
-			  soc_is_exynos4412())
-#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
-			  soc_is_exynos5420() || soc_is_exynos5800())
-
 extern u32 cp15_save_diag;
 extern u32 cp15_save_power;
 
@@ -166,7 +70,6 @@ extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
 
 extern void exynos_set_delayed_reset_assertion(bool enable);
 
-extern unsigned int samsung_rev(void);
 extern void exynos_core_restart(u32 core_id);
 extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr);
 extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr);
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index c404c15..6543c6c 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -24,7 +24,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/map.h>
-#include <plat/cpu.h>
 
 #include "common.h"
 
@@ -76,50 +75,27 @@ static void __init exynos_init_late(void)
 	exynos_pm_init();
 }
 
-static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
-					int depth, void *data)
-{
-	struct map_desc iodesc;
-	const __be32 *reg;
-	int len;
-
-	if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
-		!of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
-		return 0;
-
-	reg = of_get_flat_dt_prop(node, "reg", &len);
-	if (reg == NULL || len != (sizeof(unsigned long) * 2))
-		return 0;
-
-	iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
-	iodesc.length = be32_to_cpu(reg[1]) - 1;
-	iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
-	iodesc.type = MT_DEVICE;
-	iotable_init(&iodesc, 1);
-	return 1;
-}
-
 /*
  * exynos_map_io
  *
  * register the standard cpu IO areas
  */
-static void __init exynos_map_io(void)
+static int __init exynos_fdt_map_scu(unsigned long node, const char *uname,
+		int depth, void *data)
 {
-	if (soc_is_exynos4())
-		iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+	if (!of_flat_dt_is_compatible(node, "samsung,exynos4210") &&
+			!of_flat_dt_is_compatible(node, "samsung,exynos4212") &&
+			!of_flat_dt_is_compatible(node, "samsung,exynos4412"))
+		return 0;
+
+	iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+	return 1;
 }
 
 static void __init exynos_init_io(void)
 {
 	debug_ll_io_init();
-
-	of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
-
-	/* detect cpu id and rev. */
-	s5p_init_cpu(S5P_VA_CHIPID);
-
-	exynos_map_io();
+	of_scan_flat_dt(exynos_fdt_map_scu, NULL);
 }
 
 /*
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index af9332c..c44acc8 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -510,7 +510,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 		call_firmware_op(cpu_boot, core_id);
 
-		if (soc_is_exynos3250())
+		if (of_machine_is_compatible("samsung,exynos3250"))
 			dsb_sev();
 		else
 			arch_send_wakeup_ipi_mask(cpumask_of(cpu));
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
index a107b3a..e58f0f6 100644
--- a/arch/arm/plat-samsung/cpu.c
+++ b/arch/arm/plat-samsung/cpu.c
@@ -21,12 +21,6 @@
 unsigned long samsung_cpu_id;
 static unsigned int samsung_cpu_rev;
 
-unsigned int samsung_rev(void)
-{
-	return samsung_cpu_rev;
-}
-EXPORT_SYMBOL(samsung_rev);
-
 void __init s3c64xx_init_cpu(void)
 {
 	samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0x118);
@@ -43,11 +37,3 @@ void __init s3c64xx_init_cpu(void)
 
 	pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
 }
-
-void __init s5p_init_cpu(const void __iomem *cpuid_addr)
-{
-	samsung_cpu_id = readl_relaxed(cpuid_addr);
-	samsung_cpu_rev = samsung_cpu_id & 0xFF;
-
-	pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
-}
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index b7b702a..913c176 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -115,8 +115,6 @@ extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
 extern void s3c64xx_init_cpu(void);
 extern void s5p_init_cpu(const void __iomem *cpuid_addr);
 
-extern unsigned int samsung_rev(void);
-
 extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
 extern void s3c24xx_init_clocks(int xtal);
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index 0fe2828..8a31d4b 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -13,8 +13,6 @@
 #ifndef __ASM_PLAT_MAP_S5P_H
 #define __ASM_PLAT_MAP_S5P_H __FILE__
 
-#define S5P_VA_CHIPID		S3C_ADDR(0x02000000)
-
 #define S5P_VA_COREPERI_BASE	S3C_ADDR(0x02800000)
 #define S5P_VA_COREPERI(x)	(S5P_VA_COREPERI_BASE + (x))
 #define S5P_VA_SCU		S5P_VA_COREPERI(0x0)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
@ 2017-03-30 13:17       ` Pankaj Dubey
  0 siblings, 0 replies; 98+ messages in thread
From: Pankaj Dubey @ 2017-03-30 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

Since now we have chipid driver in place and all dependencies of
soc_is_exynosMMMM macros have been address, lets remove all such
macros. Also remove static mapping of chipid SFR in exynos.c and
related helper functions.

Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
---
 arch/arm/mach-exynos/common.h                | 97 ----------------------------
 arch/arm/mach-exynos/exynos.c                | 44 +++----------
 arch/arm/mach-exynos/platsmp.c               |  2 +-
 arch/arm/plat-samsung/cpu.c                  | 14 ----
 arch/arm/plat-samsung/include/plat/cpu.h     |  2 -
 arch/arm/plat-samsung/include/plat/map-s5p.h |  2 -
 6 files changed, 11 insertions(+), 150 deletions(-)

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 9424a8a..9d76cf8 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -14,102 +14,6 @@
 
 #include <linux/platform_data/cpuidle-exynos.h>
 
-#define EXYNOS3250_SOC_ID	0xE3472000
-#define EXYNOS3_SOC_MASK	0xFFFFF000
-
-#define EXYNOS4210_CPU_ID	0x43210000
-#define EXYNOS4212_CPU_ID	0x43220000
-#define EXYNOS4412_CPU_ID	0xE4412200
-#define EXYNOS4_CPU_MASK	0xFFFE0000
-
-#define EXYNOS5250_SOC_ID	0x43520000
-#define EXYNOS5410_SOC_ID	0xE5410000
-#define EXYNOS5420_SOC_ID	0xE5420000
-#define EXYNOS5440_SOC_ID	0xE5440000
-#define EXYNOS5800_SOC_ID	0xE5422000
-#define EXYNOS5_SOC_MASK	0xFFFFF000
-
-extern unsigned long samsung_cpu_id;
-
-#define IS_SAMSUNG_CPU(name, id, mask)		\
-static inline int is_samsung_##name(void)	\
-{						\
-	return ((samsung_cpu_id & mask) == (id & mask));	\
-}
-
-IS_SAMSUNG_CPU(exynos3250, EXYNOS3250_SOC_ID, EXYNOS3_SOC_MASK)
-IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK)
-IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK)
-IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
-IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
-IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
-
-#if defined(CONFIG_SOC_EXYNOS3250)
-# define soc_is_exynos3250()	is_samsung_exynos3250()
-#else
-# define soc_is_exynos3250()	0
-#endif
-
-#if defined(CONFIG_CPU_EXYNOS4210)
-# define soc_is_exynos4210()	is_samsung_exynos4210()
-#else
-# define soc_is_exynos4210()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS4212)
-# define soc_is_exynos4212()	is_samsung_exynos4212()
-#else
-# define soc_is_exynos4212()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS4412)
-# define soc_is_exynos4412()	is_samsung_exynos4412()
-#else
-# define soc_is_exynos4412()	0
-#endif
-
-#define EXYNOS4210_REV_0	(0x0)
-#define EXYNOS4210_REV_1_0	(0x10)
-#define EXYNOS4210_REV_1_1	(0x11)
-
-#if defined(CONFIG_SOC_EXYNOS5250)
-# define soc_is_exynos5250()	is_samsung_exynos5250()
-#else
-# define soc_is_exynos5250()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5410)
-# define soc_is_exynos5410()	is_samsung_exynos5410()
-#else
-# define soc_is_exynos5410()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5420)
-# define soc_is_exynos5420()	is_samsung_exynos5420()
-#else
-# define soc_is_exynos5420()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5440)
-# define soc_is_exynos5440()	is_samsung_exynos5440()
-#else
-# define soc_is_exynos5440()	0
-#endif
-
-#if defined(CONFIG_SOC_EXYNOS5800)
-# define soc_is_exynos5800()	is_samsung_exynos5800()
-#else
-# define soc_is_exynos5800()	0
-#endif
-
-#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4212() || \
-			  soc_is_exynos4412())
-#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
-			  soc_is_exynos5420() || soc_is_exynos5800())
-
 extern u32 cp15_save_diag;
 extern u32 cp15_save_power;
 
@@ -166,7 +70,6 @@ extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
 
 extern void exynos_set_delayed_reset_assertion(bool enable);
 
-extern unsigned int samsung_rev(void);
 extern void exynos_core_restart(u32 core_id);
 extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr);
 extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr);
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index c404c15..6543c6c 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -24,7 +24,6 @@
 #include <asm/mach/map.h>
 
 #include <mach/map.h>
-#include <plat/cpu.h>
 
 #include "common.h"
 
@@ -76,50 +75,27 @@ static void __init exynos_init_late(void)
 	exynos_pm_init();
 }
 
-static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
-					int depth, void *data)
-{
-	struct map_desc iodesc;
-	const __be32 *reg;
-	int len;
-
-	if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
-		!of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
-		return 0;
-
-	reg = of_get_flat_dt_prop(node, "reg", &len);
-	if (reg == NULL || len != (sizeof(unsigned long) * 2))
-		return 0;
-
-	iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
-	iodesc.length = be32_to_cpu(reg[1]) - 1;
-	iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
-	iodesc.type = MT_DEVICE;
-	iotable_init(&iodesc, 1);
-	return 1;
-}
-
 /*
  * exynos_map_io
  *
  * register the standard cpu IO areas
  */
-static void __init exynos_map_io(void)
+static int __init exynos_fdt_map_scu(unsigned long node, const char *uname,
+		int depth, void *data)
 {
-	if (soc_is_exynos4())
-		iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+	if (!of_flat_dt_is_compatible(node, "samsung,exynos4210") &&
+			!of_flat_dt_is_compatible(node, "samsung,exynos4212") &&
+			!of_flat_dt_is_compatible(node, "samsung,exynos4412"))
+		return 0;
+
+	iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+	return 1;
 }
 
 static void __init exynos_init_io(void)
 {
 	debug_ll_io_init();
-
-	of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
-
-	/* detect cpu id and rev. */
-	s5p_init_cpu(S5P_VA_CHIPID);
-
-	exynos_map_io();
+	of_scan_flat_dt(exynos_fdt_map_scu, NULL);
 }
 
 /*
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index af9332c..c44acc8 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -510,7 +510,7 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 		call_firmware_op(cpu_boot, core_id);
 
-		if (soc_is_exynos3250())
+		if (of_machine_is_compatible("samsung,exynos3250"))
 			dsb_sev();
 		else
 			arch_send_wakeup_ipi_mask(cpumask_of(cpu));
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
index a107b3a..e58f0f6 100644
--- a/arch/arm/plat-samsung/cpu.c
+++ b/arch/arm/plat-samsung/cpu.c
@@ -21,12 +21,6 @@
 unsigned long samsung_cpu_id;
 static unsigned int samsung_cpu_rev;
 
-unsigned int samsung_rev(void)
-{
-	return samsung_cpu_rev;
-}
-EXPORT_SYMBOL(samsung_rev);
-
 void __init s3c64xx_init_cpu(void)
 {
 	samsung_cpu_id = readl_relaxed(S3C_VA_SYS + 0x118);
@@ -43,11 +37,3 @@ void __init s3c64xx_init_cpu(void)
 
 	pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
 }
-
-void __init s5p_init_cpu(const void __iomem *cpuid_addr)
-{
-	samsung_cpu_id = readl_relaxed(cpuid_addr);
-	samsung_cpu_rev = samsung_cpu_id & 0xFF;
-
-	pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
-}
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index b7b702a..913c176 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -115,8 +115,6 @@ extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
 extern void s3c64xx_init_cpu(void);
 extern void s5p_init_cpu(const void __iomem *cpuid_addr);
 
-extern unsigned int samsung_rev(void);
-
 extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
 extern void s3c24xx_init_clocks(int xtal);
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index 0fe2828..8a31d4b 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -13,8 +13,6 @@
 #ifndef __ASM_PLAT_MAP_S5P_H
 #define __ASM_PLAT_MAP_S5P_H __FILE__
 
-#define S5P_VA_CHIPID		S3C_ADDR(0x02000000)
-
 #define S5P_VA_COREPERI_BASE	S3C_ADDR(0x02800000)
 #define S5P_VA_COREPERI(x)	(S5P_VA_COREPERI_BASE + (x))
 #define S5P_VA_SCU		S5P_VA_COREPERI(0x0)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-03-30 13:16       ` Pankaj Dubey
@ 2017-03-30 13:50         ` Arnd Bergmann
  -1 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 13:50 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas, Grant Likely, Rob Herring,
	Linus Walleij

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>
> +config EXYNOS_CHIPID
> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || COMPILE_TEST
> +       select SOC_BUS

This lets you disable the driver when COMPILE_TEST is set on exynos,
which is probably not what you wanted.

I'd do

         bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
         default ARCH_EXYNOS

     Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-03-30 13:50         ` Arnd Bergmann
  0 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 13:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>
> +config EXYNOS_CHIPID
> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || COMPILE_TEST
> +       select SOC_BUS

This lets you disable the driver when COMPILE_TEST is set on exynos,
which is probably not what you wanted.

I'd do

         bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
         default ARCH_EXYNOS

     Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 06/12] ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-03-30 13:51         ` Arnd Bergmann
  -1 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 13:51 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> This patch enables exynos_chipid driver for ARCH_EXYNOS
> based SoC.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm64/Kconfig.platforms | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 9cdaecd..b238204 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -54,6 +54,7 @@ config ARCH_BRCMSTB
>  config ARCH_EXYNOS
>         bool "ARMv8 based Samsung Exynos SoC family"
>         select COMMON_CLK_SAMSUNG
> +       select EXYNOS_CHIPID

If you check for ARCH_EXYNOS in the driver Kconfig entry, then
this patch is not needed.

       Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 06/12] ARM64: EXYNOS: enable exynos_chipid for ARCH_EXYNOS
@ 2017-03-30 13:51         ` Arnd Bergmann
  0 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> This patch enables exynos_chipid driver for ARCH_EXYNOS
> based SoC.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm64/Kconfig.platforms | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 9cdaecd..b238204 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -54,6 +54,7 @@ config ARCH_BRCMSTB
>  config ARCH_EXYNOS
>         bool "ARMv8 based Samsung Exynos SoC family"
>         select COMMON_CLK_SAMSUNG
> +       select EXYNOS_CHIPID

If you check for ARCH_EXYNOS in the driver Kconfig entry, then
this patch is not needed.

       Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-03-30 14:01         ` Arnd Bergmann
  -1 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 14:01 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:

>   * register the standard cpu IO areas
>   */
> -static void __init exynos_map_io(void)
> +static int __init exynos_fdt_map_scu(unsigned long node, const char *uname,
> +               int depth, void *data)
>  {
> -       if (soc_is_exynos4())
> -               iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
> +       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210") &&
> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4212") &&
> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4412"))
> +               return 0;
> +
> +       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
> +       return 1;
>  }

This seems really overcomplicated. From what I can tell, this is only needed
to find the SCU address, but there are better ways to do that, either by
looking up the SCU in the DT at the time you actually need it,
or by calling scu_a9_get_base().

      Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
@ 2017-03-30 14:01         ` Arnd Bergmann
  0 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:

>   * register the standard cpu IO areas
>   */
> -static void __init exynos_map_io(void)
> +static int __init exynos_fdt_map_scu(unsigned long node, const char *uname,
> +               int depth, void *data)
>  {
> -       if (soc_is_exynos4())
> -               iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
> +       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210") &&
> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4212") &&
> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4412"))
> +               return 0;
> +
> +       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
> +       return 1;
>  }

This seems really overcomplicated. From what I can tell, this is only needed
to find the SCU address, but there are better ways to do that, either by
looking up the SCU in the DT at the time you actually need it,
or by calling scu_a9_get_base().

      Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-03-30 14:03         ` Arnd Bergmann
  -1 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 14:03 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:

> +               .soc_id = "EXYNOS5250",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5260",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5440",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5410",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5420",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5800",
> +               .data = &exynos_common_s2r_data

If these are all the same, just make that soc_id="EXYNOS5*"
to match them all at once.

> +int __init exynos_s2r_init(void)
> +{
> +       const struct soc_device_attribute *match;
> +
> +       match = soc_device_match(exynos_soc_revision);
> +
> +       if (match)
> +               s2r_data = (const struct exynos_s2r_data *) match->data;
> +
> +       if (!s2r_data)
> +               return -ENODEV;
> +
> +       return 0;
> +}
> +arch_initcall(exynos_s2r_init);
> +

Can you replace the arch_initcall with a direct call from the machine
init function?

        Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
@ 2017-03-30 14:03         ` Arnd Bergmann
  0 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-30 14:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:

> +               .soc_id = "EXYNOS5250",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5260",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5440",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5410",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5420",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5800",
> +               .data = &exynos_common_s2r_data

If these are all the same, just make that soc_id="EXYNOS5*"
to match them all at once.

> +int __init exynos_s2r_init(void)
> +{
> +       const struct soc_device_attribute *match;
> +
> +       match = soc_device_match(exynos_soc_revision);
> +
> +       if (match)
> +               s2r_data = (const struct exynos_s2r_data *) match->data;
> +
> +       if (!s2r_data)
> +               return -ENODEV;
> +
> +       return 0;
> +}
> +arch_initcall(exynos_s2r_init);
> +

Can you replace the arch_initcall with a direct call from the machine
init function?

        Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-03-30 13:50         ` Arnd Bergmann
@ 2017-03-31  5:36           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-03-31  5:36 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas, Grant Likely, Rob Herring,
	Linus Walleij

Hi Arnd,

On Thursday 30 March 2017 07:20 PM, Arnd Bergmann wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>
>> +config EXYNOS_CHIPID
>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>> +       select SOC_BUS
> 
> This lets you disable the driver when COMPILE_TEST is set on exynos,
> which is probably not what you wanted.
> 

Sorry I could not get this point. EXYNOS_CHIPID is invisible menu
option, when I enabled COMPILE_TEST, option is visible in make
menuconfig but it does not allow to disable this driver. I have adopted
this config same as EXYNOS_PMU in the same file.

> I'd do
> 
>          bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
>          default ARCH_EXYNOS

I can adopt, default ARCH_EXYNOS, which will allow me to drop patch 5/12
and 6/12.

Thanks for review.
Pankaj Dubey

> 
>      Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-03-31  5:36           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-03-31  5:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Thursday 30 March 2017 07:20 PM, Arnd Bergmann wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>
>> +config EXYNOS_CHIPID
>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>> +       select SOC_BUS
> 
> This lets you disable the driver when COMPILE_TEST is set on exynos,
> which is probably not what you wanted.
> 

Sorry I could not get this point. EXYNOS_CHIPID is invisible menu
option, when I enabled COMPILE_TEST, option is visible in make
menuconfig but it does not allow to disable this driver. I have adopted
this config same as EXYNOS_PMU in the same file.

> I'd do
> 
>          bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
>          default ARCH_EXYNOS

I can adopt, default ARCH_EXYNOS, which will allow me to drop patch 5/12
and 6/12.

Thanks for review.
Pankaj Dubey

> 
>      Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
  2017-03-30 14:01         ` Arnd Bergmann
@ 2017-03-31  6:01           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-03-31  6:01 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas



On Thursday 30 March 2017 07:31 PM, Arnd Bergmann wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> 
>>   * register the standard cpu IO areas
>>   */
>> -static void __init exynos_map_io(void)
>> +static int __init exynos_fdt_map_scu(unsigned long node, const char *uname,
>> +               int depth, void *data)
>>  {
>> -       if (soc_is_exynos4())
>> -               iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
>> +       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210") &&
>> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4212") &&
>> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4412"))
>> +               return 0;
>> +
>> +       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
>> +       return 1;
>>  }
> 
> This seems really overcomplicated. From what I can tell, this is only needed
> to find the SCU address, but there are better ways to do that, either by
> looking up the SCU in the DT at the time you actually need it,
> or by calling scu_a9_get_base().

Indeed it's complicated and ugly, for the same reason I attempted to
clean-up this part for Exynos SoC in patch series [1], which was
accepted by Samsung maintainer Krzysztof and later during pull request
rejected by ARM maintainers [2]

[1]: https://www.spinics.net/lists/arm-kernel/msg540498.html
[2]: http://lkml.iu.edu/hypermail/linux/kernel/1612.0/01508.html

Given the argument we can't adopt getting base address of SCU completely
via DT without breaking OLD dtbs at some point, difficult to simplify
these stuffs.

Please guide which is the best way to handle such stuffs.

In fact I made another attempt [3] to cleanup this SCU related stuffs
for other ARM based platforms, but we could not arrive on some consensus
at that time. I will try to attempt it again soon.

[3]: http://www.spinics.net/lists/arm-kernel/msg542351.html

Thanks,
Pankaj Dubey

> 
>       Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
@ 2017-03-31  6:01           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-03-31  6:01 UTC (permalink / raw)
  To: linux-arm-kernel



On Thursday 30 March 2017 07:31 PM, Arnd Bergmann wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> 
>>   * register the standard cpu IO areas
>>   */
>> -static void __init exynos_map_io(void)
>> +static int __init exynos_fdt_map_scu(unsigned long node, const char *uname,
>> +               int depth, void *data)
>>  {
>> -       if (soc_is_exynos4())
>> -               iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
>> +       if (!of_flat_dt_is_compatible(node, "samsung,exynos4210") &&
>> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4212") &&
>> +                       !of_flat_dt_is_compatible(node, "samsung,exynos4412"))
>> +               return 0;
>> +
>> +       iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
>> +       return 1;
>>  }
> 
> This seems really overcomplicated. From what I can tell, this is only needed
> to find the SCU address, but there are better ways to do that, either by
> looking up the SCU in the DT at the time you actually need it,
> or by calling scu_a9_get_base().

Indeed it's complicated and ugly, for the same reason I attempted to
clean-up this part for Exynos SoC in patch series [1], which was
accepted by Samsung maintainer Krzysztof and later during pull request
rejected by ARM maintainers [2]

[1]: https://www.spinics.net/lists/arm-kernel/msg540498.html
[2]: http://lkml.iu.edu/hypermail/linux/kernel/1612.0/01508.html

Given the argument we can't adopt getting base address of SCU completely
via DT without breaking OLD dtbs at some point, difficult to simplify
these stuffs.

Please guide which is the best way to handle such stuffs.

In fact I made another attempt [3] to cleanup this SCU related stuffs
for other ARM based platforms, but we could not arrive on some consensus
at that time. I will try to attempt it again soon.

[3]: http://www.spinics.net/lists/arm-kernel/msg542351.html

Thanks,
Pankaj Dubey

> 
>       Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-03-31  5:36           ` pankaj.dubey
@ 2017-03-31  8:09             ` Arnd Bergmann
  -1 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-31  8:09 UTC (permalink / raw)
  To: pankaj.dubey
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas, Grant Likely, Rob Herring,
	Linus Walleij

On Fri, Mar 31, 2017 at 7:36 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
> Hi Arnd,
>
> On Thursday 30 March 2017 07:20 PM, Arnd Bergmann wrote:
>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>
>>> +config EXYNOS_CHIPID
>>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>>> +       select SOC_BUS
>>
>> This lets you disable the driver when COMPILE_TEST is set on exynos,
>> which is probably not what you wanted.
>>
>
> Sorry I could not get this point. EXYNOS_CHIPID is invisible menu
> option, when I enabled COMPILE_TEST, option is visible in make
> menuconfig but it does not allow to disable this driver. I have adopted
> this config same as EXYNOS_PMU in the same file.

I wrote my comment before I saw the 'select' statement in the later
patch. With that select, it is not a problem.

>>          bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
>>          default ARCH_EXYNOS
>
> I can adopt, default ARCH_EXYNOS, which will allow me to drop patch 5/12
> and 6/12.

Either way (select or default) is fine, just do the same thing for both chipid
and pmu. If you keep the 'select' and the 'if COMPILE_TEST', you can
drop the line 'depends on ARCH_EXYNOS || COMPILE_TEST'.

      Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-03-31  8:09             ` Arnd Bergmann
  0 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-31  8:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 31, 2017 at 7:36 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
> Hi Arnd,
>
> On Thursday 30 March 2017 07:20 PM, Arnd Bergmann wrote:
>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>
>>> +config EXYNOS_CHIPID
>>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>>> +       select SOC_BUS
>>
>> This lets you disable the driver when COMPILE_TEST is set on exynos,
>> which is probably not what you wanted.
>>
>
> Sorry I could not get this point. EXYNOS_CHIPID is invisible menu
> option, when I enabled COMPILE_TEST, option is visible in make
> menuconfig but it does not allow to disable this driver. I have adopted
> this config same as EXYNOS_PMU in the same file.

I wrote my comment before I saw the 'select' statement in the later
patch. With that select, it is not a problem.

>>          bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
>>          default ARCH_EXYNOS
>
> I can adopt, default ARCH_EXYNOS, which will allow me to drop patch 5/12
> and 6/12.

Either way (select or default) is fine, just do the same thing for both chipid
and pmu. If you keep the 'select' and the 'if COMPILE_TEST', you can
drop the line 'depends on ARCH_EXYNOS || COMPILE_TEST'.

      Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
  2017-03-31  6:01           ` pankaj.dubey
@ 2017-03-31  8:22             ` Arnd Bergmann
  -1 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-31  8:22 UTC (permalink / raw)
  To: pankaj.dubey
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas

On Fri, Mar 31, 2017 at 8:01 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
> On Thursday 30 March 2017 07:31 PM, Arnd Bergmann wrote:
>> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>
>> This seems really overcomplicated. From what I can tell, this is only needed
>> to find the SCU address, but there are better ways to do that, either by
>> looking up the SCU in the DT at the time you actually need it,
>> or by calling scu_a9_get_base().
>
> Indeed it's complicated and ugly, for the same reason I attempted to
> clean-up this part for Exynos SoC in patch series [1], which was
> accepted by Samsung maintainer Krzysztof and later during pull request
> rejected by ARM maintainers [2]
>
> [1]: https://www.spinics.net/lists/arm-kernel/msg540498.html
> [2]: http://lkml.iu.edu/hypermail/linux/kernel/1612.0/01508.html
>
> Given the argument we can't adopt getting base address of SCU completely
> via DT without breaking OLD dtbs at some point, difficult to simplify
> these stuffs.
>
> Please guide which is the best way to handle such stuffs.
>
> In fact I made another attempt [3] to cleanup this SCU related stuffs
> for other ARM based platforms, but we could not arrive on some consensus
> at that time. I will try to attempt it again soon.
>
> [3]: http://www.spinics.net/lists/arm-kernel/msg542351.html

I very much appreciate your attempts, this is very helpful. I'm sorry
for making it so hard for you. I had remembered your previous series,
but did not realize that you were the author of both this patch and
the SCU cleanup.

Let me try to understand the entire problem space better. These
are my assumptions based on what  you write:

- A clean solution would be to map the SCU based on the DT as
  you implemented in the earlier patch series, but that breaks
  running new kernels with old DTBs, which we don't want.

- Another clean solution would be to map the SCU based on
  scu_a9_get_base(), but that doesn't work on all variants of
  exynos4, because there is at least one (which?) that has incorrect
  data in the register

- The approach in this patch works, but is really ugly as it
  requires parsing the fdt.

Assuming that we don't want any of the approaches above,
here are some other ideas that might be a little better:

- Map the SCU later, just before we first need for calling
  scu_enable(): exynos_smp_prepare_cpus(),
  exynos_enter_aftr() or exynos_pm_resume(). All three
  are late enough that we can simply call ioremap()
  on the known physical address for the first caller,
  and they are all guarded by a
  ARM_CPU_PART_CORTEX_A9 check that should
  be equivalent to the EXYNOS4 check you have.

- Split the exynos4 machine descriptor from the one
  for exynos5, and exynos3, the call the iotable_init
  unconditionally for exynos4. The same method would
  also let us get rid of some of the other
  of_machine_is_compatible() checks.

       Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
@ 2017-03-31  8:22             ` Arnd Bergmann
  0 siblings, 0 replies; 98+ messages in thread
From: Arnd Bergmann @ 2017-03-31  8:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 31, 2017 at 8:01 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
> On Thursday 30 March 2017 07:31 PM, Arnd Bergmann wrote:
>> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>
>> This seems really overcomplicated. From what I can tell, this is only needed
>> to find the SCU address, but there are better ways to do that, either by
>> looking up the SCU in the DT at the time you actually need it,
>> or by calling scu_a9_get_base().
>
> Indeed it's complicated and ugly, for the same reason I attempted to
> clean-up this part for Exynos SoC in patch series [1], which was
> accepted by Samsung maintainer Krzysztof and later during pull request
> rejected by ARM maintainers [2]
>
> [1]: https://www.spinics.net/lists/arm-kernel/msg540498.html
> [2]: http://lkml.iu.edu/hypermail/linux/kernel/1612.0/01508.html
>
> Given the argument we can't adopt getting base address of SCU completely
> via DT without breaking OLD dtbs at some point, difficult to simplify
> these stuffs.
>
> Please guide which is the best way to handle such stuffs.
>
> In fact I made another attempt [3] to cleanup this SCU related stuffs
> for other ARM based platforms, but we could not arrive on some consensus
> at that time. I will try to attempt it again soon.
>
> [3]: http://www.spinics.net/lists/arm-kernel/msg542351.html

I very much appreciate your attempts, this is very helpful. I'm sorry
for making it so hard for you. I had remembered your previous series,
but did not realize that you were the author of both this patch and
the SCU cleanup.

Let me try to understand the entire problem space better. These
are my assumptions based on what  you write:

- A clean solution would be to map the SCU based on the DT as
  you implemented in the earlier patch series, but that breaks
  running new kernels with old DTBs, which we don't want.

- Another clean solution would be to map the SCU based on
  scu_a9_get_base(), but that doesn't work on all variants of
  exynos4, because there is at least one (which?) that has incorrect
  data in the register

- The approach in this patch works, but is really ugly as it
  requires parsing the fdt.

Assuming that we don't want any of the approaches above,
here are some other ideas that might be a little better:

- Map the SCU later, just before we first need for calling
  scu_enable(): exynos_smp_prepare_cpus(),
  exynos_enter_aftr() or exynos_pm_resume(). All three
  are late enough that we can simply call ioremap()
  on the known physical address for the first caller,
  and they are all guarded by a
  ARM_CPU_PART_CORTEX_A9 check that should
  be equivalent to the EXYNOS4 check you have.

- Split the exynos4 machine descriptor from the one
  for exynos5, and exynos3, the call the iotable_init
  unconditionally for exynos4. The same method would
  also let us get rid of some of the other
  of_machine_is_compatible() checks.

       Arnd

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-03-30 13:16       ` Pankaj Dubey
@ 2017-04-03  7:57         ` Marek Szyprowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2017-04-03  7:57 UTC (permalink / raw)
  To: Pankaj Dubey, linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, kgene, m.reichl, a.hajda, cwchoi00, javier,
	Grant Likely, Rob Herring, Linus Walleij

Hi Pankaj

On 2017-03-30 15:16, Pankaj Dubey wrote:
> Exynos SoCs have Chipid, for identification of product IDs and SoC
> revisions. This patch intends to provide initialization code for all
> these functionalities, at the same time it provides some sysfs entries
> for accessing these information to user-space.
>
> This driver uses existing binding for exynos-chipid.
>
> CC: Grant Likely <grant.likely@linaro.org>
> CC: Rob Herring <robh+dt@kernel.org>
> CC: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>   drivers/soc/samsung/Kconfig         |   5 ++
>   drivers/soc/samsung/Makefile        |   1 +
>   drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 115 insertions(+)
>   create mode 100644 drivers/soc/samsung/exynos-chipid.c
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 8b25bd5..a90a4ad 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
>   
>   if SOC_SAMSUNG
>   
> +config EXYNOS_CHIPID
> +	bool "Exynos Chipid controller driver" if COMPILE_TEST
> +	depends on ARCH_EXYNOS || COMPILE_TEST
> +	select SOC_BUS
> +
>   config EXYNOS_PMU
>   	bool "Exynos PMU controller driver" if COMPILE_TEST
>   	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 4d7694a..be3b6bb 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
>   obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
>   
>   obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> new file mode 100644
> index 0000000..1e9fb6b
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * EXYNOS - CHIP ID support
> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +
> +#define EXYNOS_SUBREV_MASK	(0xF << 4)
> +#define EXYNOS_MAINREV_MASK	(0xF << 0)
> +#define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
> +
> +static const struct exynos_soc_id {
> +	const char *name;
> +	unsigned int id;
> +	unsigned int mask;
> +} soc_ids[] = {
> +	{ "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
> +	{ "EXYNOS4210", 0x43210000, 0xFFFFF000 },

You have once again changed the mask for Exynos4 SoCs, so please add
following line to the above array:

{ "EXYNOS4210", 0x43200000, 0xFFFFF000 },       /* EVT0 revision */

Otherwise Exynos C210 (4210 EVT0) is not properly detected:

soc soc0: Exynos: CPU[UNKNOWN] PRO_ID[0x43200200] REV[0x0] Detected

> +	{ "EXYNOS4212", 0x43220000, 0xFFFFF000 },
> +	{ "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
> +	{ "EXYNOS5250", 0x43520000, 0xFFFFF000 },
> +	{ "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
> +	{ "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
> +	{ "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
> +	{ "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
> +	{ "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
> +	{ "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
> +	{ "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
> +};

Now the mask is same for all revisions, so you can remove it from the above
array and directly use some kind of define in the code.

> +
> +static const char * __init product_id_to_soc_id(unsigned int product_id)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
> +		if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
> +			return soc_ids[i].name;
> +	return "UNKNOWN";
> +}
> +
> +int __init exynos_chipid_early_init(void)
> +{
> +	struct soc_device_attribute *soc_dev_attr;
> +	void __iomem *exynos_chipid_base;
> +	struct soc_device *soc_dev;
> +	struct device_node *root;
> +	struct device_node *np;
> +	struct device *dev;
> +	u32 product_id;
> +	u32 revision;
> +
> +	/* look up for chipid node */
> +	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
> +	if (!np)
> +		return -ENODEV;
> +
> +	exynos_chipid_base = of_iomap(np, 0);
> +	of_node_put(np);
> +
> +	if (!exynos_chipid_base) {
> +		pr_err("%s: failed to map chipid\n", np->name);
> +		return -ENOMEM;
> +	}
> +
> +	product_id = readl_relaxed(exynos_chipid_base);
> +	revision = product_id & EXYNOS_REV_MASK;
> +	iounmap(exynos_chipid_base);
> +
> +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +	if (!soc_dev_attr)
> +		return -ENODEV;
> +
> +	soc_dev_attr->family = "Samsung Exynos";
> +
> +	root = of_find_node_by_path("/");
> +	of_property_read_string(root, "model", &soc_dev_attr->machine);
> +	of_node_put(root);
> +
> +	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
> +	soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
> +
> +	soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(soc_dev)) {
> +		kfree(soc_dev_attr->revision);
> +		kfree_const(soc_dev_attr->soc_id);
> +		kfree(soc_dev_attr);
> +		return PTR_ERR(soc_dev);
> +	}
> +	dev = soc_device_to_device(soc_dev);
> +
> +	dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
> +			soc_dev_attr->soc_id, product_id, revision);
> +
> +	return 0;
> +}
> +early_initcall(exynos_chipid_early_init);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-04-03  7:57         ` Marek Szyprowski
  0 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2017-04-03  7:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Pankaj

On 2017-03-30 15:16, Pankaj Dubey wrote:
> Exynos SoCs have Chipid, for identification of product IDs and SoC
> revisions. This patch intends to provide initialization code for all
> these functionalities, at the same time it provides some sysfs entries
> for accessing these information to user-space.
>
> This driver uses existing binding for exynos-chipid.
>
> CC: Grant Likely <grant.likely@linaro.org>
> CC: Rob Herring <robh+dt@kernel.org>
> CC: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>   drivers/soc/samsung/Kconfig         |   5 ++
>   drivers/soc/samsung/Makefile        |   1 +
>   drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 115 insertions(+)
>   create mode 100644 drivers/soc/samsung/exynos-chipid.c
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 8b25bd5..a90a4ad 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
>   
>   if SOC_SAMSUNG
>   
> +config EXYNOS_CHIPID
> +	bool "Exynos Chipid controller driver" if COMPILE_TEST
> +	depends on ARCH_EXYNOS || COMPILE_TEST
> +	select SOC_BUS
> +
>   config EXYNOS_PMU
>   	bool "Exynos PMU controller driver" if COMPILE_TEST
>   	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 4d7694a..be3b6bb 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
>   obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
>   
>   obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> new file mode 100644
> index 0000000..1e9fb6b
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * EXYNOS - CHIP ID support
> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +
> +#define EXYNOS_SUBREV_MASK	(0xF << 4)
> +#define EXYNOS_MAINREV_MASK	(0xF << 0)
> +#define EXYNOS_REV_MASK		(EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
> +
> +static const struct exynos_soc_id {
> +	const char *name;
> +	unsigned int id;
> +	unsigned int mask;
> +} soc_ids[] = {
> +	{ "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
> +	{ "EXYNOS4210", 0x43210000, 0xFFFFF000 },

You have once again changed the mask for Exynos4 SoCs, so please add
following line to the above array:

{ "EXYNOS4210", 0x43200000, 0xFFFFF000 },       /* EVT0 revision */

Otherwise Exynos C210 (4210 EVT0) is not properly detected:

soc soc0: Exynos: CPU[UNKNOWN] PRO_ID[0x43200200] REV[0x0] Detected

> +	{ "EXYNOS4212", 0x43220000, 0xFFFFF000 },
> +	{ "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
> +	{ "EXYNOS5250", 0x43520000, 0xFFFFF000 },
> +	{ "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
> +	{ "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
> +	{ "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
> +	{ "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
> +	{ "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
> +	{ "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
> +	{ "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
> +};

Now the mask is same for all revisions, so you can remove it from the above
array and directly use some kind of define in the code.

> +
> +static const char * __init product_id_to_soc_id(unsigned int product_id)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
> +		if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
> +			return soc_ids[i].name;
> +	return "UNKNOWN";
> +}
> +
> +int __init exynos_chipid_early_init(void)
> +{
> +	struct soc_device_attribute *soc_dev_attr;
> +	void __iomem *exynos_chipid_base;
> +	struct soc_device *soc_dev;
> +	struct device_node *root;
> +	struct device_node *np;
> +	struct device *dev;
> +	u32 product_id;
> +	u32 revision;
> +
> +	/* look up for chipid node */
> +	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
> +	if (!np)
> +		return -ENODEV;
> +
> +	exynos_chipid_base = of_iomap(np, 0);
> +	of_node_put(np);
> +
> +	if (!exynos_chipid_base) {
> +		pr_err("%s: failed to map chipid\n", np->name);
> +		return -ENOMEM;
> +	}
> +
> +	product_id = readl_relaxed(exynos_chipid_base);
> +	revision = product_id & EXYNOS_REV_MASK;
> +	iounmap(exynos_chipid_base);
> +
> +	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +	if (!soc_dev_attr)
> +		return -ENODEV;
> +
> +	soc_dev_attr->family = "Samsung Exynos";
> +
> +	root = of_find_node_by_path("/");
> +	of_property_read_string(root, "model", &soc_dev_attr->machine);
> +	of_node_put(root);
> +
> +	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
> +	soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
> +
> +	soc_dev = soc_device_register(soc_dev_attr);
> +	if (IS_ERR(soc_dev)) {
> +		kfree(soc_dev_attr->revision);
> +		kfree_const(soc_dev_attr->soc_id);
> +		kfree(soc_dev_attr);
> +		return PTR_ERR(soc_dev);
> +	}
> +	dev = soc_device_to_device(soc_dev);
> +
> +	dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
> +			soc_dev_attr->soc_id, product_id, revision);
> +
> +	return 0;
> +}
> +early_initcall(exynos_chipid_early_init);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-04-03  7:57         ` Marek Szyprowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2017-04-03  7:57 UTC (permalink / raw)
  To: Pankaj Dubey, linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, kgene, m.reichl, a.hajda, cwchoi00, javier

Hi Pankaj,

On 2017-03-30 15:17, Pankaj Dubey wrote:
> Various Exynos SoC has different CPU related information, such as CPU
> boot register, programming sequence making CPU up/down. Currently this
> is handled by adding lots of soc_is_exynosMMM checks in the code, in
> an attempt to remove the dependency of such helper functions specific to
> each SoC, let's separate this information pertaining to CPU by introducing
> a new "struct exynos_cpu_info". This struct will contain differences
> associated with CPU on various Exynos SoC. This can be matched by using
> generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>   arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>   1 file changed, 135 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index cb6d199..ff369b9 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -19,6 +19,7 @@
>   #include <linux/smp.h>
>   #include <linux/io.h>
>   #include <linux/of_address.h>
> +#include <linux/sys_soc.h>
>   #include <linux/soc/samsung/exynos-regs-pmu.h>
>   
>   #include <asm/cacheflush.h>
> @@ -33,6 +34,16 @@
>   
>   extern void exynos4_secondary_startup(void);
>   
> +/*
> + * struct exynos_cpu_info - Exynos CPU related info/operations
> + * @cpu_boot_reg: computes cpu boot address for requested cpu
> + */
> +struct exynos_cpu_info {
> +	void __iomem* (*cpu_boot_reg)(u32 cpu);
> +};
> +
> +static const struct exynos_cpu_info *cpu_info;
> +
>   #ifdef CONFIG_HOTPLUG_CPU
>   static inline void cpu_leave_lowpower(u32 core_id)
>   {
> @@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
>   		S5P_CORE_LOCAL_PWR_EN);
>   }
>   
> -static void __iomem *cpu_boot_reg_base(void)
> +static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
>   {
> -	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
> -		return pmu_base_addr + S5P_INFORM5;
> -	return sysram_base_addr;
> +	void __iomem *boot_reg = pmu_base_addr;
> +
> +	if (!boot_reg)
> +		return IOMEM_ERR_PTR(-ENODEV);
> +
> +	boot_reg += S5P_INFORM5;
> +
> +	return boot_reg;
>   }
>   
> -static inline void __iomem *cpu_boot_reg(int cpu)
> +static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
>   {
> -	void __iomem *boot_reg;
> +	void __iomem *boot_reg = sysram_base_addr;
>   
> -	boot_reg = cpu_boot_reg_base();
>   	if (!boot_reg)
>   		return IOMEM_ERR_PTR(-ENODEV);
> -	if (soc_is_exynos4412())
> -		boot_reg += 4*cpu;
> -	else if (soc_is_exynos5420() || soc_is_exynos5800())
> -		boot_reg += 4;
> +
> +	boot_reg += 4*cpu;
> +
>   	return boot_reg;
>   }
>   
> +static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
> +{
> +	void __iomem *boot_reg = sysram_base_addr;
> +
> +	if (!sysram_base_addr)
> +		return IOMEM_ERR_PTR(-ENODEV);
> +
> +	boot_reg += 4;
> +
> +	return boot_reg;
> +}
> +
> +static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
> +{
> +	if (!sysram_base_addr)
> +		return IOMEM_ERR_PTR(-ENODEV);
> +
> +	return sysram_base_addr;
> +}
> +
> +static inline void __iomem *cpu_boot_reg(int cpu)
> +{
> +	if (cpu_info && cpu_info->cpu_boot_reg)
> +		return cpu_info->cpu_boot_reg(cpu);
> +	return NULL;
> +}
> +
>   /*
>    * Set wake up by local power mode and execute software reset for given core.
>    *
> @@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
>   	return ret;
>   }
>   
> +static const struct exynos_cpu_info exynos3250_cpu_info = {
> +	.cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos5420_cpu_info = {
> +	.cpu_boot_reg = exynos5420_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
> +	.cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4412_cpu_info = {
> +	.cpu_boot_reg = exynos4412_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos_common_cpu_info = {
> +	.cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct soc_device_attribute exynos_soc_revision[] = {
> +	{
> +		.soc_id = "EXYNOS4210",
> +		.revision = "11",
> +		.data = &exynos4210_rev11_cpu_info
> +	}, {
> +		.soc_id = "EXYNOS4210",
> +		.revision = "10",
> +		.data = &exynos_common_cpu_info
> +	}
> +};
> +
> +static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {

exynos_pmuc_of_device_ids is a bit too easy to confuse with
drivers/soc/samsung/exynos_*pmu.c drivers and its device tree nodes.
IMHO exynos_soc_of_device_ids is a bit more appropriate here.

> +	{
> +		.compatible = "samsung,exynos3250",
> +		.data = &exynos3250_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos4212",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos4412",
> +		.data = &exynos4412_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5250",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5260",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5410",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5420",
> +		.data = &exynos5420_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5440",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5800",
> +		.data = &exynos5420_cpu_info
> +	},
> +	{ /*sentinel*/ },
> +};
> +
>   static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>   {
>   	unsigned long timeout;
> +	const struct soc_device_attribute *match;
>   	u32 mpidr = cpu_logical_map(cpu);
>   	u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>   	int ret = -ENOSYS;
>   
> +	if (of_machine_is_compatible("samsung,exynos4210")) {
> +		match = soc_device_match(exynos_soc_revision);
> +		if (match)
> +			cpu_info = (const struct exynos_cpu_info *) match->data;
> +	}
> +
>   	/*
>   	 * Set synchronisation state between this boot processor
>   	 * and the secondary one
> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>   
>   static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>   {
> +	const struct of_device_id *match;
> +	struct device_node *np;
> +
> +	if (!of_machine_is_compatible("samsung,exynos4210")) {
> +		np = of_find_matching_node_and_match(NULL,
> +				exynos_pmu_of_device_ids, &match);
> +		if (!np)
> +			pr_err("failed to find supported CPU\n");
> +		else
> +			cpu_info = (const struct exynos_cpu_info *) match->data;
> +	}
> +

This approach nukes on Exynos4210 booted with maxcpus=1, because 
exynos_boot_secondary()
is not called in such case:

Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 805 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 
4.11.0-rc5-00013-g7aa5680b6c53-dirty #1185
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
task: c0b08640 task.stack: c0b00000
PC is at exynos_set_boot_addr+0x64/0x84
LR is at exynos_enter_coupled_lowpower+0x1c/0x74
pc : [<c0117890>]    lr : [<c052f654>]    psr: 60000093
sp : c0b01f00  ip : 02800000  fp : c0b2f7e4
r10: c0b86e44  r9 : 00000001  r8 : dbb97e10
r7 : 00000001  r6 : dbb97e10  r5 : 00000001  r4 : 40116c50
r3 : 00000000  r2 : 00000001  r1 : 40116c50  r0 : 00000000
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 4000404a  DAC: 00000051
Process swapper/0 (pid: 0, stack limit = 0xc0b00210)
Stack: (0xc0b01f00 to 0xc0b02000)
1f00: c01165f8 c0b86e4c c0b05508 c052f654 c052f638 c0b2f844 c0b05508 
90442e5c
1f20: 00000000 c052d528 00041fc9 00000000 00000000 00000000 00000001 
00000001
1f40: c0b05508 dbb97e10 c0b2f7e4 dbb97e10 dae522c0 c0b86e44 c0b86e44 
c052f3b0
1f60: 00000000 c0b05424 00000001 dae522e8 c0b05424 c0b05480 c0b05424 
c0a66e08
1f80: c0b0548c c0b10b0e c0b2f7e4 dbb97e10 00000000 c0152eb0 000000bb 
ffffffff
1fa0: c0b47000 c0a34a38 dbfffb40 412fc091 00000001 c01531cc c0b08640 
c0a00c00
1fc0: ffffffff ffffffff 00000000 c0a00680 00000000 c0a34a38 00000000 
c0b473d4
1fe0: c0b05418 c0a34a34 c0b09870 4000406a 00000000 4000807c 00000000 
00000000
[<c0117890>] (exynos_set_boot_addr) from [<c052f654>] 
(exynos_enter_coupled_lowpower+0x1c/0x74)
[<c052f654>] (exynos_enter_coupled_lowpower) from [<c052d528>] 
(cpuidle_enter_state+0x64/0x264)
[<c052d528>] (cpuidle_enter_state) from [<c052f3b0>] 
(cpuidle_enter_state_coupled+0x394/0x3e4)
[<c052f3b0>] (cpuidle_enter_state_coupled) from [<c0152eb0>] 
(do_idle+0x178/0x200)
[<c0152eb0>] (do_idle) from [<c01531cc>] (cpu_startup_entry+0x18/0x1c)
[<c01531cc>] (cpu_startup_entry) from [<c0a00c00>] 
(start_kernel+0x330/0x398)
[<c0a00c00>] (start_kernel) from [<4000807c>] (0x4000807c)
Code: e1a00005 e12fff33 e3700a01 8a000004 (e5804000)
---[ end trace 46ced8ec429feb82 ]---
Kernel panic - not syncing: Attempted to kill the idle task!

>   	exynos_sysram_init();
>   
>   	exynos_set_delayed_reset_assertion(true);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-04-03  7:57         ` Marek Szyprowski
  0 siblings, 0 replies; 98+ messages in thread
From: Marek Szyprowski @ 2017-04-03  7:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Pankaj,

On 2017-03-30 15:17, Pankaj Dubey wrote:
> Various Exynos SoC has different CPU related information, such as CPU
> boot register, programming sequence making CPU up/down. Currently this
> is handled by adding lots of soc_is_exynosMMM checks in the code, in
> an attempt to remove the dependency of such helper functions specific to
> each SoC, let's separate this information pertaining to CPU by introducing
> a new "struct exynos_cpu_info". This struct will contain differences
> associated with CPU on various Exynos SoC. This can be matched by using
> generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>   arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>   1 file changed, 135 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index cb6d199..ff369b9 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -19,6 +19,7 @@
>   #include <linux/smp.h>
>   #include <linux/io.h>
>   #include <linux/of_address.h>
> +#include <linux/sys_soc.h>
>   #include <linux/soc/samsung/exynos-regs-pmu.h>
>   
>   #include <asm/cacheflush.h>
> @@ -33,6 +34,16 @@
>   
>   extern void exynos4_secondary_startup(void);
>   
> +/*
> + * struct exynos_cpu_info - Exynos CPU related info/operations
> + * @cpu_boot_reg: computes cpu boot address for requested cpu
> + */
> +struct exynos_cpu_info {
> +	void __iomem* (*cpu_boot_reg)(u32 cpu);
> +};
> +
> +static const struct exynos_cpu_info *cpu_info;
> +
>   #ifdef CONFIG_HOTPLUG_CPU
>   static inline void cpu_leave_lowpower(u32 core_id)
>   {
> @@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
>   		S5P_CORE_LOCAL_PWR_EN);
>   }
>   
> -static void __iomem *cpu_boot_reg_base(void)
> +static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
>   {
> -	if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
> -		return pmu_base_addr + S5P_INFORM5;
> -	return sysram_base_addr;
> +	void __iomem *boot_reg = pmu_base_addr;
> +
> +	if (!boot_reg)
> +		return IOMEM_ERR_PTR(-ENODEV);
> +
> +	boot_reg += S5P_INFORM5;
> +
> +	return boot_reg;
>   }
>   
> -static inline void __iomem *cpu_boot_reg(int cpu)
> +static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
>   {
> -	void __iomem *boot_reg;
> +	void __iomem *boot_reg = sysram_base_addr;
>   
> -	boot_reg = cpu_boot_reg_base();
>   	if (!boot_reg)
>   		return IOMEM_ERR_PTR(-ENODEV);
> -	if (soc_is_exynos4412())
> -		boot_reg += 4*cpu;
> -	else if (soc_is_exynos5420() || soc_is_exynos5800())
> -		boot_reg += 4;
> +
> +	boot_reg += 4*cpu;
> +
>   	return boot_reg;
>   }
>   
> +static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
> +{
> +	void __iomem *boot_reg = sysram_base_addr;
> +
> +	if (!sysram_base_addr)
> +		return IOMEM_ERR_PTR(-ENODEV);
> +
> +	boot_reg += 4;
> +
> +	return boot_reg;
> +}
> +
> +static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
> +{
> +	if (!sysram_base_addr)
> +		return IOMEM_ERR_PTR(-ENODEV);
> +
> +	return sysram_base_addr;
> +}
> +
> +static inline void __iomem *cpu_boot_reg(int cpu)
> +{
> +	if (cpu_info && cpu_info->cpu_boot_reg)
> +		return cpu_info->cpu_boot_reg(cpu);
> +	return NULL;
> +}
> +
>   /*
>    * Set wake up by local power mode and execute software reset for given core.
>    *
> @@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
>   	return ret;
>   }
>   
> +static const struct exynos_cpu_info exynos3250_cpu_info = {
> +	.cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos5420_cpu_info = {
> +	.cpu_boot_reg = exynos5420_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
> +	.cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4412_cpu_info = {
> +	.cpu_boot_reg = exynos4412_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos_common_cpu_info = {
> +	.cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct soc_device_attribute exynos_soc_revision[] = {
> +	{
> +		.soc_id = "EXYNOS4210",
> +		.revision = "11",
> +		.data = &exynos4210_rev11_cpu_info
> +	}, {
> +		.soc_id = "EXYNOS4210",
> +		.revision = "10",
> +		.data = &exynos_common_cpu_info
> +	}
> +};
> +
> +static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {

exynos_pmuc_of_device_ids is a bit too easy to confuse with
drivers/soc/samsung/exynos_*pmu.c drivers and its device tree nodes.
IMHO exynos_soc_of_device_ids is a bit more appropriate here.

> +	{
> +		.compatible = "samsung,exynos3250",
> +		.data = &exynos3250_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos4212",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos4412",
> +		.data = &exynos4412_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5250",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5260",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5410",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5420",
> +		.data = &exynos5420_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5440",
> +		.data = &exynos_common_cpu_info
> +	}, {
> +		.compatible = "samsung,exynos5800",
> +		.data = &exynos5420_cpu_info
> +	},
> +	{ /*sentinel*/ },
> +};
> +
>   static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>   {
>   	unsigned long timeout;
> +	const struct soc_device_attribute *match;
>   	u32 mpidr = cpu_logical_map(cpu);
>   	u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>   	int ret = -ENOSYS;
>   
> +	if (of_machine_is_compatible("samsung,exynos4210")) {
> +		match = soc_device_match(exynos_soc_revision);
> +		if (match)
> +			cpu_info = (const struct exynos_cpu_info *) match->data;
> +	}
> +
>   	/*
>   	 * Set synchronisation state between this boot processor
>   	 * and the secondary one
> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>   
>   static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>   {
> +	const struct of_device_id *match;
> +	struct device_node *np;
> +
> +	if (!of_machine_is_compatible("samsung,exynos4210")) {
> +		np = of_find_matching_node_and_match(NULL,
> +				exynos_pmu_of_device_ids, &match);
> +		if (!np)
> +			pr_err("failed to find supported CPU\n");
> +		else
> +			cpu_info = (const struct exynos_cpu_info *) match->data;
> +	}
> +

This approach nukes on Exynos4210 booted with maxcpus=1, because 
exynos_boot_secondary()
is not called in such case:

Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 805 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 
4.11.0-rc5-00013-g7aa5680b6c53-dirty #1185
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
task: c0b08640 task.stack: c0b00000
PC is at exynos_set_boot_addr+0x64/0x84
LR is at exynos_enter_coupled_lowpower+0x1c/0x74
pc : [<c0117890>]    lr : [<c052f654>]    psr: 60000093
sp : c0b01f00  ip : 02800000  fp : c0b2f7e4
r10: c0b86e44  r9 : 00000001  r8 : dbb97e10
r7 : 00000001  r6 : dbb97e10  r5 : 00000001  r4 : 40116c50
r3 : 00000000  r2 : 00000001  r1 : 40116c50  r0 : 00000000
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 4000404a  DAC: 00000051
Process swapper/0 (pid: 0, stack limit = 0xc0b00210)
Stack: (0xc0b01f00 to 0xc0b02000)
1f00: c01165f8 c0b86e4c c0b05508 c052f654 c052f638 c0b2f844 c0b05508 
90442e5c
1f20: 00000000 c052d528 00041fc9 00000000 00000000 00000000 00000001 
00000001
1f40: c0b05508 dbb97e10 c0b2f7e4 dbb97e10 dae522c0 c0b86e44 c0b86e44 
c052f3b0
1f60: 00000000 c0b05424 00000001 dae522e8 c0b05424 c0b05480 c0b05424 
c0a66e08
1f80: c0b0548c c0b10b0e c0b2f7e4 dbb97e10 00000000 c0152eb0 000000bb 
ffffffff
1fa0: c0b47000 c0a34a38 dbfffb40 412fc091 00000001 c01531cc c0b08640 
c0a00c00
1fc0: ffffffff ffffffff 00000000 c0a00680 00000000 c0a34a38 00000000 
c0b473d4
1fe0: c0b05418 c0a34a34 c0b09870 4000406a 00000000 4000807c 00000000 
00000000
[<c0117890>] (exynos_set_boot_addr) from [<c052f654>] 
(exynos_enter_coupled_lowpower+0x1c/0x74)
[<c052f654>] (exynos_enter_coupled_lowpower) from [<c052d528>] 
(cpuidle_enter_state+0x64/0x264)
[<c052d528>] (cpuidle_enter_state) from [<c052f3b0>] 
(cpuidle_enter_state_coupled+0x394/0x3e4)
[<c052f3b0>] (cpuidle_enter_state_coupled) from [<c0152eb0>] 
(do_idle+0x178/0x200)
[<c0152eb0>] (do_idle) from [<c01531cc>] (cpu_startup_entry+0x18/0x1c)
[<c01531cc>] (cpu_startup_entry) from [<c0a00c00>] 
(start_kernel+0x330/0x398)
[<c0a00c00>] (start_kernel) from [<4000807c>] (0x4000807c)
Code: e1a00005 e12fff33 e3700a01 8a000004 (e5804000)
---[ end trace 46ced8ec429feb82 ]---
Kernel panic - not syncing: Attempted to kill the idle task!

>   	exynos_sysram_init();
>   
>   	exynos_set_delayed_reset_assertion(true);

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-03-31  8:09             ` Arnd Bergmann
@ 2017-04-03  9:21               ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:21 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas, Grant Likely, Rob Herring,
	Linus Walleij



On Friday 31 March 2017 01:39 PM, Arnd Bergmann wrote:
> On Fri, Mar 31, 2017 at 7:36 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>> Hi Arnd,
>>
>> On Thursday 30 March 2017 07:20 PM, Arnd Bergmann wrote:
>>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>>
>>>> +config EXYNOS_CHIPID
>>>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>>>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>>>> +       select SOC_BUS
>>>
>>> This lets you disable the driver when COMPILE_TEST is set on exynos,
>>> which is probably not what you wanted.
>>>
>>
>> Sorry I could not get this point. EXYNOS_CHIPID is invisible menu
>> option, when I enabled COMPILE_TEST, option is visible in make
>> menuconfig but it does not allow to disable this driver. I have adopted
>> this config same as EXYNOS_PMU in the same file.
> 
> I wrote my comment before I saw the 'select' statement in the later
> patch. With that select, it is not a problem.
> 
>>>          bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
>>>          default ARCH_EXYNOS
>>
>> I can adopt, default ARCH_EXYNOS, which will allow me to drop patch 5/12
>> and 6/12.
> 
> Either way (select or default) is fine, just do the same thing for both chipid
> and pmu. If you keep the 'select' and the 'if COMPILE_TEST', you can
> drop the line 'depends on ARCH_EXYNOS || COMPILE_TEST'.
> 

OK, I understood your point. Thanks.

Pankaj Dubey

>       Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-04-03  9:21               ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:21 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 31 March 2017 01:39 PM, Arnd Bergmann wrote:
> On Fri, Mar 31, 2017 at 7:36 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>> Hi Arnd,
>>
>> On Thursday 30 March 2017 07:20 PM, Arnd Bergmann wrote:
>>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>>
>>>> +config EXYNOS_CHIPID
>>>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>>>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>>>> +       select SOC_BUS
>>>
>>> This lets you disable the driver when COMPILE_TEST is set on exynos,
>>> which is probably not what you wanted.
>>>
>>
>> Sorry I could not get this point. EXYNOS_CHIPID is invisible menu
>> option, when I enabled COMPILE_TEST, option is visible in make
>> menuconfig but it does not allow to disable this driver. I have adopted
>> this config same as EXYNOS_PMU in the same file.
> 
> I wrote my comment before I saw the 'select' statement in the later
> patch. With that select, it is not a problem.
> 
>>>          bool "Exynos Chipid controller driver" if COMPILE_TEST && !ARCHEXYNOS
>>>          default ARCH_EXYNOS
>>
>> I can adopt, default ARCH_EXYNOS, which will allow me to drop patch 5/12
>> and 6/12.
> 
> Either way (select or default) is fine, just do the same thing for both chipid
> and pmu. If you keep the 'select' and the 'if COMPILE_TEST', you can
> drop the line 'depends on ARCH_EXYNOS || COMPILE_TEST'.
> 

OK, I understood your point. Thanks.

Pankaj Dubey

>       Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
  2017-03-31  8:22             ` Arnd Bergmann
@ 2017-04-03  9:25               ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:25 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-samsung-soc, Linux ARM, Krzysztof Kozlowski,
	Marek Szyprowski, Kukjin Kim, m.reichl, a.hajda, cwchoi00,
	Javier Martinez Canillas



On Friday 31 March 2017 01:52 PM, Arnd Bergmann wrote:
> On Fri, Mar 31, 2017 at 8:01 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>> On Thursday 30 March 2017 07:31 PM, Arnd Bergmann wrote:
>>> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>
>>> This seems really overcomplicated. From what I can tell, this is only needed
>>> to find the SCU address, but there are better ways to do that, either by
>>> looking up the SCU in the DT at the time you actually need it,
>>> or by calling scu_a9_get_base().
>>
>> Indeed it's complicated and ugly, for the same reason I attempted to
>> clean-up this part for Exynos SoC in patch series [1], which was
>> accepted by Samsung maintainer Krzysztof and later during pull request
>> rejected by ARM maintainers [2]
>>
>> [1]: https://www.spinics.net/lists/arm-kernel/msg540498.html
>> [2]: http://lkml.iu.edu/hypermail/linux/kernel/1612.0/01508.html
>>
>> Given the argument we can't adopt getting base address of SCU completely
>> via DT without breaking OLD dtbs at some point, difficult to simplify
>> these stuffs.
>>
>> Please guide which is the best way to handle such stuffs.
>>
>> In fact I made another attempt [3] to cleanup this SCU related stuffs
>> for other ARM based platforms, but we could not arrive on some consensus
>> at that time. I will try to attempt it again soon.
>>
>> [3]: http://www.spinics.net/lists/arm-kernel/msg542351.html
> 
> I very much appreciate your attempts, this is very helpful. I'm sorry
> for making it so hard for you. I had remembered your previous series,
> but did not realize that you were the author of both this patch and
> the SCU cleanup.
> 
> Let me try to understand the entire problem space better. These
> are my assumptions based on what  you write:
> 
> - A clean solution would be to map the SCU based on the DT as
>   you implemented in the earlier patch series, but that breaks
>   running new kernels with old DTBs, which we don't want.
> 
> - Another clean solution would be to map the SCU based on
>   scu_a9_get_base(), but that doesn't work on all variants of
>   exynos4, because there is at least one (which?) that has incorrect
>   data in the register

Sorry, I am also not aware which variant does not support this.
Currently for none of exynos4 we are using scu_a9_get_base(), and due to
unavailability of all exynos4 based board with me, I can't test it.

> 
> - The approach in this patch works, but is really ugly as it
>   requires parsing the fdt.
> 
> Assuming that we don't want any of the approaches above,
> here are some other ideas that might be a little better:
> 
> - Map the SCU later, just before we first need for calling
>   scu_enable(): exynos_smp_prepare_cpus(),
>   exynos_enter_aftr() or exynos_pm_resume(). All three
>   are late enough that we can simply call ioremap()
>   on the known physical address for the first caller,
>   and they are all guarded by a
>   ARM_CPU_PART_CORTEX_A9 check that should
>   be equivalent to the EXYNOS4 check you have.
> 

OK, let me try this, I think I can shift it at a little later point of boot.

> - Split the exynos4 machine descriptor from the one
>   for exynos5, and exynos3, the call the iotable_init
>   unconditionally for exynos4. The same method would
>   also let us get rid of some of the other
>   of_machine_is_compatible() checks.
> 

Once we move SCU mapping to later point of time, iotable_init can be
dropped. Currently only for SCU mapping it is getting called. So this
part will become more clean.


Thanks for suggestion. I will work on it and submit next version.

Pankaj Dubey

>        Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information
@ 2017-04-03  9:25               ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:25 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 31 March 2017 01:52 PM, Arnd Bergmann wrote:
> On Fri, Mar 31, 2017 at 8:01 AM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>> On Thursday 30 March 2017 07:31 PM, Arnd Bergmann wrote:
>>> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>
>>> This seems really overcomplicated. From what I can tell, this is only needed
>>> to find the SCU address, but there are better ways to do that, either by
>>> looking up the SCU in the DT at the time you actually need it,
>>> or by calling scu_a9_get_base().
>>
>> Indeed it's complicated and ugly, for the same reason I attempted to
>> clean-up this part for Exynos SoC in patch series [1], which was
>> accepted by Samsung maintainer Krzysztof and later during pull request
>> rejected by ARM maintainers [2]
>>
>> [1]: https://www.spinics.net/lists/arm-kernel/msg540498.html
>> [2]: http://lkml.iu.edu/hypermail/linux/kernel/1612.0/01508.html
>>
>> Given the argument we can't adopt getting base address of SCU completely
>> via DT without breaking OLD dtbs at some point, difficult to simplify
>> these stuffs.
>>
>> Please guide which is the best way to handle such stuffs.
>>
>> In fact I made another attempt [3] to cleanup this SCU related stuffs
>> for other ARM based platforms, but we could not arrive on some consensus
>> at that time. I will try to attempt it again soon.
>>
>> [3]: http://www.spinics.net/lists/arm-kernel/msg542351.html
> 
> I very much appreciate your attempts, this is very helpful. I'm sorry
> for making it so hard for you. I had remembered your previous series,
> but did not realize that you were the author of both this patch and
> the SCU cleanup.
> 
> Let me try to understand the entire problem space better. These
> are my assumptions based on what  you write:
> 
> - A clean solution would be to map the SCU based on the DT as
>   you implemented in the earlier patch series, but that breaks
>   running new kernels with old DTBs, which we don't want.
> 
> - Another clean solution would be to map the SCU based on
>   scu_a9_get_base(), but that doesn't work on all variants of
>   exynos4, because there is at least one (which?) that has incorrect
>   data in the register

Sorry, I am also not aware which variant does not support this.
Currently for none of exynos4 we are using scu_a9_get_base(), and due to
unavailability of all exynos4 based board with me, I can't test it.

> 
> - The approach in this patch works, but is really ugly as it
>   requires parsing the fdt.
> 
> Assuming that we don't want any of the approaches above,
> here are some other ideas that might be a little better:
> 
> - Map the SCU later, just before we first need for calling
>   scu_enable(): exynos_smp_prepare_cpus(),
>   exynos_enter_aftr() or exynos_pm_resume(). All three
>   are late enough that we can simply call ioremap()
>   on the known physical address for the first caller,
>   and they are all guarded by a
>   ARM_CPU_PART_CORTEX_A9 check that should
>   be equivalent to the EXYNOS4 check you have.
> 

OK, let me try this, I think I can shift it at a little later point of boot.

> - Split the exynos4 machine descriptor from the one
>   for exynos5, and exynos3, the call the iotable_init
>   unconditionally for exynos4. The same method would
>   also let us get rid of some of the other
>   of_machine_is_compatible() checks.
> 

Once we move SCU mapping to later point of time, iotable_init can be
dropped. Currently only for SCU mapping it is getting called. So this
part will become more clean.


Thanks for suggestion. I will work on it and submit next version.

Pankaj Dubey

>        Arnd
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-04-03  7:57         ` Marek Szyprowski
@ 2017-04-03  9:35           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:35 UTC (permalink / raw)
  To: Marek Szyprowski, linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, kgene, m.reichl, a.hajda, cwchoi00, javier,
	Grant Likely, Rob Herring, Linus Walleij

Hi Marek,

On Monday 03 April 2017 01:27 PM, Marek Szyprowski wrote:
> Hi Pankaj
> 
> On 2017-03-30 15:16, Pankaj Dubey wrote:
>> Exynos SoCs have Chipid, for identification of product IDs and SoC
>> revisions. This patch intends to provide initialization code for all
>> these functionalities, at the same time it provides some sysfs entries
>> for accessing these information to user-space.
>>
>> This driver uses existing binding for exynos-chipid.

snip

>> +
>> +static const struct exynos_soc_id {
>> +    const char *name;
>> +    unsigned int id;
>> +    unsigned int mask;
>> +} soc_ids[] = {
>> +    { "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
>> +    { "EXYNOS4210", 0x43210000, 0xFFFFF000 },
> 
> You have once again changed the mask for Exynos4 SoCs, so please add
> following line to the above array:

Yes, this time I cross-verified from the UM of respective SoC's and
added it.

> 
> { "EXYNOS4210", 0x43200000, 0xFFFFF000 },       /* EVT0 revision */
> 
> Otherwise Exynos C210 (4210 EVT0) is not properly detected:
> 
> soc soc0: Exynos: CPU[UNKNOWN] PRO_ID[0x43200200] REV[0x0] Detected

Thanks for testing, I will add support for this.

> 
>> +    { "EXYNOS4212", 0x43220000, 0xFFFFF000 },
>> +    { "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
>> +    { "EXYNOS5250", 0x43520000, 0xFFFFF000 },
>> +    { "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
>> +    { "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
>> +    { "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
>> +    { "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
>> +    { "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
>> +    { "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
>> +    { "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
>> +};
> 
> Now the mask is same for all revisions, so you can remove it from the above
> array and directly use some kind of define in the code.

Yes, I also observed, but somehow I missed to update this part. I will
change this in next version.

> 
>> +
>> +static const char * __init product_id_to_soc_id(unsigned int product_id)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
>> +        if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
>> +            return soc_ids[i].name;
>> +    return "UNKNOWN";
>> +}
>> +
>> +int __init exynos_chipid_early_init(void)
>> +{
>> +    struct soc_device_attribute *soc_dev_attr;
>> +    void __iomem *exynos_chipid_base;
>> +    struct soc_device *soc_dev;
>> +    struct device_node *root;
>> +    struct device_node *np;
>> +    struct device *dev;
>> +    u32 product_id;
>> +    u32 revision;
>> +
>> +    /* look up for chipid node */
>> +    np = of_find_compatible_node(NULL, NULL,
>> "samsung,exynos4210-chipid");
>> +    if (!np)
>> +        return -ENODEV;
>> +
>> +    exynos_chipid_base = of_iomap(np, 0);
>> +    of_node_put(np);
>> +
>> +    if (!exynos_chipid_base) {
>> +        pr_err("%s: failed to map chipid\n", np->name);
>> +        return -ENOMEM;
>> +    }
>> +
>> +    product_id = readl_relaxed(exynos_chipid_base);
>> +    revision = product_id & EXYNOS_REV_MASK;
>> +    iounmap(exynos_chipid_base);
>> +
>> +    soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
>> +    if (!soc_dev_attr)
>> +        return -ENODEV;
>> +
>> +    soc_dev_attr->family = "Samsung Exynos";
>> +
>> +    root = of_find_node_by_path("/");
>> +    of_property_read_string(root, "model", &soc_dev_attr->machine);
>> +    of_node_put(root);
>> +
>> +    soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
>> +    soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
>> +
>> +    soc_dev = soc_device_register(soc_dev_attr);
>> +    if (IS_ERR(soc_dev)) {
>> +        kfree(soc_dev_attr->revision);
>> +        kfree_const(soc_dev_attr->soc_id);
>> +        kfree(soc_dev_attr);
>> +        return PTR_ERR(soc_dev);
>> +    }
>> +    dev = soc_device_to_device(soc_dev);
>> +
>> +    dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
>> +            soc_dev_attr->soc_id, product_id, revision);
>> +
>> +    return 0;
>> +}
>> +early_initcall(exynos_chipid_early_init);
> 
> Best regards


Thanks,
Pankaj Dubey

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-04-03  9:35           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Monday 03 April 2017 01:27 PM, Marek Szyprowski wrote:
> Hi Pankaj
> 
> On 2017-03-30 15:16, Pankaj Dubey wrote:
>> Exynos SoCs have Chipid, for identification of product IDs and SoC
>> revisions. This patch intends to provide initialization code for all
>> these functionalities, at the same time it provides some sysfs entries
>> for accessing these information to user-space.
>>
>> This driver uses existing binding for exynos-chipid.

snip

>> +
>> +static const struct exynos_soc_id {
>> +    const char *name;
>> +    unsigned int id;
>> +    unsigned int mask;
>> +} soc_ids[] = {
>> +    { "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
>> +    { "EXYNOS4210", 0x43210000, 0xFFFFF000 },
> 
> You have once again changed the mask for Exynos4 SoCs, so please add
> following line to the above array:

Yes, this time I cross-verified from the UM of respective SoC's and
added it.

> 
> { "EXYNOS4210", 0x43200000, 0xFFFFF000 },       /* EVT0 revision */
> 
> Otherwise Exynos C210 (4210 EVT0) is not properly detected:
> 
> soc soc0: Exynos: CPU[UNKNOWN] PRO_ID[0x43200200] REV[0x0] Detected

Thanks for testing, I will add support for this.

> 
>> +    { "EXYNOS4212", 0x43220000, 0xFFFFF000 },
>> +    { "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
>> +    { "EXYNOS5250", 0x43520000, 0xFFFFF000 },
>> +    { "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
>> +    { "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
>> +    { "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
>> +    { "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
>> +    { "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
>> +    { "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
>> +    { "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
>> +};
> 
> Now the mask is same for all revisions, so you can remove it from the above
> array and directly use some kind of define in the code.

Yes, I also observed, but somehow I missed to update this part. I will
change this in next version.

> 
>> +
>> +static const char * __init product_id_to_soc_id(unsigned int product_id)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
>> +        if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
>> +            return soc_ids[i].name;
>> +    return "UNKNOWN";
>> +}
>> +
>> +int __init exynos_chipid_early_init(void)
>> +{
>> +    struct soc_device_attribute *soc_dev_attr;
>> +    void __iomem *exynos_chipid_base;
>> +    struct soc_device *soc_dev;
>> +    struct device_node *root;
>> +    struct device_node *np;
>> +    struct device *dev;
>> +    u32 product_id;
>> +    u32 revision;
>> +
>> +    /* look up for chipid node */
>> +    np = of_find_compatible_node(NULL, NULL,
>> "samsung,exynos4210-chipid");
>> +    if (!np)
>> +        return -ENODEV;
>> +
>> +    exynos_chipid_base = of_iomap(np, 0);
>> +    of_node_put(np);
>> +
>> +    if (!exynos_chipid_base) {
>> +        pr_err("%s: failed to map chipid\n", np->name);
>> +        return -ENOMEM;
>> +    }
>> +
>> +    product_id = readl_relaxed(exynos_chipid_base);
>> +    revision = product_id & EXYNOS_REV_MASK;
>> +    iounmap(exynos_chipid_base);
>> +
>> +    soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
>> +    if (!soc_dev_attr)
>> +        return -ENODEV;
>> +
>> +    soc_dev_attr->family = "Samsung Exynos";
>> +
>> +    root = of_find_node_by_path("/");
>> +    of_property_read_string(root, "model", &soc_dev_attr->machine);
>> +    of_node_put(root);
>> +
>> +    soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
>> +    soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
>> +
>> +    soc_dev = soc_device_register(soc_dev_attr);
>> +    if (IS_ERR(soc_dev)) {
>> +        kfree(soc_dev_attr->revision);
>> +        kfree_const(soc_dev_attr->soc_id);
>> +        kfree(soc_dev_attr);
>> +        return PTR_ERR(soc_dev);
>> +    }
>> +    dev = soc_device_to_device(soc_dev);
>> +
>> +    dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
>> +            soc_dev_attr->soc_id, product_id, revision);
>> +
>> +    return 0;
>> +}
>> +early_initcall(exynos_chipid_early_init);
> 
> Best regards


Thanks,
Pankaj Dubey

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
  2017-04-03  7:57         ` Marek Szyprowski
@ 2017-04-03  9:54           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:54 UTC (permalink / raw)
  To: Marek Szyprowski, linux-samsung-soc, linux-arm-kernel
  Cc: krzk, arnd, kgene, m.reichl, a.hajda, cwchoi00, javier

Hi Marek,

On Monday 03 April 2017 01:27 PM, Marek Szyprowski wrote:
> Hi Pankaj,
> 
> On 2017-03-30 15:17, Pankaj Dubey wrote:
>> Various Exynos SoC has different CPU related information, such as CPU
>> boot register, programming sequence making CPU up/down. Currently this
>> is handled by adding lots of soc_is_exynosMMM checks in the code, in
>> an attempt to remove the dependency of such helper functions specific to
>> each SoC, let's separate this information pertaining to CPU by
>> introducing
>> a new "struct exynos_cpu_info". This struct will contain differences
>> associated with CPU on various Exynos SoC. This can be matched by using
>> generic API "soc_device_match".
>>

>> +
>> +static const struct of_device_id exynos_pmu_of_device_ids[]
>> __initconst = {
> 
> exynos_pmuc_of_device_ids is a bit too easy to confuse with
> drivers/soc/samsung/exynos_*pmu.c drivers and its device tree nodes.
> IMHO exynos_soc_of_device_ids is a bit more appropriate here.
> 

Yes you are right, I will update this name.

>> +    {
>> +        .compatible = "samsung,exynos3250",
>> +        .data = &exynos3250_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos4212",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos4412",
>> +        .data = &exynos4412_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5250",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5260",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5410",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5420",
>> +        .data = &exynos5420_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5440",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5800",
>> +        .data = &exynos5420_cpu_info
>> +    },
>> +    { /*sentinel*/ },
>> +};
>> +
>>   static int exynos_boot_secondary(unsigned int cpu, struct
>> task_struct *idle)
>>   {
>>       unsigned long timeout;
>> +    const struct soc_device_attribute *match;
>>       u32 mpidr = cpu_logical_map(cpu);
>>       u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>>       int ret = -ENOSYS;
>>   +    if (of_machine_is_compatible("samsung,exynos4210")) {
>> +        match = soc_device_match(exynos_soc_revision);
>> +        if (match)
>> +            cpu_info = (const struct exynos_cpu_info *) match->data;
>> +    }
>> +
>>       /*
>>        * Set synchronisation state between this boot processor
>>        * and the secondary one
>> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int
>> cpu, struct task_struct *idle)
>>     static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>>   {
>> +    const struct of_device_id *match;
>> +    struct device_node *np;
>> +
>> +    if (!of_machine_is_compatible("samsung,exynos4210")) {
>> +        np = of_find_matching_node_and_match(NULL,
>> +                exynos_pmu_of_device_ids, &match);
>> +        if (!np)
>> +            pr_err("failed to find supported CPU\n");
>> +        else
>> +            cpu_info = (const struct exynos_cpu_info *) match->data;
>> +    }
>> +
> 
> This approach nukes on Exynos4210 booted with maxcpus=1, because
> exynos_boot_secondary()
> is not called in such case:

argh :(

If you see I have handled Exynos4210 case in a different manner, because
as per code-flow I can see following order of sequence:

1: exynos_smp_prepare_cpus
2: exynos_chipid_early_init
3: exynos_boot_secondary

We can't handle differentiation of Exynos4210 case in smp_prepare_cpus
only based on compatible property of root node, as it has different
revision boards and chipid is not getting initialized before
smp_prepare_cpus, even though I have marked it as early_initcall, I am
not sure how I can make chipid initialization much early than this? Any
idea?

So I decided to handle it in exynos_boot_secondary and populate its
cpu_info based on match found via "soc_device_match" API.

But as you tested and mentioned exynos_boot_secondary will not be called
if nr_cpus is capped to 1 and this will lead to crash, I missed this point.

I feel I am forced to add such work-around as there is need of some I/Ps
such as chipid to be probed or initialized at very early stage, but
currently I am not seeing any such initcall or feature (early probe or
something similar) exist to make this work

Let me think again how we can make it work.. any suggestion will be
helpful for me :)

Thanks,
Pankaj Dubey


> 
> Unable to handle kernel NULL pointer dereference at virtual address
> 00000000
> pgd = c0004000
> [00000000] *pgd=00000000
> Internal error: Oops: 805 [#1] PREEMPT SMP ARM
> Modules linked in:
> CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> 4.11.0-rc5-00013-g7aa5680b6c53-dirty #1185
> Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
> task: c0b08640 task.stack: c0b00000
> PC is at exynos_set_boot_addr+0x64/0x84
> LR is at exynos_enter_coupled_lowpower+0x1c/0x74
> pc : [<c0117890>]    lr : [<c052f654>]    psr: 60000093
> sp : c0b01f00  ip : 02800000  fp : c0b2f7e4
> r10: c0b86e44  r9 : 00000001  r8 : dbb97e10
> r7 : 00000001  r6 : dbb97e10  r5 : 00000001  r4 : 40116c50
> r3 : 00000000  r2 : 00000001  r1 : 40116c50  r0 : 00000000
> Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 10c5387d  Table: 4000404a  DAC: 00000051
> Process swapper/0 (pid: 0, stack limit = 0xc0b00210)
> Stack: (0xc0b01f00 to 0xc0b02000)
> 1f00: c01165f8 c0b86e4c c0b05508 c052f654 c052f638 c0b2f844 c0b05508
> 90442e5c
> 1f20: 00000000 c052d528 00041fc9 00000000 00000000 00000000 00000001
> 00000001
> 1f40: c0b05508 dbb97e10 c0b2f7e4 dbb97e10 dae522c0 c0b86e44 c0b86e44
> c052f3b0
> 1f60: 00000000 c0b05424 00000001 dae522e8 c0b05424 c0b05480 c0b05424
> c0a66e08
> 1f80: c0b0548c c0b10b0e c0b2f7e4 dbb97e10 00000000 c0152eb0 000000bb
> ffffffff
> 1fa0: c0b47000 c0a34a38 dbfffb40 412fc091 00000001 c01531cc c0b08640
> c0a00c00
> 1fc0: ffffffff ffffffff 00000000 c0a00680 00000000 c0a34a38 00000000
> c0b473d4
> 1fe0: c0b05418 c0a34a34 c0b09870 4000406a 00000000 4000807c 00000000
> 00000000
> [<c0117890>] (exynos_set_boot_addr) from [<c052f654>]
> (exynos_enter_coupled_lowpower+0x1c/0x74)
> [<c052f654>] (exynos_enter_coupled_lowpower) from [<c052d528>]
> (cpuidle_enter_state+0x64/0x264)
> [<c052d528>] (cpuidle_enter_state) from [<c052f3b0>]
> (cpuidle_enter_state_coupled+0x394/0x3e4)
> [<c052f3b0>] (cpuidle_enter_state_coupled) from [<c0152eb0>]
> (do_idle+0x178/0x200)
> [<c0152eb0>] (do_idle) from [<c01531cc>] (cpu_startup_entry+0x18/0x1c)
> [<c01531cc>] (cpu_startup_entry) from [<c0a00c00>]
> (start_kernel+0x330/0x398)
> [<c0a00c00>] (start_kernel) from [<4000807c>] (0x4000807c)
> Code: e1a00005 e12fff33 e3700a01 8a000004 (e5804000)
> ---[ end trace 46ced8ec429feb82 ]---
> Kernel panic - not syncing: Attempted to kill the idle task!
> 
>>       exynos_sysram_init();
>>         exynos_set_delayed_reset_assertion(true);
> 
> Best regards

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-04-03  9:54           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-03  9:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marek,

On Monday 03 April 2017 01:27 PM, Marek Szyprowski wrote:
> Hi Pankaj,
> 
> On 2017-03-30 15:17, Pankaj Dubey wrote:
>> Various Exynos SoC has different CPU related information, such as CPU
>> boot register, programming sequence making CPU up/down. Currently this
>> is handled by adding lots of soc_is_exynosMMM checks in the code, in
>> an attempt to remove the dependency of such helper functions specific to
>> each SoC, let's separate this information pertaining to CPU by
>> introducing
>> a new "struct exynos_cpu_info". This struct will contain differences
>> associated with CPU on various Exynos SoC. This can be matched by using
>> generic API "soc_device_match".
>>

>> +
>> +static const struct of_device_id exynos_pmu_of_device_ids[]
>> __initconst = {
> 
> exynos_pmuc_of_device_ids is a bit too easy to confuse with
> drivers/soc/samsung/exynos_*pmu.c drivers and its device tree nodes.
> IMHO exynos_soc_of_device_ids is a bit more appropriate here.
> 

Yes you are right, I will update this name.

>> +    {
>> +        .compatible = "samsung,exynos3250",
>> +        .data = &exynos3250_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos4212",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos4412",
>> +        .data = &exynos4412_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5250",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5260",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5410",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5420",
>> +        .data = &exynos5420_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5440",
>> +        .data = &exynos_common_cpu_info
>> +    }, {
>> +        .compatible = "samsung,exynos5800",
>> +        .data = &exynos5420_cpu_info
>> +    },
>> +    { /*sentinel*/ },
>> +};
>> +
>>   static int exynos_boot_secondary(unsigned int cpu, struct
>> task_struct *idle)
>>   {
>>       unsigned long timeout;
>> +    const struct soc_device_attribute *match;
>>       u32 mpidr = cpu_logical_map(cpu);
>>       u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>>       int ret = -ENOSYS;
>>   +    if (of_machine_is_compatible("samsung,exynos4210")) {
>> +        match = soc_device_match(exynos_soc_revision);
>> +        if (match)
>> +            cpu_info = (const struct exynos_cpu_info *) match->data;
>> +    }
>> +
>>       /*
>>        * Set synchronisation state between this boot processor
>>        * and the secondary one
>> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int
>> cpu, struct task_struct *idle)
>>     static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>>   {
>> +    const struct of_device_id *match;
>> +    struct device_node *np;
>> +
>> +    if (!of_machine_is_compatible("samsung,exynos4210")) {
>> +        np = of_find_matching_node_and_match(NULL,
>> +                exynos_pmu_of_device_ids, &match);
>> +        if (!np)
>> +            pr_err("failed to find supported CPU\n");
>> +        else
>> +            cpu_info = (const struct exynos_cpu_info *) match->data;
>> +    }
>> +
> 
> This approach nukes on Exynos4210 booted with maxcpus=1, because
> exynos_boot_secondary()
> is not called in such case:

argh :(

If you see I have handled Exynos4210 case in a different manner, because
as per code-flow I can see following order of sequence:

1: exynos_smp_prepare_cpus
2: exynos_chipid_early_init
3: exynos_boot_secondary

We can't handle differentiation of Exynos4210 case in smp_prepare_cpus
only based on compatible property of root node, as it has different
revision boards and chipid is not getting initialized before
smp_prepare_cpus, even though I have marked it as early_initcall, I am
not sure how I can make chipid initialization much early than this? Any
idea?

So I decided to handle it in exynos_boot_secondary and populate its
cpu_info based on match found via "soc_device_match" API.

But as you tested and mentioned exynos_boot_secondary will not be called
if nr_cpus is capped to 1 and this will lead to crash, I missed this point.

I feel I am forced to add such work-around as there is need of some I/Ps
such as chipid to be probed or initialized at very early stage, but
currently I am not seeing any such initcall or feature (early probe or
something similar) exist to make this work

Let me think again how we can make it work.. any suggestion will be
helpful for me :)

Thanks,
Pankaj Dubey


> 
> Unable to handle kernel NULL pointer dereference at virtual address
> 00000000
> pgd = c0004000
> [00000000] *pgd=00000000
> Internal error: Oops: 805 [#1] PREEMPT SMP ARM
> Modules linked in:
> CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> 4.11.0-rc5-00013-g7aa5680b6c53-dirty #1185
> Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
> task: c0b08640 task.stack: c0b00000
> PC is at exynos_set_boot_addr+0x64/0x84
> LR is at exynos_enter_coupled_lowpower+0x1c/0x74
> pc : [<c0117890>]    lr : [<c052f654>]    psr: 60000093
> sp : c0b01f00  ip : 02800000  fp : c0b2f7e4
> r10: c0b86e44  r9 : 00000001  r8 : dbb97e10
> r7 : 00000001  r6 : dbb97e10  r5 : 00000001  r4 : 40116c50
> r3 : 00000000  r2 : 00000001  r1 : 40116c50  r0 : 00000000
> Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 10c5387d  Table: 4000404a  DAC: 00000051
> Process swapper/0 (pid: 0, stack limit = 0xc0b00210)
> Stack: (0xc0b01f00 to 0xc0b02000)
> 1f00: c01165f8 c0b86e4c c0b05508 c052f654 c052f638 c0b2f844 c0b05508
> 90442e5c
> 1f20: 00000000 c052d528 00041fc9 00000000 00000000 00000000 00000001
> 00000001
> 1f40: c0b05508 dbb97e10 c0b2f7e4 dbb97e10 dae522c0 c0b86e44 c0b86e44
> c052f3b0
> 1f60: 00000000 c0b05424 00000001 dae522e8 c0b05424 c0b05480 c0b05424
> c0a66e08
> 1f80: c0b0548c c0b10b0e c0b2f7e4 dbb97e10 00000000 c0152eb0 000000bb
> ffffffff
> 1fa0: c0b47000 c0a34a38 dbfffb40 412fc091 00000001 c01531cc c0b08640
> c0a00c00
> 1fc0: ffffffff ffffffff 00000000 c0a00680 00000000 c0a34a38 00000000
> c0b473d4
> 1fe0: c0b05418 c0a34a34 c0b09870 4000406a 00000000 4000807c 00000000
> 00000000
> [<c0117890>] (exynos_set_boot_addr) from [<c052f654>]
> (exynos_enter_coupled_lowpower+0x1c/0x74)
> [<c052f654>] (exynos_enter_coupled_lowpower) from [<c052d528>]
> (cpuidle_enter_state+0x64/0x264)
> [<c052d528>] (cpuidle_enter_state) from [<c052f3b0>]
> (cpuidle_enter_state_coupled+0x394/0x3e4)
> [<c052f3b0>] (cpuidle_enter_state_coupled) from [<c0152eb0>]
> (do_idle+0x178/0x200)
> [<c0152eb0>] (do_idle) from [<c01531cc>] (cpu_startup_entry+0x18/0x1c)
> [<c01531cc>] (cpu_startup_entry) from [<c0a00c00>]
> (start_kernel+0x330/0x398)
> [<c0a00c00>] (start_kernel) from [<4000807c>] (0x4000807c)
> Code: e1a00005 e12fff33 e3700a01 8a000004 (e5804000)
> ---[ end trace 46ced8ec429feb82 ]---
> Kernel panic - not syncing: Attempted to kill the idle task!
> 
>>       exynos_sysram_init();
>>         exynos_set_delayed_reset_assertion(true);
> 
> Best regards

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines
  2017-03-30 13:16       ` Pankaj Dubey
@ 2017-04-07  7:45         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  7:45 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> To remove dependency on soc_is_exynosMMMM macros and remove multiple
> checks for such macros, let's refactor code in firmware.c file.
> SoC specific firmware_ops are separated and registered during
> exynos_firmware_init based on matching machine compatible.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/firmware.c | 114 +++++++++++++++++++++++++++++++---------
>  1 file changed, 89 insertions(+), 25 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
> index e81a78b..b04c47a 100644
> --- a/arch/arm/mach-exynos/firmware.c
> +++ b/arch/arm/mach-exynos/firmware.c
> @@ -35,6 +35,25 @@ static void exynos_save_cp15(void)
>              : : "cc");
>  }
>
> +static int exynos3250_do_idle(unsigned long mode)
> +{
> +       switch (mode) {
> +       case FW_DO_IDLE_AFTR:
> +               writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
> +                              sysram_ns_base_addr + 0x24);
> +               writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
> +               flush_cache_all();
> +               exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
> +                               SMC_POWERSTATE_IDLE, 0);
> +               exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
> +                               SMC_POWERSTATE_IDLE, 0);
> +               break;
> +       case FW_DO_IDLE_SLEEP:
> +               exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
> +       }
> +       return 0;
> +}
> +
>  static int exynos_do_idle(unsigned long mode)
>  {
>         switch (mode) {
> @@ -44,14 +63,7 @@ static int exynos_do_idle(unsigned long mode)
>                 writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
>                                sysram_ns_base_addr + 0x24);
>                 writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
> -               if (soc_is_exynos3250()) {
> -                       flush_cache_all();
> -                       exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
> -                                  SMC_POWERSTATE_IDLE, 0);
> -                       exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
> -                                  SMC_POWERSTATE_IDLE, 0);
> -               } else
> -                       exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
> +               exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
>                 break;
>         case FW_DO_IDLE_SLEEP:
>                 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
> @@ -59,28 +71,25 @@ static int exynos_do_idle(unsigned long mode)
>         return 0;
>  }
>
> -static int exynos_cpu_boot(int cpu)
> +static int exynos4212_cpu_boot(int cpu)
>  {
>         /*
> -        * Exynos3250 doesn't need to send smc command for secondary CPU boot
> -        * because Exynos3250 removes WFE in secure mode.
> -        */
> -       if (soc_is_exynos3250())
> -               return 0;
> -
> -       /*
>          * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
>          * But, Exynos4212 has only one secondary CPU so second parameter
>          * isn't used for informing secure firmware about CPU id.
>          */
> -       if (soc_is_exynos4212())
> -               cpu = 0;
> +       cpu = 0;

The comment above is clear enough so I think there is no need for this
assignment. Just use 0 as argument in exynos_smc().

Rest looks good so with this change:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines
@ 2017-04-07  7:45         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  7:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> To remove dependency on soc_is_exynosMMMM macros and remove multiple
> checks for such macros, let's refactor code in firmware.c file.
> SoC specific firmware_ops are separated and registered during
> exynos_firmware_init based on matching machine compatible.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/firmware.c | 114 +++++++++++++++++++++++++++++++---------
>  1 file changed, 89 insertions(+), 25 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
> index e81a78b..b04c47a 100644
> --- a/arch/arm/mach-exynos/firmware.c
> +++ b/arch/arm/mach-exynos/firmware.c
> @@ -35,6 +35,25 @@ static void exynos_save_cp15(void)
>              : : "cc");
>  }
>
> +static int exynos3250_do_idle(unsigned long mode)
> +{
> +       switch (mode) {
> +       case FW_DO_IDLE_AFTR:
> +               writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
> +                              sysram_ns_base_addr + 0x24);
> +               writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
> +               flush_cache_all();
> +               exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
> +                               SMC_POWERSTATE_IDLE, 0);
> +               exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
> +                               SMC_POWERSTATE_IDLE, 0);
> +               break;
> +       case FW_DO_IDLE_SLEEP:
> +               exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
> +       }
> +       return 0;
> +}
> +
>  static int exynos_do_idle(unsigned long mode)
>  {
>         switch (mode) {
> @@ -44,14 +63,7 @@ static int exynos_do_idle(unsigned long mode)
>                 writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
>                                sysram_ns_base_addr + 0x24);
>                 writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
> -               if (soc_is_exynos3250()) {
> -                       flush_cache_all();
> -                       exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
> -                                  SMC_POWERSTATE_IDLE, 0);
> -                       exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
> -                                  SMC_POWERSTATE_IDLE, 0);
> -               } else
> -                       exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
> +               exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
>                 break;
>         case FW_DO_IDLE_SLEEP:
>                 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
> @@ -59,28 +71,25 @@ static int exynos_do_idle(unsigned long mode)
>         return 0;
>  }
>
> -static int exynos_cpu_boot(int cpu)
> +static int exynos4212_cpu_boot(int cpu)
>  {
>         /*
> -        * Exynos3250 doesn't need to send smc command for secondary CPU boot
> -        * because Exynos3250 removes WFE in secure mode.
> -        */
> -       if (soc_is_exynos3250())
> -               return 0;
> -
> -       /*
>          * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
>          * But, Exynos4212 has only one secondary CPU so second parameter
>          * isn't used for informing secure firmware about CPU id.
>          */
> -       if (soc_is_exynos4212())
> -               cpu = 0;
> +       cpu = 0;

The comment above is clear enough so I think there is no need for this
assignment. Just use 0 as argument in exynos_smc().

Rest looks good so with this change:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines
  2017-04-07  7:45         ` Krzysztof Kozlowski
@ 2017-04-07  8:06           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07  8:06 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 01:15 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> To remove dependency on soc_is_exynosMMMM macros and remove multiple
>> checks for such macros, let's refactor code in firmware.c file.
>> SoC specific firmware_ops are separated and registered during
>> exynos_firmware_init based on matching machine compatible.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/firmware.c | 114 +++++++++++++++++++++++++++++++---------
>>  1 file changed, 89 insertions(+), 25 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
>> index e81a78b..b04c47a 100644
>> --- a/arch/arm/mach-exynos/firmware.c
>> +++ b/arch/arm/mach-exynos/firmware.c
>> @@ -35,6 +35,25 @@ static void exynos_save_cp15(void)
>>              : : "cc");
>>  }
>>
>> +static int exynos3250_do_idle(unsigned long mode)
>> +{
>> +       switch (mode) {
>> +       case FW_DO_IDLE_AFTR:
>> +               writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
>> +                              sysram_ns_base_addr + 0x24);
>> +               writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
>> +               flush_cache_all();
>> +               exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
>> +                               SMC_POWERSTATE_IDLE, 0);
>> +               exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
>> +                               SMC_POWERSTATE_IDLE, 0);
>> +               break;
>> +       case FW_DO_IDLE_SLEEP:
>> +               exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
>> +       }
>> +       return 0;
>> +}
>> +
>>  static int exynos_do_idle(unsigned long mode)
>>  {
>>         switch (mode) {
>> @@ -44,14 +63,7 @@ static int exynos_do_idle(unsigned long mode)
>>                 writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
>>                                sysram_ns_base_addr + 0x24);
>>                 writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
>> -               if (soc_is_exynos3250()) {
>> -                       flush_cache_all();
>> -                       exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
>> -                                  SMC_POWERSTATE_IDLE, 0);
>> -                       exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
>> -                                  SMC_POWERSTATE_IDLE, 0);
>> -               } else
>> -                       exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
>> +               exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
>>                 break;
>>         case FW_DO_IDLE_SLEEP:
>>                 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
>> @@ -59,28 +71,25 @@ static int exynos_do_idle(unsigned long mode)
>>         return 0;
>>  }
>>
>> -static int exynos_cpu_boot(int cpu)
>> +static int exynos4212_cpu_boot(int cpu)
>>  {
>>         /*
>> -        * Exynos3250 doesn't need to send smc command for secondary CPU boot
>> -        * because Exynos3250 removes WFE in secure mode.
>> -        */
>> -       if (soc_is_exynos3250())
>> -               return 0;
>> -
>> -       /*
>>          * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
>>          * But, Exynos4212 has only one secondary CPU so second parameter
>>          * isn't used for informing secure firmware about CPU id.
>>          */
>> -       if (soc_is_exynos4212())
>> -               cpu = 0;
>> +       cpu = 0;
> 
> The comment above is clear enough so I think there is no need for this
> assignment. Just use 0 as argument in exynos_smc().
> 

Ok, will modify accordingly in next patchset.

> Rest looks good so with this change:
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> 

Thanks for review,
Pankaj Dubey

> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines
@ 2017-04-07  8:06           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07  8:06 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 01:15 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> To remove dependency on soc_is_exynosMMMM macros and remove multiple
>> checks for such macros, let's refactor code in firmware.c file.
>> SoC specific firmware_ops are separated and registered during
>> exynos_firmware_init based on matching machine compatible.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/firmware.c | 114 +++++++++++++++++++++++++++++++---------
>>  1 file changed, 89 insertions(+), 25 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
>> index e81a78b..b04c47a 100644
>> --- a/arch/arm/mach-exynos/firmware.c
>> +++ b/arch/arm/mach-exynos/firmware.c
>> @@ -35,6 +35,25 @@ static void exynos_save_cp15(void)
>>              : : "cc");
>>  }
>>
>> +static int exynos3250_do_idle(unsigned long mode)
>> +{
>> +       switch (mode) {
>> +       case FW_DO_IDLE_AFTR:
>> +               writel_relaxed(virt_to_phys(exynos_cpu_resume_ns),
>> +                              sysram_ns_base_addr + 0x24);
>> +               writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
>> +               flush_cache_all();
>> +               exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
>> +                               SMC_POWERSTATE_IDLE, 0);
>> +               exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
>> +                               SMC_POWERSTATE_IDLE, 0);
>> +               break;
>> +       case FW_DO_IDLE_SLEEP:
>> +               exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
>> +       }
>> +       return 0;
>> +}
>> +
>>  static int exynos_do_idle(unsigned long mode)
>>  {
>>         switch (mode) {
>> @@ -44,14 +63,7 @@ static int exynos_do_idle(unsigned long mode)
>>                 writel_relaxed(__pa_symbol(exynos_cpu_resume_ns),
>>                                sysram_ns_base_addr + 0x24);
>>                 writel_relaxed(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
>> -               if (soc_is_exynos3250()) {
>> -                       flush_cache_all();
>> -                       exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
>> -                                  SMC_POWERSTATE_IDLE, 0);
>> -                       exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
>> -                                  SMC_POWERSTATE_IDLE, 0);
>> -               } else
>> -                       exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
>> +               exynos_smc(SMC_CMD_CPU0AFTR, 0, 0, 0);
>>                 break;
>>         case FW_DO_IDLE_SLEEP:
>>                 exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
>> @@ -59,28 +71,25 @@ static int exynos_do_idle(unsigned long mode)
>>         return 0;
>>  }
>>
>> -static int exynos_cpu_boot(int cpu)
>> +static int exynos4212_cpu_boot(int cpu)
>>  {
>>         /*
>> -        * Exynos3250 doesn't need to send smc command for secondary CPU boot
>> -        * because Exynos3250 removes WFE in secure mode.
>> -        */
>> -       if (soc_is_exynos3250())
>> -               return 0;
>> -
>> -       /*
>>          * The second parameter of SMC_CMD_CPU1BOOT command means CPU id.
>>          * But, Exynos4212 has only one secondary CPU so second parameter
>>          * isn't used for informing secure firmware about CPU id.
>>          */
>> -       if (soc_is_exynos4212())
>> -               cpu = 0;
>> +       cpu = 0;
> 
> The comment above is clear enough so I think there is no need for this
> assignment. Just use 0 as argument in exynos_smc().
> 

Ok, will modify accordingly in next patchset.

> Rest looks good so with this change:
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> 

Thanks for review,
Pankaj Dubey

> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
  2017-03-30 13:16       ` Pankaj Dubey
@ 2017-04-07  8:24         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  8:24 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
> driver, so let's remove/minimize usage of any such helper function usage
> from pm.c.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>  2 files changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index 1a7e5b5..4a73b02 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>  }
>
>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
> -static void exynos_set_wakeupmask(long mask)
> +static void exynos_set_wakeupmask(void)
>  {
> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
> -       if (soc_is_exynos3250())
> +       if (of_machine_is_compatible("samsung,exynos3250")) {
> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
> +       } else
> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);

You need {} around this too. Checkpatch should complain about it as
well so be sure to run it.

Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
@ 2017-04-07  8:24         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  8:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
> driver, so let's remove/minimize usage of any such helper function usage
> from pm.c.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>  2 files changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index 1a7e5b5..4a73b02 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>  }
>
>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
> -static void exynos_set_wakeupmask(long mask)
> +static void exynos_set_wakeupmask(void)
>  {
> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
> -       if (soc_is_exynos3250())
> +       if (of_machine_is_compatible("samsung,exynos3250")) {
> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
> +       } else
> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);

You need {} around this too. Checkpatch should complain about it as
well so be sure to run it.

Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus
  2017-03-30 13:16       ` Pankaj Dubey
@ 2017-04-07  8:31         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  8:31 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> We are taking care of setting secondary cpu boot address in
> exynos_boot_secondary just before sending ipi to secondary CPUs,
> so we can safely remove this setting from smp_prepare_cpus.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 26 --------------------------
>  1 file changed, 26 deletions(-)
>

I also wondered why we need this twice... Testing on different
platforms would be nice to be sure that we did not miss anything but
it looks correct for me. For my reference:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus
@ 2017-04-07  8:31         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  8:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> We are taking care of setting secondary cpu boot address in
> exynos_boot_secondary just before sending ipi to secondary CPUs,
> so we can safely remove this setting from smp_prepare_cpus.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 26 --------------------------
>  1 file changed, 26 deletions(-)
>

I also wondered why we need this twice... Testing on different
platforms would be nice to be sure that we did not miss anything but
it looks correct for me. For my reference:
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-03-30 13:16       ` Pankaj Dubey
@ 2017-04-07  9:13         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  9:13 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas,
	Grant Likely, Rob Herring, Linus Walleij

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Exynos SoCs have Chipid, for identification of product IDs and SoC
> revisions. This patch intends to provide initialization code for all
> these functionalities, at the same time it provides some sysfs entries
> for accessing these information to user-space.
>
> This driver uses existing binding for exynos-chipid.
>
> CC: Grant Likely <grant.likely@linaro.org>
> CC: Rob Herring <robh+dt@kernel.org>
> CC: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/soc/samsung/Kconfig         |   5 ++
>  drivers/soc/samsung/Makefile        |   1 +
>  drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 115 insertions(+)
>  create mode 100644 drivers/soc/samsung/exynos-chipid.c
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 8b25bd5..a90a4ad 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
>
>  if SOC_SAMSUNG
>
> +config EXYNOS_CHIPID
> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || COMPILE_TEST
> +       select SOC_BUS
> +
>  config EXYNOS_PMU
>         bool "Exynos PMU controller driver" if COMPILE_TEST
>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 4d7694a..be3b6bb 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
>  obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
>
>  obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> new file mode 100644
> index 0000000..1e9fb6b
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + *
> + * EXYNOS - CHIP ID support
> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +
> +#define EXYNOS_SUBREV_MASK     (0xF << 4)
> +#define EXYNOS_MAINREV_MASK    (0xF << 0)
> +#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
> +
> +static const struct exynos_soc_id {
> +       const char *name;
> +       unsigned int id;
> +       unsigned int mask;
> +} soc_ids[] = {
> +       { "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
> +       { "EXYNOS4210", 0x43210000, 0xFFFFF000 },
> +       { "EXYNOS4212", 0x43220000, 0xFFFFF000 },
> +       { "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
> +       { "EXYNOS5250", 0x43520000, 0xFFFFF000 },
> +       { "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
> +       { "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
> +       { "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
> +       { "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
> +       { "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
> +       { "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
> +       { "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
> +};
> +
> +static const char * __init product_id_to_soc_id(unsigned int product_id)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
> +               if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
> +                       return soc_ids[i].name;
> +       return "UNKNOWN";
> +}
> +
> +int __init exynos_chipid_early_init(void)
> +{
> +       struct soc_device_attribute *soc_dev_attr;
> +       void __iomem *exynos_chipid_base;
> +       struct soc_device *soc_dev;
> +       struct device_node *root;
> +       struct device_node *np;
> +       struct device *dev;
> +       u32 product_id;
> +       u32 revision;
> +
> +       /* look up for chipid node */
> +       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
> +       if (!np)
> +               return -ENODEV;
> +
> +       exynos_chipid_base = of_iomap(np, 0);
> +       of_node_put(np);
> +
> +       if (!exynos_chipid_base) {
> +               pr_err("%s: failed to map chipid\n", np->name);
> +               return -ENOMEM;
> +       }
> +
> +       product_id = readl_relaxed(exynos_chipid_base);
> +       revision = product_id & EXYNOS_REV_MASK;
> +       iounmap(exynos_chipid_base);
> +
> +       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +       if (!soc_dev_attr)
> +               return -ENODEV;

This should be -ENOMEM

> +
> +       soc_dev_attr->family = "Samsung Exynos";
> +
> +       root = of_find_node_by_path("/");
> +       of_property_read_string(root, "model", &soc_dev_attr->machine);
> +       of_node_put(root);
> +
> +       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
> +       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
> +
> +       soc_dev = soc_device_register(soc_dev_attr);
> +       if (IS_ERR(soc_dev)) {
> +               kfree(soc_dev_attr->revision);
> +               kfree_const(soc_dev_attr->soc_id);

This was not allocated with kstrdup_const() so it should not be freed.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-04-07  9:13         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Exynos SoCs have Chipid, for identification of product IDs and SoC
> revisions. This patch intends to provide initialization code for all
> these functionalities, at the same time it provides some sysfs entries
> for accessing these information to user-space.
>
> This driver uses existing binding for exynos-chipid.
>
> CC: Grant Likely <grant.likely@linaro.org>
> CC: Rob Herring <robh+dt@kernel.org>
> CC: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  drivers/soc/samsung/Kconfig         |   5 ++
>  drivers/soc/samsung/Makefile        |   1 +
>  drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 115 insertions(+)
>  create mode 100644 drivers/soc/samsung/exynos-chipid.c
>
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> index 8b25bd5..a90a4ad 100644
> --- a/drivers/soc/samsung/Kconfig
> +++ b/drivers/soc/samsung/Kconfig
> @@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
>
>  if SOC_SAMSUNG
>
> +config EXYNOS_CHIPID
> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
> +       depends on ARCH_EXYNOS || COMPILE_TEST
> +       select SOC_BUS
> +
>  config EXYNOS_PMU
>         bool "Exynos PMU controller driver" if COMPILE_TEST
>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 4d7694a..be3b6bb 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
>  obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
>
>  obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
> new file mode 100644
> index 0000000..1e9fb6b
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-chipid.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
> + *           http://www.samsung.com/
> + *
> + * EXYNOS - CHIP ID support
> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/sys_soc.h>
> +
> +#define EXYNOS_SUBREV_MASK     (0xF << 4)
> +#define EXYNOS_MAINREV_MASK    (0xF << 0)
> +#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
> +
> +static const struct exynos_soc_id {
> +       const char *name;
> +       unsigned int id;
> +       unsigned int mask;
> +} soc_ids[] = {
> +       { "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
> +       { "EXYNOS4210", 0x43210000, 0xFFFFF000 },
> +       { "EXYNOS4212", 0x43220000, 0xFFFFF000 },
> +       { "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
> +       { "EXYNOS5250", 0x43520000, 0xFFFFF000 },
> +       { "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
> +       { "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
> +       { "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
> +       { "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
> +       { "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
> +       { "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
> +       { "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
> +};
> +
> +static const char * __init product_id_to_soc_id(unsigned int product_id)
> +{
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
> +               if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
> +                       return soc_ids[i].name;
> +       return "UNKNOWN";
> +}
> +
> +int __init exynos_chipid_early_init(void)
> +{
> +       struct soc_device_attribute *soc_dev_attr;
> +       void __iomem *exynos_chipid_base;
> +       struct soc_device *soc_dev;
> +       struct device_node *root;
> +       struct device_node *np;
> +       struct device *dev;
> +       u32 product_id;
> +       u32 revision;
> +
> +       /* look up for chipid node */
> +       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
> +       if (!np)
> +               return -ENODEV;
> +
> +       exynos_chipid_base = of_iomap(np, 0);
> +       of_node_put(np);
> +
> +       if (!exynos_chipid_base) {
> +               pr_err("%s: failed to map chipid\n", np->name);
> +               return -ENOMEM;
> +       }
> +
> +       product_id = readl_relaxed(exynos_chipid_base);
> +       revision = product_id & EXYNOS_REV_MASK;
> +       iounmap(exynos_chipid_base);
> +
> +       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
> +       if (!soc_dev_attr)
> +               return -ENODEV;

This should be -ENOMEM

> +
> +       soc_dev_attr->family = "Samsung Exynos";
> +
> +       root = of_find_node_by_path("/");
> +       of_property_read_string(root, "model", &soc_dev_attr->machine);
> +       of_node_put(root);
> +
> +       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
> +       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
> +
> +       soc_dev = soc_device_register(soc_dev_attr);
> +       if (IS_ERR(soc_dev)) {
> +               kfree(soc_dev_attr->revision);
> +               kfree_const(soc_dev_attr->soc_id);

This was not allocated with kstrdup_const() so it should not be freed.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-04-07  9:24         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  9:24 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> For s2r various Exynos SoC needs different programming sequence and data.

This is not S2R so:
"Sleep modes on various Exynos SoCs need..."

> Currently this is handled by adding lots of soc_is_exynosMMM checks in the
> code, in an attempt to remove the dependency of such helper functions
"code." full stop.

> specific to each SoC, let's separate these programming sequence by
> introducing a new struct exynos_s2r_data. This struct will contain

If you plan to extend it to all sleep modes, then:
"exynos_sleep_data"? But if not, then just "exynos_aftr_data" or
"exynos_cpuidle_data" as this is real use for now.

> different function hooks and data for differentiating these programming
> sequences based on SoC's soc_id and revision parameters which can be
> matched by using generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/pm.c | 122 +++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 116 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index 4a73b02..fa24098 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -20,6 +20,7 @@
>  #include <linux/of.h>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>  #include <linux/soc/samsung/exynos-pmu.h>
> +#include <linux/sys_soc.h>
>
>  #include <asm/firmware.h>
>  #include <asm/smp_scu.h>
> @@ -30,6 +31,12 @@
>
>  #include "common.h"
>
> +struct exynos_s2r_data {

Rename all "s2r" occurrences to appropriate name.

> +       void (*enter_aftr)(void);
> +};
> +
> +static const struct exynos_s2r_data *s2r_data;
> +
>  static inline void __iomem *exynos_boot_vector_addr(void)
>  {
>         if (samsung_rev() == EXYNOS4210_REV_1_1)
> @@ -160,13 +167,26 @@ static int exynos_aftr_finisher(unsigned long flags)
>
>  void exynos_enter_aftr(void)
>  {
> +       if (s2r_data && s2r_data->enter_aftr)
> +               s2r_data->enter_aftr();
> +}
> +
> +static void exynos3_enter_aftr(void)
> +{
>         unsigned int cpuid = smp_processor_id();
>
>         cpu_pm_enter();
> +       exynos_set_boot_flag(cpuid, C2_STATE);
> +       exynos_pm_central_suspend();
> +       cpu_suspend(0, exynos_aftr_finisher);
> +       exynos_pm_central_resume();
> +       exynos_clear_boot_flag(cpuid, C2_STATE);
> +       cpu_pm_exit();
> +}
>
> -       if (of_machine_is_compatible("samsung,exynos3250"))
> -               exynos_set_boot_flag(cpuid, C2_STATE);
> -
> +static void exynos4_enter_aftr(void)
> +{
> +       cpu_pm_enter();
>         exynos_pm_central_suspend();
>
>         if (of_machine_is_compatible("samsung,exynos4212") ||
> @@ -185,13 +205,103 @@ void exynos_enter_aftr(void)
>         }
>
>         exynos_pm_central_resume();
> +       cpu_pm_exit();
> +}
>
> -       if (of_machine_is_compatible("samsung,exynos3250"))
> -               exynos_clear_boot_flag(cpuid, C2_STATE);
> -
> +static void exynos5_enter_aftr(void)
> +{
> +       cpu_pm_enter();
> +       exynos_pm_central_suspend();
> +       cpu_suspend(0, exynos_aftr_finisher);
> +       exynos_pm_central_resume();
>         cpu_pm_exit();
>  }
>
> +static const struct exynos_s2r_data exynos_common_s2r_data = {
> +       .enter_aftr             = exynos5_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos3250_s2r_data = {
> +       .enter_aftr             = exynos3_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
> +       .enter_aftr             = exynos4_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
> +       .enter_aftr             = exynos4_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos4x12_s2r_data = {
> +       .enter_aftr             = exynos4_enter_aftr,
> +};
> +
> +static const struct soc_device_attribute exynos_soc_revision[] __initconst = {
> +       {
> +               .soc_id = "EXYNOS3250",
> +               .data = &exynos3250_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "11",
> +               .data = &exynos4210_rev11_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "10",
> +               .data = &exynos4210_rev10_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4212",
> +               .data = &exynos4x12_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4412",
> +               .data = &exynos4x12_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5250",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5260",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5440",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5410",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5420",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5800",
> +               .data = &exynos_common_s2r_data
> +       },
> +};
> +
> +int __init exynos_s2r_init(void)
> +{
> +       const struct soc_device_attribute *match;
> +
> +       match = soc_device_match(exynos_soc_revision);
> +
> +       if (match)
> +               s2r_data = (const struct exynos_s2r_data *) match->data;
> +
> +       if (!s2r_data)
> +               return -ENODEV;
> +
> +       return 0;
> +}
> +arch_initcall(exynos_s2r_init);
> +

I guess you already found possible probe-order issue. You should
register all of this after having the soc chipid driver. However it is
required by cpuidle driver which is being registered in machine_init()
call....  You cannot use deferred probe here, so maybe the only way is
to manually order the calls in machine_init():
1. exynos_chipid_early_init()
2. this one.
3. cpuidle driver register.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
@ 2017-04-07  9:24         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> For s2r various Exynos SoC needs different programming sequence and data.

This is not S2R so:
"Sleep modes on various Exynos SoCs need..."

> Currently this is handled by adding lots of soc_is_exynosMMM checks in the
> code, in an attempt to remove the dependency of such helper functions
"code." full stop.

> specific to each SoC, let's separate these programming sequence by
> introducing a new struct exynos_s2r_data. This struct will contain

If you plan to extend it to all sleep modes, then:
"exynos_sleep_data"? But if not, then just "exynos_aftr_data" or
"exynos_cpuidle_data" as this is real use for now.

> different function hooks and data for differentiating these programming
> sequences based on SoC's soc_id and revision parameters which can be
> matched by using generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/pm.c | 122 +++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 116 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index 4a73b02..fa24098 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -20,6 +20,7 @@
>  #include <linux/of.h>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>  #include <linux/soc/samsung/exynos-pmu.h>
> +#include <linux/sys_soc.h>
>
>  #include <asm/firmware.h>
>  #include <asm/smp_scu.h>
> @@ -30,6 +31,12 @@
>
>  #include "common.h"
>
> +struct exynos_s2r_data {

Rename all "s2r" occurrences to appropriate name.

> +       void (*enter_aftr)(void);
> +};
> +
> +static const struct exynos_s2r_data *s2r_data;
> +
>  static inline void __iomem *exynos_boot_vector_addr(void)
>  {
>         if (samsung_rev() == EXYNOS4210_REV_1_1)
> @@ -160,13 +167,26 @@ static int exynos_aftr_finisher(unsigned long flags)
>
>  void exynos_enter_aftr(void)
>  {
> +       if (s2r_data && s2r_data->enter_aftr)
> +               s2r_data->enter_aftr();
> +}
> +
> +static void exynos3_enter_aftr(void)
> +{
>         unsigned int cpuid = smp_processor_id();
>
>         cpu_pm_enter();
> +       exynos_set_boot_flag(cpuid, C2_STATE);
> +       exynos_pm_central_suspend();
> +       cpu_suspend(0, exynos_aftr_finisher);
> +       exynos_pm_central_resume();
> +       exynos_clear_boot_flag(cpuid, C2_STATE);
> +       cpu_pm_exit();
> +}
>
> -       if (of_machine_is_compatible("samsung,exynos3250"))
> -               exynos_set_boot_flag(cpuid, C2_STATE);
> -
> +static void exynos4_enter_aftr(void)
> +{
> +       cpu_pm_enter();
>         exynos_pm_central_suspend();
>
>         if (of_machine_is_compatible("samsung,exynos4212") ||
> @@ -185,13 +205,103 @@ void exynos_enter_aftr(void)
>         }
>
>         exynos_pm_central_resume();
> +       cpu_pm_exit();
> +}
>
> -       if (of_machine_is_compatible("samsung,exynos3250"))
> -               exynos_clear_boot_flag(cpuid, C2_STATE);
> -
> +static void exynos5_enter_aftr(void)
> +{
> +       cpu_pm_enter();
> +       exynos_pm_central_suspend();
> +       cpu_suspend(0, exynos_aftr_finisher);
> +       exynos_pm_central_resume();
>         cpu_pm_exit();
>  }
>
> +static const struct exynos_s2r_data exynos_common_s2r_data = {
> +       .enter_aftr             = exynos5_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos3250_s2r_data = {
> +       .enter_aftr             = exynos3_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
> +       .enter_aftr             = exynos4_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
> +       .enter_aftr             = exynos4_enter_aftr,
> +};
> +
> +static const struct exynos_s2r_data exynos4x12_s2r_data = {
> +       .enter_aftr             = exynos4_enter_aftr,
> +};
> +
> +static const struct soc_device_attribute exynos_soc_revision[] __initconst = {
> +       {
> +               .soc_id = "EXYNOS3250",
> +               .data = &exynos3250_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "11",
> +               .data = &exynos4210_rev11_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "10",
> +               .data = &exynos4210_rev10_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4212",
> +               .data = &exynos4x12_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS4412",
> +               .data = &exynos4x12_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5250",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5260",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5440",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5410",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5420",
> +               .data = &exynos_common_s2r_data
> +       },
> +       {
> +               .soc_id = "EXYNOS5800",
> +               .data = &exynos_common_s2r_data
> +       },
> +};
> +
> +int __init exynos_s2r_init(void)
> +{
> +       const struct soc_device_attribute *match;
> +
> +       match = soc_device_match(exynos_soc_revision);
> +
> +       if (match)
> +               s2r_data = (const struct exynos_s2r_data *) match->data;
> +
> +       if (!s2r_data)
> +               return -ENODEV;
> +
> +       return 0;
> +}
> +arch_initcall(exynos_s2r_init);
> +

I guess you already found possible probe-order issue. You should
register all of this after having the soc chipid driver. However it is
required by cpuidle driver which is being registered in machine_init()
call....  You cannot use deferred probe here, so maybe the only way is
to manually order the calls in machine_init():
1. exynos_chipid_early_init()
2. this one.
3. cpuidle driver register.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr,flag} ops to exynos_s2r_data
  2017-03-30 13:17       ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} " Pankaj Dubey
@ 2017-04-07 10:32         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 10:32 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC needs different boot addresses and flags. Currently we
> are handling this difference by adding lots of soc_is_exynosMMM checks in
> the code, in an attempt to remove the dependency of such helper functions
> specific to each SoC, let's separate helper functions for these helper
> functions by moving them into SoC specific hooks in struct exynos_s2r_data.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/pm.c | 60 +++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 50 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index fa24098..c3fa537 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -32,26 +32,56 @@
>  #include "common.h"
>
>  struct exynos_s2r_data {
> +       void __iomem* (*boot_vector_addr)(void);
> +       void __iomem* (*boot_vector_flag)(void);
>         void (*enter_aftr)(void);
>  };

OK, now I see more uses of this structure so the naming could be
"exynos_pm_data"?

>
>  static const struct exynos_s2r_data *s2r_data;
>
> -static inline void __iomem *exynos_boot_vector_addr(void)
> +static void __iomem *exynos_boot_vector_addr(void)
> +{
> +       if (s2r_data && s2r_data->boot_vector_addr)
> +               return s2r_data->boot_vector_addr();
> +
> +       return NULL;
> +}
> +
> +static inline void __iomem *exynos4210_rev11_boot_vector_addr(void)

Inlines here are mixed up and you are changing them without
explanation in commit msg. Previously the exynos_boot_vector_addr()
was inlined, now not. Okay, I can accept that but please mention this
in commit msg.
But below you are adding new inline functions which are stored as
pointers in ops. This looks both inconsistent with above and incorrect
from logical point of view. How would you like to inline them if they
are referenced through pointer? (okay, compilers are smart and crazy
so maybe they can do it but anyway I am curious how this would look
like).

> +{
> +       return pmu_base_addr + S5P_INFORM7;
> +}
> +
> +static inline void __iomem *exynos4210_rev10_boot_vector_addr(void)
> +{
> +       return sysram_base_addr + 0x24;
> +}
> +
> +static inline void __iomem *exynos_common_boot_vector_addr(void)
>  {
> -       if (samsung_rev() == EXYNOS4210_REV_1_1)
> -               return pmu_base_addr + S5P_INFORM7;
> -       else if (samsung_rev() == EXYNOS4210_REV_1_0)
> -               return sysram_base_addr + 0x24;
>         return pmu_base_addr + S5P_INFORM0;
>  }
>
> -static inline void __iomem *exynos_boot_vector_flag(void)
> +static void __iomem *exynos_boot_vector_flag(void)

ditto for the flag.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} ops to exynos_s2r_data
@ 2017-04-07 10:32         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC needs different boot addresses and flags. Currently we
> are handling this difference by adding lots of soc_is_exynosMMM checks in
> the code, in an attempt to remove the dependency of such helper functions
> specific to each SoC, let's separate helper functions for these helper
> functions by moving them into SoC specific hooks in struct exynos_s2r_data.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/pm.c | 60 +++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 50 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
> index fa24098..c3fa537 100644
> --- a/arch/arm/mach-exynos/pm.c
> +++ b/arch/arm/mach-exynos/pm.c
> @@ -32,26 +32,56 @@
>  #include "common.h"
>
>  struct exynos_s2r_data {
> +       void __iomem* (*boot_vector_addr)(void);
> +       void __iomem* (*boot_vector_flag)(void);
>         void (*enter_aftr)(void);
>  };

OK, now I see more uses of this structure so the naming could be
"exynos_pm_data"?

>
>  static const struct exynos_s2r_data *s2r_data;
>
> -static inline void __iomem *exynos_boot_vector_addr(void)
> +static void __iomem *exynos_boot_vector_addr(void)
> +{
> +       if (s2r_data && s2r_data->boot_vector_addr)
> +               return s2r_data->boot_vector_addr();
> +
> +       return NULL;
> +}
> +
> +static inline void __iomem *exynos4210_rev11_boot_vector_addr(void)

Inlines here are mixed up and you are changing them without
explanation in commit msg. Previously the exynos_boot_vector_addr()
was inlined, now not. Okay, I can accept that but please mention this
in commit msg.
But below you are adding new inline functions which are stored as
pointers in ops. This looks both inconsistent with above and incorrect
from logical point of view. How would you like to inline them if they
are referenced through pointer? (okay, compilers are smart and crazy
so maybe they can do it but anyway I am curious how this would look
like).

> +{
> +       return pmu_base_addr + S5P_INFORM7;
> +}
> +
> +static inline void __iomem *exynos4210_rev10_boot_vector_addr(void)
> +{
> +       return sysram_base_addr + 0x24;
> +}
> +
> +static inline void __iomem *exynos_common_boot_vector_addr(void)
>  {
> -       if (samsung_rev() == EXYNOS4210_REV_1_1)
> -               return pmu_base_addr + S5P_INFORM7;
> -       else if (samsung_rev() == EXYNOS4210_REV_1_0)
> -               return sysram_base_addr + 0x24;
>         return pmu_base_addr + S5P_INFORM0;
>  }
>
> -static inline void __iomem *exynos_boot_vector_flag(void)
> +static void __iomem *exynos_boot_vector_flag(void)

ditto for the flag.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-04-07 10:41         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 10:41 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC has different CPU related information, such as CPU
> boot register, programming sequence making CPU up/down. Currently this
> is handled by adding lots of soc_is_exynosMMM checks in the code, in
> an attempt to remove the dependency of such helper functions specific to
> each SoC, let's separate this information pertaining to CPU by introducing
> a new "struct exynos_cpu_info". This struct will contain differences
> associated with CPU on various Exynos SoC. This can be matched by using
> generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 135 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index cb6d199..ff369b9 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -19,6 +19,7 @@
>  #include <linux/smp.h>
>  #include <linux/io.h>
>  #include <linux/of_address.h>
> +#include <linux/sys_soc.h>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>
>  #include <asm/cacheflush.h>
> @@ -33,6 +34,16 @@
>
>  extern void exynos4_secondary_startup(void);
>
> +/*
> + * struct exynos_cpu_info - Exynos CPU related info/operations
> + * @cpu_boot_reg: computes cpu boot address for requested cpu
> + */
> +struct exynos_cpu_info {
> +       void __iomem* (*cpu_boot_reg)(u32 cpu);
> +};

Beside Marek comments, I think we are getting too many structures for
differentiating Exynos. Actually all of them describe the same -
difference between Exynos revisions. Having many separate structures
means that you have to initialize all of them in different places in
different (probably) order. The good benefit is however making them
local (static) so the scope is limited... but anyway I dislike the
duplication.

How about combining all of them into one (except the firmware which
has its own register function):

struct exynos_revision_data {
void __iomem* (*boot_vector_addr)(void);
void __iomem* (*boot_vector_flag)(void);
void (*enter_aftr)(void);
void __iomem* (*cpu_boot_reg)(u32 cpu);
void (*cpu_power_down)(u32 cpu);
void (*cpu_power_up)(u32 cpu);
};

Best regards,
Krzysztof


> +
> +static const struct exynos_cpu_info *cpu_info;
> +
>  #ifdef CONFIG_HOTPLUG_CPU
>  static inline void cpu_leave_lowpower(u32 core_id)
>  {
> @@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
>                 S5P_CORE_LOCAL_PWR_EN);
>  }
>
> -static void __iomem *cpu_boot_reg_base(void)
> +static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
>  {
> -       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
> -               return pmu_base_addr + S5P_INFORM5;
> -       return sysram_base_addr;
> +       void __iomem *boot_reg = pmu_base_addr;
> +
> +       if (!boot_reg)
> +               return IOMEM_ERR_PTR(-ENODEV);
> +
> +       boot_reg += S5P_INFORM5;
> +
> +       return boot_reg;
>  }
>
> -static inline void __iomem *cpu_boot_reg(int cpu)
> +static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
>  {
> -       void __iomem *boot_reg;
> +       void __iomem *boot_reg = sysram_base_addr;
>
> -       boot_reg = cpu_boot_reg_base();
>         if (!boot_reg)
>                 return IOMEM_ERR_PTR(-ENODEV);
> -       if (soc_is_exynos4412())
> -               boot_reg += 4*cpu;
> -       else if (soc_is_exynos5420() || soc_is_exynos5800())
> -               boot_reg += 4;
> +
> +       boot_reg += 4*cpu;
> +
>         return boot_reg;
>  }
>
> +static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
> +{
> +       void __iomem *boot_reg = sysram_base_addr;
> +
> +       if (!sysram_base_addr)
> +               return IOMEM_ERR_PTR(-ENODEV);
> +
> +       boot_reg += 4;
> +
> +       return boot_reg;
> +}
> +
> +static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
> +{
> +       if (!sysram_base_addr)
> +               return IOMEM_ERR_PTR(-ENODEV);
> +
> +       return sysram_base_addr;
> +}
> +
> +static inline void __iomem *cpu_boot_reg(int cpu)
> +{
> +       if (cpu_info && cpu_info->cpu_boot_reg)
> +               return cpu_info->cpu_boot_reg(cpu);
> +       return NULL;
> +}
> +
>  /*
>   * Set wake up by local power mode and execute software reset for given core.
>   *
> @@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
>         return ret;
>  }
>
> +static const struct exynos_cpu_info exynos3250_cpu_info = {
> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos5420_cpu_info = {
> +       .cpu_boot_reg = exynos5420_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
> +       .cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4412_cpu_info = {
> +       .cpu_boot_reg = exynos4412_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos_common_cpu_info = {
> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct soc_device_attribute exynos_soc_revision[] = {
> +       {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "11",
> +               .data = &exynos4210_rev11_cpu_info
> +       }, {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "10",
> +               .data = &exynos_common_cpu_info
> +       }
> +};
> +
> +static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
> +       {
> +               .compatible = "samsung,exynos3250",
> +               .data = &exynos3250_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos4212",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos4412",
> +               .data = &exynos4412_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5250",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5260",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5410",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5420",
> +               .data = &exynos5420_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5440",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5800",
> +               .data = &exynos5420_cpu_info
> +       },
> +       { /*sentinel*/ },
> +};
> +
>  static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  {
>         unsigned long timeout;
> +       const struct soc_device_attribute *match;
>         u32 mpidr = cpu_logical_map(cpu);
>         u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>         int ret = -ENOSYS;
>
> +       if (of_machine_is_compatible("samsung,exynos4210")) {
> +               match = soc_device_match(exynos_soc_revision);
> +               if (match)
> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
> +       }
> +
>         /*
>          * Set synchronisation state between this boot processor
>          * and the secondary one
> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>
>  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>  {
> +       const struct of_device_id *match;
> +       struct device_node *np;
> +
> +       if (!of_machine_is_compatible("samsung,exynos4210")) {
> +               np = of_find_matching_node_and_match(NULL,
> +                               exynos_pmu_of_device_ids, &match);
> +               if (!np)
> +                       pr_err("failed to find supported CPU\n");
> +               else
> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
> +       }
> +
>         exynos_sysram_init();
>
>         exynos_set_delayed_reset_assertion(true);
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-04-07 10:41         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC has different CPU related information, such as CPU
> boot register, programming sequence making CPU up/down. Currently this
> is handled by adding lots of soc_is_exynosMMM checks in the code, in
> an attempt to remove the dependency of such helper functions specific to
> each SoC, let's separate this information pertaining to CPU by introducing
> a new "struct exynos_cpu_info". This struct will contain differences
> associated with CPU on various Exynos SoC. This can be matched by using
> generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 135 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index cb6d199..ff369b9 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -19,6 +19,7 @@
>  #include <linux/smp.h>
>  #include <linux/io.h>
>  #include <linux/of_address.h>
> +#include <linux/sys_soc.h>
>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>
>  #include <asm/cacheflush.h>
> @@ -33,6 +34,16 @@
>
>  extern void exynos4_secondary_startup(void);
>
> +/*
> + * struct exynos_cpu_info - Exynos CPU related info/operations
> + * @cpu_boot_reg: computes cpu boot address for requested cpu
> + */
> +struct exynos_cpu_info {
> +       void __iomem* (*cpu_boot_reg)(u32 cpu);
> +};

Beside Marek comments, I think we are getting too many structures for
differentiating Exynos. Actually all of them describe the same -
difference between Exynos revisions. Having many separate structures
means that you have to initialize all of them in different places in
different (probably) order. The good benefit is however making them
local (static) so the scope is limited... but anyway I dislike the
duplication.

How about combining all of them into one (except the firmware which
has its own register function):

struct exynos_revision_data {
void __iomem* (*boot_vector_addr)(void);
void __iomem* (*boot_vector_flag)(void);
void (*enter_aftr)(void);
void __iomem* (*cpu_boot_reg)(u32 cpu);
void (*cpu_power_down)(u32 cpu);
void (*cpu_power_up)(u32 cpu);
};

Best regards,
Krzysztof


> +
> +static const struct exynos_cpu_info *cpu_info;
> +
>  #ifdef CONFIG_HOTPLUG_CPU
>  static inline void cpu_leave_lowpower(u32 core_id)
>  {
> @@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
>                 S5P_CORE_LOCAL_PWR_EN);
>  }
>
> -static void __iomem *cpu_boot_reg_base(void)
> +static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
>  {
> -       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
> -               return pmu_base_addr + S5P_INFORM5;
> -       return sysram_base_addr;
> +       void __iomem *boot_reg = pmu_base_addr;
> +
> +       if (!boot_reg)
> +               return IOMEM_ERR_PTR(-ENODEV);
> +
> +       boot_reg += S5P_INFORM5;
> +
> +       return boot_reg;
>  }
>
> -static inline void __iomem *cpu_boot_reg(int cpu)
> +static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
>  {
> -       void __iomem *boot_reg;
> +       void __iomem *boot_reg = sysram_base_addr;
>
> -       boot_reg = cpu_boot_reg_base();
>         if (!boot_reg)
>                 return IOMEM_ERR_PTR(-ENODEV);
> -       if (soc_is_exynos4412())
> -               boot_reg += 4*cpu;
> -       else if (soc_is_exynos5420() || soc_is_exynos5800())
> -               boot_reg += 4;
> +
> +       boot_reg += 4*cpu;
> +
>         return boot_reg;
>  }
>
> +static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
> +{
> +       void __iomem *boot_reg = sysram_base_addr;
> +
> +       if (!sysram_base_addr)
> +               return IOMEM_ERR_PTR(-ENODEV);
> +
> +       boot_reg += 4;
> +
> +       return boot_reg;
> +}
> +
> +static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
> +{
> +       if (!sysram_base_addr)
> +               return IOMEM_ERR_PTR(-ENODEV);
> +
> +       return sysram_base_addr;
> +}
> +
> +static inline void __iomem *cpu_boot_reg(int cpu)
> +{
> +       if (cpu_info && cpu_info->cpu_boot_reg)
> +               return cpu_info->cpu_boot_reg(cpu);
> +       return NULL;
> +}
> +
>  /*
>   * Set wake up by local power mode and execute software reset for given core.
>   *
> @@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
>         return ret;
>  }
>
> +static const struct exynos_cpu_info exynos3250_cpu_info = {
> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos5420_cpu_info = {
> +       .cpu_boot_reg = exynos5420_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
> +       .cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos4412_cpu_info = {
> +       .cpu_boot_reg = exynos4412_cpu_boot_reg,
> +};
> +
> +static const struct exynos_cpu_info exynos_common_cpu_info = {
> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
> +};
> +
> +static const struct soc_device_attribute exynos_soc_revision[] = {
> +       {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "11",
> +               .data = &exynos4210_rev11_cpu_info
> +       }, {
> +               .soc_id = "EXYNOS4210",
> +               .revision = "10",
> +               .data = &exynos_common_cpu_info
> +       }
> +};
> +
> +static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
> +       {
> +               .compatible = "samsung,exynos3250",
> +               .data = &exynos3250_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos4212",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos4412",
> +               .data = &exynos4412_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5250",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5260",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5410",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5420",
> +               .data = &exynos5420_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5440",
> +               .data = &exynos_common_cpu_info
> +       }, {
> +               .compatible = "samsung,exynos5800",
> +               .data = &exynos5420_cpu_info
> +       },
> +       { /*sentinel*/ },
> +};
> +
>  static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  {
>         unsigned long timeout;
> +       const struct soc_device_attribute *match;
>         u32 mpidr = cpu_logical_map(cpu);
>         u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>         int ret = -ENOSYS;
>
> +       if (of_machine_is_compatible("samsung,exynos4210")) {
> +               match = soc_device_match(exynos_soc_revision);
> +               if (match)
> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
> +       }
> +
>         /*
>          * Set synchronisation state between this boot processor
>          * and the secondary one
> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>
>  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>  {
> +       const struct of_device_id *match;
> +       struct device_node *np;
> +
> +       if (!of_machine_is_compatible("samsung,exynos4210")) {
> +               np = of_find_matching_node_and_match(NULL,
> +                               exynos_pmu_of_device_ids, &match);
> +               if (!np)
> +                       pr_err("failed to find supported CPU\n");
> +               else
> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
> +       }
> +
>         exynos_sysram_init();
>
>         exynos_set_delayed_reset_assertion(true);
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-04-07 10:47         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 10:47 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC has different CPU related information, such as CPU
> boot register, programming sequence making CPU up/down. Currently this
> is handled by adding lots of soc_is_exynosMMM checks in the code, in
> an attempt to remove the dependency of such helper functions specific to
> each SoC, let's separate this information pertaining to CPU by introducing
> a new "struct exynos_cpu_info". This struct will contain differences
> associated with CPU on various Exynos SoC. This can be matched by using
> generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 135 insertions(+), 11 deletions(-)

(...)

>  static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  {
>         unsigned long timeout;
> +       const struct soc_device_attribute *match;
>         u32 mpidr = cpu_logical_map(cpu);
>         u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>         int ret = -ENOSYS;
>
> +       if (of_machine_is_compatible("samsung,exynos4210")) {
> +               match = soc_device_match(exynos_soc_revision);
> +               if (match)
> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
> +       }
> +
>         /*
>          * Set synchronisation state between this boot processor
>          * and the secondary one
> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>
>  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>  {
> +       const struct of_device_id *match;
> +       struct device_node *np;
> +
> +       if (!of_machine_is_compatible("samsung,exynos4210")) {

This differentiation is unnatural. It looks like the chipid
soc_device_match driver is not simplifying things but complicating.
Maybe the solution I mentioned in previous mails (initialize these in
proper order from some of machine init calls) would simplify it...

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-04-07 10:47         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC has different CPU related information, such as CPU
> boot register, programming sequence making CPU up/down. Currently this
> is handled by adding lots of soc_is_exynosMMM checks in the code, in
> an attempt to remove the dependency of such helper functions specific to
> each SoC, let's separate this information pertaining to CPU by introducing
> a new "struct exynos_cpu_info". This struct will contain differences
> associated with CPU on various Exynos SoC. This can be matched by using
> generic API "soc_device_match".
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>  1 file changed, 135 insertions(+), 11 deletions(-)

(...)

>  static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  {
>         unsigned long timeout;
> +       const struct soc_device_attribute *match;
>         u32 mpidr = cpu_logical_map(cpu);
>         u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>         int ret = -ENOSYS;
>
> +       if (of_machine_is_compatible("samsung,exynos4210")) {
> +               match = soc_device_match(exynos_soc_revision);
> +               if (match)
> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
> +       }
> +
>         /*
>          * Set synchronisation state between this boot processor
>          * and the secondary one
> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>
>  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>  {
> +       const struct of_device_id *match;
> +       struct device_node *np;
> +
> +       if (!of_machine_is_compatible("samsung,exynos4210")) {

This differentiation is unnatural. It looks like the chipid
soc_device_match driver is not simplifying things but complicating.
Maybe the solution I mentioned in previous mails (initialize these in
proper order from some of machine init calls) would simplify it...

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
  2017-03-30 13:17       ` [PATCH v9 10/12] ARM: EXYNOS: move power_{down, up} " Pankaj Dubey
@ 2017-04-07 12:04         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 12:04 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC handles CPU power_up and power_down operation
> differently. To handle this difference until now we were using
> soc_is_exynosMMM helper functions, in an attempt to remove the dependency
> of such helper functions specific to each SoC, let's move power_{down,up}
> functionality as a SoC specific function pointer hooks in
> struct exynos_cpu_info.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 61 +++++++++++++++++++++++++++++++-----------
>  1 file changed, 46 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index ff369b9..6f08b15 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -37,9 +37,13 @@ extern void exynos4_secondary_startup(void);
>  /*
>   * struct exynos_cpu_info - Exynos CPU related info/operations
>   * @cpu_boot_reg: computes cpu boot address for requested cpu
> + * @cpu_power_down: handles cpu power down routine for requested cpu
> + * @cpu_power_up: handles cpu power up routine for requested cpu
>   */
>  struct exynos_cpu_info {
>         void __iomem* (*cpu_boot_reg)(u32 cpu);
> +       void (*cpu_power_down)(u32 cpu);
> +       void (*cpu_power_up)(u32 cpu);
>  };
>
>  static const struct exynos_cpu_info *cpu_info;
> @@ -92,19 +96,29 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
>  }
>  #endif /* CONFIG_HOTPLUG_CPU */
>
> -/**
> - * exynos_core_power_down : power down the specified cpu
> +/*
> + * exynos_core_power_down - power down the specified cpu
>   * @cpu : the cpu to power down
> - *
> - * Power down the specified cpu. The sequence must be finished by a
> - * call to cpu_do_idle()
> - *
> + * The sequence must be finished by a call to cpu_do_idle()
>   */
>  void exynos_cpu_power_down(int cpu)
>  {
> +       if (cpu_info && cpu_info->cpu_power_down)
> +               cpu_info->cpu_power_down(cpu);
> +}
> +
> +static void exynos_common_cpu_power_down(u32 cpu)
> +{
>         u32 core_conf;
>
> -       if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
> +       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
> +       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +}
> +
> +static void exynos5420_cpu_power_down(u32 cpu)
> +{
> +       if (cpu == 0) {
>                 /*
>                  * Bypass power down for CPU0 during suspend. Check for
>                  * the SYS_PWR_REG value to decide if we are suspending
> @@ -116,24 +130,31 @@ void exynos_cpu_power_down(int cpu)
>                         return;
>         }
>
> -       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> -       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
> -       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +       exynos_common_cpu_power_down(cpu);
>  }
>
> -/**
> +/*
>   * exynos_cpu_power_up : power up the specified cpu
>   * @cpu : the cpu to power up
> - *
> - * Power up the specified cpu
>   */
>  void exynos_cpu_power_up(int cpu)
>  {
> +       if (cpu_info && cpu_info->cpu_power_up)
> +               cpu_info->cpu_power_up(cpu);
> +}
> +
> +static void exynos_common_cpu_power_up(u32 cpu)
> +{
>         u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
> +       pmu_raw_writel(core_conf,
> +                       EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +}
>
> -       if (soc_is_exynos3250())
> -               core_conf |= S5P_CORE_AUTOWAKEUP_EN;
> +static void exynos3250_cpu_power_up(u32 cpu)
> +{
> +       u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>
> +       core_conf |= S5P_CORE_AUTOWAKEUP_EN;

Maybe just:
        core_conf = S5P_CORE_LOCAL_PWR_EN \
                           | S5P_CORE_AUTOWAKEUP_EN;
?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
@ 2017-04-07 12:04         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> Various Exynos SoC handles CPU power_up and power_down operation
> differently. To handle this difference until now we were using
> soc_is_exynosMMM helper functions, in an attempt to remove the dependency
> of such helper functions specific to each SoC, let's move power_{down,up}
> functionality as a SoC specific function pointer hooks in
> struct exynos_cpu_info.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 61 +++++++++++++++++++++++++++++++-----------
>  1 file changed, 46 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index ff369b9..6f08b15 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -37,9 +37,13 @@ extern void exynos4_secondary_startup(void);
>  /*
>   * struct exynos_cpu_info - Exynos CPU related info/operations
>   * @cpu_boot_reg: computes cpu boot address for requested cpu
> + * @cpu_power_down: handles cpu power down routine for requested cpu
> + * @cpu_power_up: handles cpu power up routine for requested cpu
>   */
>  struct exynos_cpu_info {
>         void __iomem* (*cpu_boot_reg)(u32 cpu);
> +       void (*cpu_power_down)(u32 cpu);
> +       void (*cpu_power_up)(u32 cpu);
>  };
>
>  static const struct exynos_cpu_info *cpu_info;
> @@ -92,19 +96,29 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
>  }
>  #endif /* CONFIG_HOTPLUG_CPU */
>
> -/**
> - * exynos_core_power_down : power down the specified cpu
> +/*
> + * exynos_core_power_down - power down the specified cpu
>   * @cpu : the cpu to power down
> - *
> - * Power down the specified cpu. The sequence must be finished by a
> - * call to cpu_do_idle()
> - *
> + * The sequence must be finished by a call to cpu_do_idle()
>   */
>  void exynos_cpu_power_down(int cpu)
>  {
> +       if (cpu_info && cpu_info->cpu_power_down)
> +               cpu_info->cpu_power_down(cpu);
> +}
> +
> +static void exynos_common_cpu_power_down(u32 cpu)
> +{
>         u32 core_conf;
>
> -       if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
> +       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
> +       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +}
> +
> +static void exynos5420_cpu_power_down(u32 cpu)
> +{
> +       if (cpu == 0) {
>                 /*
>                  * Bypass power down for CPU0 during suspend. Check for
>                  * the SYS_PWR_REG value to decide if we are suspending
> @@ -116,24 +130,31 @@ void exynos_cpu_power_down(int cpu)
>                         return;
>         }
>
> -       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> -       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
> -       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +       exynos_common_cpu_power_down(cpu);
>  }
>
> -/**
> +/*
>   * exynos_cpu_power_up : power up the specified cpu
>   * @cpu : the cpu to power up
> - *
> - * Power up the specified cpu
>   */
>  void exynos_cpu_power_up(int cpu)
>  {
> +       if (cpu_info && cpu_info->cpu_power_up)
> +               cpu_info->cpu_power_up(cpu);
> +}
> +
> +static void exynos_common_cpu_power_up(u32 cpu)
> +{
>         u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
> +       pmu_raw_writel(core_conf,
> +                       EXYNOS_ARM_CORE_CONFIGURATION(cpu));
> +}
>
> -       if (soc_is_exynos3250())
> -               core_conf |= S5P_CORE_AUTOWAKEUP_EN;
> +static void exynos3250_cpu_power_up(u32 cpu)
> +{
> +       u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>
> +       core_conf |= S5P_CORE_AUTOWAKEUP_EN;

Maybe just:
        core_conf = S5P_CORE_LOCAL_PWR_EN \
                           | S5P_CORE_AUTOWAKEUP_EN;
?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
  2017-04-07  8:24         ` Krzysztof Kozlowski
@ 2017-04-07 12:12           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 12:12 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 01:54 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
>> driver, so let's remove/minimize usage of any such helper function usage
>> from pm.c.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>>  2 files changed, 15 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index 1a7e5b5..4a73b02 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>>  }
>>
>>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
>> -static void exynos_set_wakeupmask(long mask)
>> +static void exynos_set_wakeupmask(void)
>>  {
>> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
>> -       if (soc_is_exynos3250())
>> +       if (of_machine_is_compatible("samsung,exynos3250")) {
>> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
>> +       } else
>> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
> 
> You need {} around this too. Checkpatch should complain about it as
> well so be sure to run it.
> 

I ran checkpatch before posting, but it didn't complain about this. Here
is the result when I ran it again today on the same patch.

./scripts/checkpatch.pl
exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch

total: 0 errors, 0 warnings, 81 lines checked

exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
has no obvious style problems and is ready for submission.


Thanks,
Pankaj Dubey
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> 
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
@ 2017-04-07 12:12           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 12:12 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 01:54 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
>> driver, so let's remove/minimize usage of any such helper function usage
>> from pm.c.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>>  2 files changed, 15 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index 1a7e5b5..4a73b02 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>>  }
>>
>>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
>> -static void exynos_set_wakeupmask(long mask)
>> +static void exynos_set_wakeupmask(void)
>>  {
>> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
>> -       if (soc_is_exynos3250())
>> +       if (of_machine_is_compatible("samsung,exynos3250")) {
>> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
>> +       } else
>> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
> 
> You need {} around this too. Checkpatch should complain about it as
> well so be sure to run it.
> 

I ran checkpatch before posting, but it didn't complain about this. Here
is the result when I ran it again today on the same patch.

./scripts/checkpatch.pl
exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch

total: 0 errors, 0 warnings, 81 lines checked

exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
has no obvious style problems and is ready for submission.


Thanks,
Pankaj Dubey
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> 
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus
  2017-04-07  8:31         ` Krzysztof Kozlowski
@ 2017-04-07 12:15           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 12:15 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 02:01 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> We are taking care of setting secondary cpu boot address in
>> exynos_boot_secondary just before sending ipi to secondary CPUs,
>> so we can safely remove this setting from smp_prepare_cpus.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/platsmp.c | 26 --------------------------
>>  1 file changed, 26 deletions(-)
>>
> 
> I also wondered why we need this twice... Testing on different
> platforms would be nice to be sure that we did not miss anything but
> it looks correct for me. For my reference:
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> 

Thanks for review.
I am trying to get one Exynos3250 based board for testing, once I get
chance to test on it, I will update status about this.

Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus
@ 2017-04-07 12:15           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 12:15 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 02:01 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> We are taking care of setting secondary cpu boot address in
>> exynos_boot_secondary just before sending ipi to secondary CPUs,
>> so we can safely remove this setting from smp_prepare_cpus.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/platsmp.c | 26 --------------------------
>>  1 file changed, 26 deletions(-)
>>
> 
> I also wondered why we need this twice... Testing on different
> platforms would be nice to be sure that we did not miss anything but
> it looks correct for me. For my reference:
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> 

Thanks for review.
I am trying to get one Exynos3250 based board for testing, once I get
chance to test on it, I will update status about this.

Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
  2017-04-07  9:13         ` Krzysztof Kozlowski
@ 2017-04-07 12:18           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 12:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas,
	Grant Likely, Rob Herring, Linus Walleij



On Friday 07 April 2017 02:43 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Exynos SoCs have Chipid, for identification of product IDs and SoC
>> revisions. This patch intends to provide initialization code for all
>> these functionalities, at the same time it provides some sysfs entries
>> for accessing these information to user-space.
>>
>> This driver uses existing binding for exynos-chipid.
>>
>> CC: Grant Likely <grant.likely@linaro.org>
>> CC: Rob Herring <robh+dt@kernel.org>
>> CC: Linus Walleij <linus.walleij@linaro.org>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>  drivers/soc/samsung/Kconfig         |   5 ++
>>  drivers/soc/samsung/Makefile        |   1 +
>>  drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 115 insertions(+)
>>  create mode 100644 drivers/soc/samsung/exynos-chipid.c
>>
>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>> index 8b25bd5..a90a4ad 100644
>> --- a/drivers/soc/samsung/Kconfig
>> +++ b/drivers/soc/samsung/Kconfig
>> @@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
>>
>>  if SOC_SAMSUNG
>>
>> +config EXYNOS_CHIPID
>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>> +       select SOC_BUS
>> +
>>  config EXYNOS_PMU
>>         bool "Exynos PMU controller driver" if COMPILE_TEST
>>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
>> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
>> index 4d7694a..be3b6bb 100644
>> --- a/drivers/soc/samsung/Makefile
>> +++ b/drivers/soc/samsung/Makefile
>> @@ -1,3 +1,4 @@
>> +obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
>>  obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
>>
>>  obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
>> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
>> new file mode 100644
>> index 0000000..1e9fb6b
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -0,0 +1,109 @@
>> +/*
>> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
>> + *           http://www.samsung.com/
>> + *
>> + * EXYNOS - CHIP ID support
>> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/sys_soc.h>
>> +
>> +#define EXYNOS_SUBREV_MASK     (0xF << 4)
>> +#define EXYNOS_MAINREV_MASK    (0xF << 0)
>> +#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
>> +
>> +static const struct exynos_soc_id {
>> +       const char *name;
>> +       unsigned int id;
>> +       unsigned int mask;
>> +} soc_ids[] = {
>> +       { "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
>> +       { "EXYNOS4210", 0x43210000, 0xFFFFF000 },
>> +       { "EXYNOS4212", 0x43220000, 0xFFFFF000 },
>> +       { "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
>> +       { "EXYNOS5250", 0x43520000, 0xFFFFF000 },
>> +       { "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
>> +       { "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
>> +       { "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
>> +       { "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
>> +       { "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
>> +       { "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
>> +       { "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
>> +};
>> +
>> +static const char * __init product_id_to_soc_id(unsigned int product_id)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
>> +               if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
>> +                       return soc_ids[i].name;
>> +       return "UNKNOWN";
>> +}
>> +
>> +int __init exynos_chipid_early_init(void)
>> +{
>> +       struct soc_device_attribute *soc_dev_attr;
>> +       void __iomem *exynos_chipid_base;
>> +       struct soc_device *soc_dev;
>> +       struct device_node *root;
>> +       struct device_node *np;
>> +       struct device *dev;
>> +       u32 product_id;
>> +       u32 revision;
>> +
>> +       /* look up for chipid node */
>> +       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
>> +       if (!np)
>> +               return -ENODEV;
>> +
>> +       exynos_chipid_base = of_iomap(np, 0);
>> +       of_node_put(np);
>> +
>> +       if (!exynos_chipid_base) {
>> +               pr_err("%s: failed to map chipid\n", np->name);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       product_id = readl_relaxed(exynos_chipid_base);
>> +       revision = product_id & EXYNOS_REV_MASK;
>> +       iounmap(exynos_chipid_base);
>> +
>> +       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
>> +       if (!soc_dev_attr)
>> +               return -ENODEV;
> 
> This should be -ENOMEM
> 
OK. Will take care in next patchset.

>> +
>> +       soc_dev_attr->family = "Samsung Exynos";
>> +
>> +       root = of_find_node_by_path("/");
>> +       of_property_read_string(root, "model", &soc_dev_attr->machine);
>> +       of_node_put(root);
>> +
>> +       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
>> +       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
>> +
>> +       soc_dev = soc_device_register(soc_dev_attr);
>> +       if (IS_ERR(soc_dev)) {
>> +               kfree(soc_dev_attr->revision);
>> +               kfree_const(soc_dev_attr->soc_id);
> 
> This was not allocated with kstrdup_const() so it should not be freed.
> 

Sorry, I missed to take care of this, you pointed out this in V8 as well.

Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 04/12] soc: samsung: add exynos chipid driver support
@ 2017-04-07 12:18           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 12:18 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 02:43 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Exynos SoCs have Chipid, for identification of product IDs and SoC
>> revisions. This patch intends to provide initialization code for all
>> these functionalities, at the same time it provides some sysfs entries
>> for accessing these information to user-space.
>>
>> This driver uses existing binding for exynos-chipid.
>>
>> CC: Grant Likely <grant.likely@linaro.org>
>> CC: Rob Herring <robh+dt@kernel.org>
>> CC: Linus Walleij <linus.walleij@linaro.org>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> [m.szyprowski: for suggestion and code snippet of product_id_to_soc_id]
>> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> ---
>>  drivers/soc/samsung/Kconfig         |   5 ++
>>  drivers/soc/samsung/Makefile        |   1 +
>>  drivers/soc/samsung/exynos-chipid.c | 109 ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 115 insertions(+)
>>  create mode 100644 drivers/soc/samsung/exynos-chipid.c
>>
>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>> index 8b25bd5..a90a4ad 100644
>> --- a/drivers/soc/samsung/Kconfig
>> +++ b/drivers/soc/samsung/Kconfig
>> @@ -6,6 +6,11 @@ menuconfig SOC_SAMSUNG
>>
>>  if SOC_SAMSUNG
>>
>> +config EXYNOS_CHIPID
>> +       bool "Exynos Chipid controller driver" if COMPILE_TEST
>> +       depends on ARCH_EXYNOS || COMPILE_TEST
>> +       select SOC_BUS
>> +
>>  config EXYNOS_PMU
>>         bool "Exynos PMU controller driver" if COMPILE_TEST
>>         depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
>> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
>> index 4d7694a..be3b6bb 100644
>> --- a/drivers/soc/samsung/Makefile
>> +++ b/drivers/soc/samsung/Makefile
>> @@ -1,3 +1,4 @@
>> +obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
>>  obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
>>
>>  obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
>> diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
>> new file mode 100644
>> index 0000000..1e9fb6b
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-chipid.c
>> @@ -0,0 +1,109 @@
>> +/*
>> + * Copyright (c) 2017 Samsung Electronics Co., Ltd.
>> + *           http://www.samsung.com/
>> + *
>> + * EXYNOS - CHIP ID support
>> + * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/sys_soc.h>
>> +
>> +#define EXYNOS_SUBREV_MASK     (0xF << 4)
>> +#define EXYNOS_MAINREV_MASK    (0xF << 0)
>> +#define EXYNOS_REV_MASK                (EXYNOS_SUBREV_MASK | EXYNOS_MAINREV_MASK)
>> +
>> +static const struct exynos_soc_id {
>> +       const char *name;
>> +       unsigned int id;
>> +       unsigned int mask;
>> +} soc_ids[] = {
>> +       { "EXYNOS3250", 0xE3472000, 0xFFFFF000 },
>> +       { "EXYNOS4210", 0x43210000, 0xFFFFF000 },
>> +       { "EXYNOS4212", 0x43220000, 0xFFFFF000 },
>> +       { "EXYNOS4412", 0xE4412000, 0xFFFFF000 },
>> +       { "EXYNOS5250", 0x43520000, 0xFFFFF000 },
>> +       { "EXYNOS5260", 0xE5260000, 0xFFFFF000 },
>> +       { "EXYNOS5410", 0xE5410000, 0xFFFFF000 },
>> +       { "EXYNOS5420", 0xE5420000, 0xFFFFF000 },
>> +       { "EXYNOS5440", 0xE5440000, 0xFFFFF000 },
>> +       { "EXYNOS5800", 0xE5422000, 0xFFFFF000 },
>> +       { "EXYNOS7420", 0xE7420000, 0xFFFFF000 },
>> +       { "EXYNOS5433", 0xE5433000, 0xFFFFF000 },
>> +};
>> +
>> +static const char * __init product_id_to_soc_id(unsigned int product_id)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
>> +               if ((product_id & soc_ids[i].mask) == soc_ids[i].id)
>> +                       return soc_ids[i].name;
>> +       return "UNKNOWN";
>> +}
>> +
>> +int __init exynos_chipid_early_init(void)
>> +{
>> +       struct soc_device_attribute *soc_dev_attr;
>> +       void __iomem *exynos_chipid_base;
>> +       struct soc_device *soc_dev;
>> +       struct device_node *root;
>> +       struct device_node *np;
>> +       struct device *dev;
>> +       u32 product_id;
>> +       u32 revision;
>> +
>> +       /* look up for chipid node */
>> +       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
>> +       if (!np)
>> +               return -ENODEV;
>> +
>> +       exynos_chipid_base = of_iomap(np, 0);
>> +       of_node_put(np);
>> +
>> +       if (!exynos_chipid_base) {
>> +               pr_err("%s: failed to map chipid\n", np->name);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       product_id = readl_relaxed(exynos_chipid_base);
>> +       revision = product_id & EXYNOS_REV_MASK;
>> +       iounmap(exynos_chipid_base);
>> +
>> +       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
>> +       if (!soc_dev_attr)
>> +               return -ENODEV;
> 
> This should be -ENOMEM
> 
OK. Will take care in next patchset.

>> +
>> +       soc_dev_attr->family = "Samsung Exynos";
>> +
>> +       root = of_find_node_by_path("/");
>> +       of_property_read_string(root, "model", &soc_dev_attr->machine);
>> +       of_node_put(root);
>> +
>> +       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
>> +       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
>> +
>> +       soc_dev = soc_device_register(soc_dev_attr);
>> +       if (IS_ERR(soc_dev)) {
>> +               kfree(soc_dev_attr->revision);
>> +               kfree_const(soc_dev_attr->soc_id);
> 
> This was not allocated with kstrdup_const() so it should not be freed.
> 

Sorry, I missed to take care of this, you pointed out this in V8 as well.

Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 11/12] ARM: EXYNOS: move cpu_restart as a SoC specific hook to exynos_cpu_info
  2017-03-30 13:17       ` Pankaj Dubey
@ 2017-04-07 12:23         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 12:23 UTC (permalink / raw)
  To: Pankaj Dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> To handle differences in cpu_restart functionality among various Exynos SoC
> let's move cpu_restart as a SoC specific function hook to exynos_cpu_info.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index 6f08b15..af9332c 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -39,11 +39,13 @@ extern void exynos4_secondary_startup(void);
>   * @cpu_boot_reg: computes cpu boot address for requested cpu
>   * @cpu_power_down: handles cpu power down routine for requested cpu
>   * @cpu_power_up: handles cpu power up routine for requested cpu
> + * @cpu_restart: handles cpu restart routine for requested cpu
>   */
>  struct exynos_cpu_info {
>         void __iomem* (*cpu_boot_reg)(u32 cpu);
>         void (*cpu_power_down)(u32 cpu);
>         void (*cpu_power_up)(u32 cpu);
> +       void (*cpu_restart)(u32 cpu);
>  };
>
>  static const struct exynos_cpu_info *cpu_info;
> @@ -252,16 +254,19 @@ static inline void __iomem *cpu_boot_reg(int cpu)
>  }
>
>  /*
> - * Set wake up by local power mode and execute software reset for given core.
> - *
> + * exynos_core_restart : restart the specified cpu
> + * @core_id : the cpu to be restarted
>   * Currently this is needed only when booting secondary CPU on Exynos3250.
>   */
>  void exynos_core_restart(u32 core_id)
>  {
> -       u32 val;
> +       if (cpu_info && cpu_info->cpu_restart)
> +               cpu_info->cpu_restart(core_id);
> +}
>
> -       if (!of_machine_is_compatible("samsung,exynos3250"))
> -               return;
> +static void exynos3250_core_restart(u32 core_id)
> +{
> +       u32 val;
>
>         while (!pmu_raw_readl(S5P_PMU_SPARE2))
>                 udelay(10);
> @@ -362,6 +367,7 @@ static const struct exynos_cpu_info exynos3250_cpu_info = {
>         .cpu_boot_reg = exynos_common_cpu_boot_reg,
>         .cpu_power_down = exynos_common_cpu_power_down,
>         .cpu_power_up = exynos3250_cpu_power_up,
> +       .cpu_restart = exynos3250_core_restart,

This is actually not a CPU restart but poking a CPU after power up. It
is called right after enabling power to given CPU but before setting
boot addr. For Exynos3250 in fact we do a restart but before we wait
for bootloader flag and we set local wakeup mode.

Putting this under cpu_restart will be misleading because:
1. I am not sure this is a valid restart method even for Exynos3250
(although it might work because the bootloader flag would be set
anyway).
2. It is called in specific moment.

I think this should not be made generic... or the naming should be
different, like: cpu_post_power_up().

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 11/12] ARM: EXYNOS: move cpu_restart as a SoC specific hook to exynos_cpu_info
@ 2017-04-07 12:23         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 12:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
> To handle differences in cpu_restart functionality among various Exynos SoC
> let's move cpu_restart as a SoC specific function hook to exynos_cpu_info.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> ---
>  arch/arm/mach-exynos/platsmp.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
> index 6f08b15..af9332c 100644
> --- a/arch/arm/mach-exynos/platsmp.c
> +++ b/arch/arm/mach-exynos/platsmp.c
> @@ -39,11 +39,13 @@ extern void exynos4_secondary_startup(void);
>   * @cpu_boot_reg: computes cpu boot address for requested cpu
>   * @cpu_power_down: handles cpu power down routine for requested cpu
>   * @cpu_power_up: handles cpu power up routine for requested cpu
> + * @cpu_restart: handles cpu restart routine for requested cpu
>   */
>  struct exynos_cpu_info {
>         void __iomem* (*cpu_boot_reg)(u32 cpu);
>         void (*cpu_power_down)(u32 cpu);
>         void (*cpu_power_up)(u32 cpu);
> +       void (*cpu_restart)(u32 cpu);
>  };
>
>  static const struct exynos_cpu_info *cpu_info;
> @@ -252,16 +254,19 @@ static inline void __iomem *cpu_boot_reg(int cpu)
>  }
>
>  /*
> - * Set wake up by local power mode and execute software reset for given core.
> - *
> + * exynos_core_restart : restart the specified cpu
> + * @core_id : the cpu to be restarted
>   * Currently this is needed only when booting secondary CPU on Exynos3250.
>   */
>  void exynos_core_restart(u32 core_id)
>  {
> -       u32 val;
> +       if (cpu_info && cpu_info->cpu_restart)
> +               cpu_info->cpu_restart(core_id);
> +}
>
> -       if (!of_machine_is_compatible("samsung,exynos3250"))
> -               return;
> +static void exynos3250_core_restart(u32 core_id)
> +{
> +       u32 val;
>
>         while (!pmu_raw_readl(S5P_PMU_SPARE2))
>                 udelay(10);
> @@ -362,6 +367,7 @@ static const struct exynos_cpu_info exynos3250_cpu_info = {
>         .cpu_boot_reg = exynos_common_cpu_boot_reg,
>         .cpu_power_down = exynos_common_cpu_power_down,
>         .cpu_power_up = exynos3250_cpu_power_up,
> +       .cpu_restart = exynos3250_core_restart,

This is actually not a CPU restart but poking a CPU after power up. It
is called right after enabling power to given CPU but before setting
boot addr. For Exynos3250 in fact we do a restart but before we wait
for bootloader flag and we set local wakeup mode.

Putting this under cpu_restart will be misleading because:
1. I am not sure this is a valid restart method even for Exynos3250
(although it might work because the bootloader flag would be set
anyway).
2. It is called in specific moment.

I think this should not be made generic... or the naming should be
different, like: cpu_post_power_up().

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
  2017-04-07 12:12           ` pankaj.dubey
@ 2017-04-07 12:24             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 12:24 UTC (permalink / raw)
  To: pankaj.dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Fri, Apr 7, 2017 at 2:12 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>
>
> On Friday 07 April 2017 01:54 PM, Krzysztof Kozlowski wrote:
>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
>>> driver, so let's remove/minimize usage of any such helper function usage
>>> from pm.c.
>>>
>>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>> ---
>>>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>>>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>>>  2 files changed, 15 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>>> index 1a7e5b5..4a73b02 100644
>>> --- a/arch/arm/mach-exynos/pm.c
>>> +++ b/arch/arm/mach-exynos/pm.c
>>> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>>>  }
>>>
>>>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
>>> -static void exynos_set_wakeupmask(long mask)
>>> +static void exynos_set_wakeupmask(void)
>>>  {
>>> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
>>> -       if (soc_is_exynos3250())
>>> +       if (of_machine_is_compatible("samsung,exynos3250")) {
>>> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
>>> +       } else
>>> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>
>> You need {} around this too. Checkpatch should complain about it as
>> well so be sure to run it.
>>
>
> I ran checkpatch before posting, but it didn't complain about this. Here
> is the result when I ran it again today on the same patch.
>
> ./scripts/checkpatch.pl
> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
>
> total: 0 errors, 0 warnings, 81 lines checked
>
> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
> has no obvious style problems and is ready for submission.

Ahh, okay, my bad. :)
But anyway please fix it.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
@ 2017-04-07 12:24             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 12:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 7, 2017 at 2:12 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>
>
> On Friday 07 April 2017 01:54 PM, Krzysztof Kozlowski wrote:
>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
>>> driver, so let's remove/minimize usage of any such helper function usage
>>> from pm.c.
>>>
>>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>> ---
>>>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>>>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>>>  2 files changed, 15 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>>> index 1a7e5b5..4a73b02 100644
>>> --- a/arch/arm/mach-exynos/pm.c
>>> +++ b/arch/arm/mach-exynos/pm.c
>>> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>>>  }
>>>
>>>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
>>> -static void exynos_set_wakeupmask(long mask)
>>> +static void exynos_set_wakeupmask(void)
>>>  {
>>> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
>>> -       if (soc_is_exynos3250())
>>> +       if (of_machine_is_compatible("samsung,exynos3250")) {
>>> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
>>> +       } else
>>> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>
>> You need {} around this too. Checkpatch should complain about it as
>> well so be sure to run it.
>>
>
> I ran checkpatch before posting, but it didn't complain about this. Here
> is the result when I ran it again today on the same patch.
>
> ./scripts/checkpatch.pl
> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
>
> total: 0 errors, 0 warnings, 81 lines checked
>
> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
> has no obvious style problems and is ready for submission.

Ahh, okay, my bad. :)
But anyway please fix it.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr,flag} ops to exynos_s2r_data
  2017-04-07 10:32         ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} " Krzysztof Kozlowski
@ 2017-04-07 13:52           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 13:52 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 04:02 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Various Exynos SoC needs different boot addresses and flags. Currently we
>> are handling this difference by adding lots of soc_is_exynosMMM checks in
>> the code, in an attempt to remove the dependency of such helper functions
>> specific to each SoC, let's separate helper functions for these helper
>> functions by moving them into SoC specific hooks in struct exynos_s2r_data.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/pm.c | 60 +++++++++++++++++++++++++++++++++++++++--------
>>  1 file changed, 50 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index fa24098..c3fa537 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -32,26 +32,56 @@
>>  #include "common.h"
>>
>>  struct exynos_s2r_data {
>> +       void __iomem* (*boot_vector_addr)(void);
>> +       void __iomem* (*boot_vector_flag)(void);
>>         void (*enter_aftr)(void);
>>  };
> 
> OK, now I see more uses of this structure so the naming could be
> "exynos_pm_data"?

OK. I will update accordingly.

> 
>>
>>  static const struct exynos_s2r_data *s2r_data;
>>
>> -static inline void __iomem *exynos_boot_vector_addr(void)
>> +static void __iomem *exynos_boot_vector_addr(void)
>> +{
>> +       if (s2r_data && s2r_data->boot_vector_addr)
>> +               return s2r_data->boot_vector_addr();
>> +
>> +       return NULL;
>> +}
>> +
>> +static inline void __iomem *exynos4210_rev11_boot_vector_addr(void)
> 
> Inlines here are mixed up and you are changing them without
> explanation in commit msg. Previously the exynos_boot_vector_addr()
> was inlined, now not. Okay, I can accept that but please mention this
> in commit msg.

OK, let me recheck these inline functions once again.

> But below you are adding new inline functions which are stored as
> pointers in ops. This looks both inconsistent with above and incorrect
> from logical point of view. How would you like to inline them if they
> are referenced through pointer? (okay, compilers are smart and crazy
> so maybe they can do it but anyway I am curious how this would look
> like).

Well I am also wondering what was in my mind when I made them inline and
why I do not get any compilation warning or error?

Just looking for answer, is it OK for inline functions to be used as
function pointers? I can see it is allowed and compilers won't complain
as 'inline' specifier is just hint for compiler and they may or may not
make them inline. Here also as you pointed out probably compilers will
take care and not make them inline.

I further checked with 'nm' command on pm.o file I can see even these
inline marked functions are present in symbol listing so looks they have
not been really inlined by compiler.

I will update this in next patchset.

> 
>> +{
>> +       return pmu_base_addr + S5P_INFORM7;
>> +}
>> +
>> +static inline void __iomem *exynos4210_rev10_boot_vector_addr(void)
>> +{
>> +       return sysram_base_addr + 0x24;
>> +}
>> +
>> +static inline void __iomem *exynos_common_boot_vector_addr(void)
>>  {
>> -       if (samsung_rev() == EXYNOS4210_REV_1_1)
>> -               return pmu_base_addr + S5P_INFORM7;
>> -       else if (samsung_rev() == EXYNOS4210_REV_1_0)
>> -               return sysram_base_addr + 0x24;
>>         return pmu_base_addr + S5P_INFORM0;
>>  }
>>
>> -static inline void __iomem *exynos_boot_vector_flag(void)
>> +static void __iomem *exynos_boot_vector_flag(void)
> 
> ditto for the flag.
> 

This also I will take care in next patchset.

Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} ops to exynos_s2r_data
@ 2017-04-07 13:52           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 13:52 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 04:02 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Various Exynos SoC needs different boot addresses and flags. Currently we
>> are handling this difference by adding lots of soc_is_exynosMMM checks in
>> the code, in an attempt to remove the dependency of such helper functions
>> specific to each SoC, let's separate helper functions for these helper
>> functions by moving them into SoC specific hooks in struct exynos_s2r_data.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/pm.c | 60 +++++++++++++++++++++++++++++++++++++++--------
>>  1 file changed, 50 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index fa24098..c3fa537 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -32,26 +32,56 @@
>>  #include "common.h"
>>
>>  struct exynos_s2r_data {
>> +       void __iomem* (*boot_vector_addr)(void);
>> +       void __iomem* (*boot_vector_flag)(void);
>>         void (*enter_aftr)(void);
>>  };
> 
> OK, now I see more uses of this structure so the naming could be
> "exynos_pm_data"?

OK. I will update accordingly.

> 
>>
>>  static const struct exynos_s2r_data *s2r_data;
>>
>> -static inline void __iomem *exynos_boot_vector_addr(void)
>> +static void __iomem *exynos_boot_vector_addr(void)
>> +{
>> +       if (s2r_data && s2r_data->boot_vector_addr)
>> +               return s2r_data->boot_vector_addr();
>> +
>> +       return NULL;
>> +}
>> +
>> +static inline void __iomem *exynos4210_rev11_boot_vector_addr(void)
> 
> Inlines here are mixed up and you are changing them without
> explanation in commit msg. Previously the exynos_boot_vector_addr()
> was inlined, now not. Okay, I can accept that but please mention this
> in commit msg.

OK, let me recheck these inline functions once again.

> But below you are adding new inline functions which are stored as
> pointers in ops. This looks both inconsistent with above and incorrect
> from logical point of view. How would you like to inline them if they
> are referenced through pointer? (okay, compilers are smart and crazy
> so maybe they can do it but anyway I am curious how this would look
> like).

Well I am also wondering what was in my mind when I made them inline and
why I do not get any compilation warning or error?

Just looking for answer, is it OK for inline functions to be used as
function pointers? I can see it is allowed and compilers won't complain
as 'inline' specifier is just hint for compiler and they may or may not
make them inline. Here also as you pointed out probably compilers will
take care and not make them inline.

I further checked with 'nm' command on pm.o file I can see even these
inline marked functions are present in symbol listing so looks they have
not been really inlined by compiler.

I will update this in next patchset.

> 
>> +{
>> +       return pmu_base_addr + S5P_INFORM7;
>> +}
>> +
>> +static inline void __iomem *exynos4210_rev10_boot_vector_addr(void)
>> +{
>> +       return sysram_base_addr + 0x24;
>> +}
>> +
>> +static inline void __iomem *exynos_common_boot_vector_addr(void)
>>  {
>> -       if (samsung_rev() == EXYNOS4210_REV_1_1)
>> -               return pmu_base_addr + S5P_INFORM7;
>> -       else if (samsung_rev() == EXYNOS4210_REV_1_0)
>> -               return sysram_base_addr + 0x24;
>>         return pmu_base_addr + S5P_INFORM0;
>>  }
>>
>> -static inline void __iomem *exynos_boot_vector_flag(void)
>> +static void __iomem *exynos_boot_vector_flag(void)
> 
> ditto for the flag.
> 

This also I will take care in next patchset.

Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
  2017-04-07 10:41         ` Krzysztof Kozlowski
@ 2017-04-07 14:00           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:00 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 04:11 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Various Exynos SoC has different CPU related information, such as CPU
>> boot register, programming sequence making CPU up/down. Currently this
>> is handled by adding lots of soc_is_exynosMMM checks in the code, in
>> an attempt to remove the dependency of such helper functions specific to
>> each SoC, let's separate this information pertaining to CPU by introducing
>> a new "struct exynos_cpu_info". This struct will contain differences
>> associated with CPU on various Exynos SoC. This can be matched by using
>> generic API "soc_device_match".
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 135 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
>> index cb6d199..ff369b9 100644
>> --- a/arch/arm/mach-exynos/platsmp.c
>> +++ b/arch/arm/mach-exynos/platsmp.c
>> @@ -19,6 +19,7 @@
>>  #include <linux/smp.h>
>>  #include <linux/io.h>
>>  #include <linux/of_address.h>
>> +#include <linux/sys_soc.h>
>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>
>>  #include <asm/cacheflush.h>
>> @@ -33,6 +34,16 @@
>>
>>  extern void exynos4_secondary_startup(void);
>>
>> +/*
>> + * struct exynos_cpu_info - Exynos CPU related info/operations
>> + * @cpu_boot_reg: computes cpu boot address for requested cpu
>> + */
>> +struct exynos_cpu_info {
>> +       void __iomem* (*cpu_boot_reg)(u32 cpu);
>> +};
> 
> Beside Marek comments, I think we are getting too many structures for
> differentiating Exynos. Actually all of them describe the same -
> difference between Exynos revisions. Having many separate structures
> means that you have to initialize all of them in different places in
> different (probably) order. The good benefit is however making them
> local (static) so the scope is limited... but anyway I dislike the
> duplication.
> 

OK, regarding duplication, only the way they are initialized is getting
duplicated. But again, my long term goal was to remove dependency of
pm.c and suspend.c from arm/mach-exynos/{exynos.c,platsmp.c} or common.h
in mach-exynos. So that we could move these files as a Exynos Power
Management driver in drivers/soc/ where we already moved pm_domain.c, as
you see these three files pm.c, suspend.c and pm_domain.c are heavily
dependent on PMU driver, and handles Power Management states.

So I feel keeping CPU specific data separate from PM specific data makes
sense and will help in moving these files as a platform driver one day?

Surely I will work out and see how I can minimize duplication.


Thanks,
Pankaj Dubey

> How about combining all of them into one (except the firmware which
> has its own register function):
> 
> struct exynos_revision_data {
> void __iomem* (*boot_vector_addr)(void);
> void __iomem* (*boot_vector_flag)(void);
> void (*enter_aftr)(void);
> void __iomem* (*cpu_boot_reg)(u32 cpu);
> void (*cpu_power_down)(u32 cpu);
> void (*cpu_power_up)(u32 cpu);
> };
> 
> Best regards,
> Krzysztof
> 
> 
>> +
>> +static const struct exynos_cpu_info *cpu_info;
>> +
>>  #ifdef CONFIG_HOTPLUG_CPU
>>  static inline void cpu_leave_lowpower(u32 core_id)
>>  {
>> @@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
>>                 S5P_CORE_LOCAL_PWR_EN);
>>  }
>>
>> -static void __iomem *cpu_boot_reg_base(void)
>> +static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
>>  {
>> -       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
>> -               return pmu_base_addr + S5P_INFORM5;
>> -       return sysram_base_addr;
>> +       void __iomem *boot_reg = pmu_base_addr;
>> +
>> +       if (!boot_reg)
>> +               return IOMEM_ERR_PTR(-ENODEV);
>> +
>> +       boot_reg += S5P_INFORM5;
>> +
>> +       return boot_reg;
>>  }
>>
>> -static inline void __iomem *cpu_boot_reg(int cpu)
>> +static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
>>  {
>> -       void __iomem *boot_reg;
>> +       void __iomem *boot_reg = sysram_base_addr;
>>
>> -       boot_reg = cpu_boot_reg_base();
>>         if (!boot_reg)
>>                 return IOMEM_ERR_PTR(-ENODEV);
>> -       if (soc_is_exynos4412())
>> -               boot_reg += 4*cpu;
>> -       else if (soc_is_exynos5420() || soc_is_exynos5800())
>> -               boot_reg += 4;
>> +
>> +       boot_reg += 4*cpu;
>> +
>>         return boot_reg;
>>  }
>>
>> +static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
>> +{
>> +       void __iomem *boot_reg = sysram_base_addr;
>> +
>> +       if (!sysram_base_addr)
>> +               return IOMEM_ERR_PTR(-ENODEV);
>> +
>> +       boot_reg += 4;
>> +
>> +       return boot_reg;
>> +}
>> +
>> +static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
>> +{
>> +       if (!sysram_base_addr)
>> +               return IOMEM_ERR_PTR(-ENODEV);
>> +
>> +       return sysram_base_addr;
>> +}
>> +
>> +static inline void __iomem *cpu_boot_reg(int cpu)
>> +{
>> +       if (cpu_info && cpu_info->cpu_boot_reg)
>> +               return cpu_info->cpu_boot_reg(cpu);
>> +       return NULL;
>> +}
>> +
>>  /*
>>   * Set wake up by local power mode and execute software reset for given core.
>>   *
>> @@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
>>         return ret;
>>  }
>>
>> +static const struct exynos_cpu_info exynos3250_cpu_info = {
>> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos5420_cpu_info = {
>> +       .cpu_boot_reg = exynos5420_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
>> +       .cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos4412_cpu_info = {
>> +       .cpu_boot_reg = exynos4412_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos_common_cpu_info = {
>> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
>> +};
>> +
>> +static const struct soc_device_attribute exynos_soc_revision[] = {
>> +       {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "11",
>> +               .data = &exynos4210_rev11_cpu_info
>> +       }, {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "10",
>> +               .data = &exynos_common_cpu_info
>> +       }
>> +};
>> +
>> +static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
>> +       {
>> +               .compatible = "samsung,exynos3250",
>> +               .data = &exynos3250_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos4212",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos4412",
>> +               .data = &exynos4412_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5250",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5260",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5410",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5420",
>> +               .data = &exynos5420_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5440",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5800",
>> +               .data = &exynos5420_cpu_info
>> +       },
>> +       { /*sentinel*/ },
>> +};
>> +
>>  static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>>  {
>>         unsigned long timeout;
>> +       const struct soc_device_attribute *match;
>>         u32 mpidr = cpu_logical_map(cpu);
>>         u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>>         int ret = -ENOSYS;
>>
>> +       if (of_machine_is_compatible("samsung,exynos4210")) {
>> +               match = soc_device_match(exynos_soc_revision);
>> +               if (match)
>> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
>> +       }
>> +
>>         /*
>>          * Set synchronisation state between this boot processor
>>          * and the secondary one
>> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>>
>>  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>>  {
>> +       const struct of_device_id *match;
>> +       struct device_node *np;
>> +
>> +       if (!of_machine_is_compatible("samsung,exynos4210")) {
>> +               np = of_find_matching_node_and_match(NULL,
>> +                               exynos_pmu_of_device_ids, &match);
>> +               if (!np)
>> +                       pr_err("failed to find supported CPU\n");
>> +               else
>> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
>> +       }
>> +
>>         exynos_sysram_init();
>>
>>         exynos_set_delayed_reset_assertion(true);
>> --
>> 2.7.4
>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-04-07 14:00           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:00 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 04:11 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Various Exynos SoC has different CPU related information, such as CPU
>> boot register, programming sequence making CPU up/down. Currently this
>> is handled by adding lots of soc_is_exynosMMM checks in the code, in
>> an attempt to remove the dependency of such helper functions specific to
>> each SoC, let's separate this information pertaining to CPU by introducing
>> a new "struct exynos_cpu_info". This struct will contain differences
>> associated with CPU on various Exynos SoC. This can be matched by using
>> generic API "soc_device_match".
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 135 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
>> index cb6d199..ff369b9 100644
>> --- a/arch/arm/mach-exynos/platsmp.c
>> +++ b/arch/arm/mach-exynos/platsmp.c
>> @@ -19,6 +19,7 @@
>>  #include <linux/smp.h>
>>  #include <linux/io.h>
>>  #include <linux/of_address.h>
>> +#include <linux/sys_soc.h>
>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>
>>  #include <asm/cacheflush.h>
>> @@ -33,6 +34,16 @@
>>
>>  extern void exynos4_secondary_startup(void);
>>
>> +/*
>> + * struct exynos_cpu_info - Exynos CPU related info/operations
>> + * @cpu_boot_reg: computes cpu boot address for requested cpu
>> + */
>> +struct exynos_cpu_info {
>> +       void __iomem* (*cpu_boot_reg)(u32 cpu);
>> +};
> 
> Beside Marek comments, I think we are getting too many structures for
> differentiating Exynos. Actually all of them describe the same -
> difference between Exynos revisions. Having many separate structures
> means that you have to initialize all of them in different places in
> different (probably) order. The good benefit is however making them
> local (static) so the scope is limited... but anyway I dislike the
> duplication.
> 

OK, regarding duplication, only the way they are initialized is getting
duplicated. But again, my long term goal was to remove dependency of
pm.c and suspend.c from arm/mach-exynos/{exynos.c,platsmp.c} or common.h
in mach-exynos. So that we could move these files as a Exynos Power
Management driver in drivers/soc/ where we already moved pm_domain.c, as
you see these three files pm.c, suspend.c and pm_domain.c are heavily
dependent on PMU driver, and handles Power Management states.

So I feel keeping CPU specific data separate from PM specific data makes
sense and will help in moving these files as a platform driver one day?

Surely I will work out and see how I can minimize duplication.


Thanks,
Pankaj Dubey

> How about combining all of them into one (except the firmware which
> has its own register function):
> 
> struct exynos_revision_data {
> void __iomem* (*boot_vector_addr)(void);
> void __iomem* (*boot_vector_flag)(void);
> void (*enter_aftr)(void);
> void __iomem* (*cpu_boot_reg)(u32 cpu);
> void (*cpu_power_down)(u32 cpu);
> void (*cpu_power_up)(u32 cpu);
> };
> 
> Best regards,
> Krzysztof
> 
> 
>> +
>> +static const struct exynos_cpu_info *cpu_info;
>> +
>>  #ifdef CONFIG_HOTPLUG_CPU
>>  static inline void cpu_leave_lowpower(u32 core_id)
>>  {
>> @@ -168,27 +179,57 @@ int exynos_cluster_power_state(int cluster)
>>                 S5P_CORE_LOCAL_PWR_EN);
>>  }
>>
>> -static void __iomem *cpu_boot_reg_base(void)
>> +static void __iomem *exynos4210_rev11_cpu_boot_reg(u32 cpu)
>>  {
>> -       if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
>> -               return pmu_base_addr + S5P_INFORM5;
>> -       return sysram_base_addr;
>> +       void __iomem *boot_reg = pmu_base_addr;
>> +
>> +       if (!boot_reg)
>> +               return IOMEM_ERR_PTR(-ENODEV);
>> +
>> +       boot_reg += S5P_INFORM5;
>> +
>> +       return boot_reg;
>>  }
>>
>> -static inline void __iomem *cpu_boot_reg(int cpu)
>> +static void __iomem *exynos4412_cpu_boot_reg(u32 cpu)
>>  {
>> -       void __iomem *boot_reg;
>> +       void __iomem *boot_reg = sysram_base_addr;
>>
>> -       boot_reg = cpu_boot_reg_base();
>>         if (!boot_reg)
>>                 return IOMEM_ERR_PTR(-ENODEV);
>> -       if (soc_is_exynos4412())
>> -               boot_reg += 4*cpu;
>> -       else if (soc_is_exynos5420() || soc_is_exynos5800())
>> -               boot_reg += 4;
>> +
>> +       boot_reg += 4*cpu;
>> +
>>         return boot_reg;
>>  }
>>
>> +static void __iomem *exynos5420_cpu_boot_reg(u32 cpu)
>> +{
>> +       void __iomem *boot_reg = sysram_base_addr;
>> +
>> +       if (!sysram_base_addr)
>> +               return IOMEM_ERR_PTR(-ENODEV);
>> +
>> +       boot_reg += 4;
>> +
>> +       return boot_reg;
>> +}
>> +
>> +static void __iomem *exynos_common_cpu_boot_reg(u32 cpu)
>> +{
>> +       if (!sysram_base_addr)
>> +               return IOMEM_ERR_PTR(-ENODEV);
>> +
>> +       return sysram_base_addr;
>> +}
>> +
>> +static inline void __iomem *cpu_boot_reg(int cpu)
>> +{
>> +       if (cpu_info && cpu_info->cpu_boot_reg)
>> +               return cpu_info->cpu_boot_reg(cpu);
>> +       return NULL;
>> +}
>> +
>>  /*
>>   * Set wake up by local power mode and execute software reset for given core.
>>   *
>> @@ -296,13 +337,84 @@ int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
>>         return ret;
>>  }
>>
>> +static const struct exynos_cpu_info exynos3250_cpu_info = {
>> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos5420_cpu_info = {
>> +       .cpu_boot_reg = exynos5420_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos4210_rev11_cpu_info = {
>> +       .cpu_boot_reg = exynos4210_rev11_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos4412_cpu_info = {
>> +       .cpu_boot_reg = exynos4412_cpu_boot_reg,
>> +};
>> +
>> +static const struct exynos_cpu_info exynos_common_cpu_info = {
>> +       .cpu_boot_reg = exynos_common_cpu_boot_reg,
>> +};
>> +
>> +static const struct soc_device_attribute exynos_soc_revision[] = {
>> +       {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "11",
>> +               .data = &exynos4210_rev11_cpu_info
>> +       }, {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "10",
>> +               .data = &exynos_common_cpu_info
>> +       }
>> +};
>> +
>> +static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = {
>> +       {
>> +               .compatible = "samsung,exynos3250",
>> +               .data = &exynos3250_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos4212",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos4412",
>> +               .data = &exynos4412_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5250",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5260",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5410",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5420",
>> +               .data = &exynos5420_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5440",
>> +               .data = &exynos_common_cpu_info
>> +       }, {
>> +               .compatible = "samsung,exynos5800",
>> +               .data = &exynos5420_cpu_info
>> +       },
>> +       { /*sentinel*/ },
>> +};
>> +
>>  static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>>  {
>>         unsigned long timeout;
>> +       const struct soc_device_attribute *match;
>>         u32 mpidr = cpu_logical_map(cpu);
>>         u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>>         int ret = -ENOSYS;
>>
>> +       if (of_machine_is_compatible("samsung,exynos4210")) {
>> +               match = soc_device_match(exynos_soc_revision);
>> +               if (match)
>> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
>> +       }
>> +
>>         /*
>>          * Set synchronisation state between this boot processor
>>          * and the secondary one
>> @@ -387,6 +499,18 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
>>
>>  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
>>  {
>> +       const struct of_device_id *match;
>> +       struct device_node *np;
>> +
>> +       if (!of_machine_is_compatible("samsung,exynos4210")) {
>> +               np = of_find_matching_node_and_match(NULL,
>> +                               exynos_pmu_of_device_ids, &match);
>> +               if (!np)
>> +                       pr_err("failed to find supported CPU\n");
>> +               else
>> +                       cpu_info = (const struct exynos_cpu_info *) match->data;
>> +       }
>> +
>>         exynos_sysram_init();
>>
>>         exynos_set_delayed_reset_assertion(true);
>> --
>> 2.7.4
>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
  2017-04-07  9:24         ` Krzysztof Kozlowski
@ 2017-04-07 14:11           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:11 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 02:54 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> For s2r various Exynos SoC needs different programming sequence and data.
> 
> This is not S2R so:
> "Sleep modes on various Exynos SoCs need..."

OK.
> 
>> Currently this is handled by adding lots of soc_is_exynosMMM checks in the
>> code, in an attempt to remove the dependency of such helper functions
> "code." full stop.
> 
>> specific to each SoC, let's separate these programming sequence by
>> introducing a new struct exynos_s2r_data. This struct will contain
> 
> If you plan to extend it to all sleep modes, then:
> "exynos_sleep_data"? But if not, then just "exynos_aftr_data" or
> "exynos_cpuidle_data" as this is real use for now.

As you suggested in patch 08/12, I will use exynos_pm_data.

> 
>> different function hooks and data for differentiating these programming
>> sequences based on SoC's soc_id and revision parameters which can be
>> matched by using generic API "soc_device_match".
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/pm.c | 122 +++++++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 116 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index 4a73b02..fa24098 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/of.h>
>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>  #include <linux/soc/samsung/exynos-pmu.h>
>> +#include <linux/sys_soc.h>
>>
>>  #include <asm/firmware.h>
>>  #include <asm/smp_scu.h>
>> @@ -30,6 +31,12 @@
>>
>>  #include "common.h"
>>
>> +struct exynos_s2r_data {
> 
> Rename all "s2r" occurrences to appropriate name.

OK.

> 
>> +       void (*enter_aftr)(void);
>> +};
>> +
>> +static const struct exynos_s2r_data *s2r_data;
>> +
>>  static inline void __iomem *exynos_boot_vector_addr(void)
>>  {
>>         if (samsung_rev() == EXYNOS4210_REV_1_1)
>> @@ -160,13 +167,26 @@ static int exynos_aftr_finisher(unsigned long flags)
>>
>>  void exynos_enter_aftr(void)
>>  {
>> +       if (s2r_data && s2r_data->enter_aftr)
>> +               s2r_data->enter_aftr();
>> +}
>> +
>> +static void exynos3_enter_aftr(void)
>> +{
>>         unsigned int cpuid = smp_processor_id();
>>
>>         cpu_pm_enter();
>> +       exynos_set_boot_flag(cpuid, C2_STATE);
>> +       exynos_pm_central_suspend();
>> +       cpu_suspend(0, exynos_aftr_finisher);
>> +       exynos_pm_central_resume();
>> +       exynos_clear_boot_flag(cpuid, C2_STATE);
>> +       cpu_pm_exit();
>> +}
>>
>> -       if (of_machine_is_compatible("samsung,exynos3250"))
>> -               exynos_set_boot_flag(cpuid, C2_STATE);
>> -
>> +static void exynos4_enter_aftr(void)
>> +{
>> +       cpu_pm_enter();
>>         exynos_pm_central_suspend();
>>
>>         if (of_machine_is_compatible("samsung,exynos4212") ||
>> @@ -185,13 +205,103 @@ void exynos_enter_aftr(void)
>>         }
>>
>>         exynos_pm_central_resume();
>> +       cpu_pm_exit();
>> +}
>>
>> -       if (of_machine_is_compatible("samsung,exynos3250"))
>> -               exynos_clear_boot_flag(cpuid, C2_STATE);
>> -
>> +static void exynos5_enter_aftr(void)
>> +{
>> +       cpu_pm_enter();
>> +       exynos_pm_central_suspend();
>> +       cpu_suspend(0, exynos_aftr_finisher);
>> +       exynos_pm_central_resume();
>>         cpu_pm_exit();
>>  }
>>
>> +static const struct exynos_s2r_data exynos_common_s2r_data = {
>> +       .enter_aftr             = exynos5_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos3250_s2r_data = {
>> +       .enter_aftr             = exynos3_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
>> +       .enter_aftr             = exynos4_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
>> +       .enter_aftr             = exynos4_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos4x12_s2r_data = {
>> +       .enter_aftr             = exynos4_enter_aftr,
>> +};
>> +
>> +static const struct soc_device_attribute exynos_soc_revision[] __initconst = {
>> +       {
>> +               .soc_id = "EXYNOS3250",
>> +               .data = &exynos3250_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "11",
>> +               .data = &exynos4210_rev11_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "10",
>> +               .data = &exynos4210_rev10_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4212",
>> +               .data = &exynos4x12_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4412",
>> +               .data = &exynos4x12_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5250",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5260",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5440",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5410",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5420",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5800",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +};
>> +
>> +int __init exynos_s2r_init(void)
>> +{
>> +       const struct soc_device_attribute *match;
>> +
>> +       match = soc_device_match(exynos_soc_revision);
>> +
>> +       if (match)
>> +               s2r_data = (const struct exynos_s2r_data *) match->data;
>> +
>> +       if (!s2r_data)
>> +               return -ENODEV;
>> +
>> +       return 0;
>> +}
>> +arch_initcall(exynos_s2r_init);
>> +
> 
> I guess you already found possible probe-order issue. You should
> register all of this after having the soc chipid driver. However it is
> required by cpuidle driver which is being registered in machine_init()
> call....  You cannot use deferred probe here, so maybe the only way is
> to manually order the calls in machine_init():
> 1. exynos_chipid_early_init()
> 2. this one.
> 3. cpuidle driver register.
> 

exynos_s2r_init is not required during early stage of boot, so as Arnd
suggested I can drop arch_initcall here and probably go for

1: late_init
2: Call this directly from machine_init

I prefer first option, as I mentioned my long term plan to move these
files out of arch/arm/mach-exynos/ and if I call it from mach-exynos,
then while moving I have to make this function as export symbol or make
it extern so that mach-exynos/exynos.c should be able to access it. Both
of these approaches have been rejected in past. What do you say?


Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
@ 2017-04-07 14:11           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:11 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 02:54 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> For s2r various Exynos SoC needs different programming sequence and data.
> 
> This is not S2R so:
> "Sleep modes on various Exynos SoCs need..."

OK.
> 
>> Currently this is handled by adding lots of soc_is_exynosMMM checks in the
>> code, in an attempt to remove the dependency of such helper functions
> "code." full stop.
> 
>> specific to each SoC, let's separate these programming sequence by
>> introducing a new struct exynos_s2r_data. This struct will contain
> 
> If you plan to extend it to all sleep modes, then:
> "exynos_sleep_data"? But if not, then just "exynos_aftr_data" or
> "exynos_cpuidle_data" as this is real use for now.

As you suggested in patch 08/12, I will use exynos_pm_data.

> 
>> different function hooks and data for differentiating these programming
>> sequences based on SoC's soc_id and revision parameters which can be
>> matched by using generic API "soc_device_match".
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/pm.c | 122 +++++++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 116 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>> index 4a73b02..fa24098 100644
>> --- a/arch/arm/mach-exynos/pm.c
>> +++ b/arch/arm/mach-exynos/pm.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/of.h>
>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>  #include <linux/soc/samsung/exynos-pmu.h>
>> +#include <linux/sys_soc.h>
>>
>>  #include <asm/firmware.h>
>>  #include <asm/smp_scu.h>
>> @@ -30,6 +31,12 @@
>>
>>  #include "common.h"
>>
>> +struct exynos_s2r_data {
> 
> Rename all "s2r" occurrences to appropriate name.

OK.

> 
>> +       void (*enter_aftr)(void);
>> +};
>> +
>> +static const struct exynos_s2r_data *s2r_data;
>> +
>>  static inline void __iomem *exynos_boot_vector_addr(void)
>>  {
>>         if (samsung_rev() == EXYNOS4210_REV_1_1)
>> @@ -160,13 +167,26 @@ static int exynos_aftr_finisher(unsigned long flags)
>>
>>  void exynos_enter_aftr(void)
>>  {
>> +       if (s2r_data && s2r_data->enter_aftr)
>> +               s2r_data->enter_aftr();
>> +}
>> +
>> +static void exynos3_enter_aftr(void)
>> +{
>>         unsigned int cpuid = smp_processor_id();
>>
>>         cpu_pm_enter();
>> +       exynos_set_boot_flag(cpuid, C2_STATE);
>> +       exynos_pm_central_suspend();
>> +       cpu_suspend(0, exynos_aftr_finisher);
>> +       exynos_pm_central_resume();
>> +       exynos_clear_boot_flag(cpuid, C2_STATE);
>> +       cpu_pm_exit();
>> +}
>>
>> -       if (of_machine_is_compatible("samsung,exynos3250"))
>> -               exynos_set_boot_flag(cpuid, C2_STATE);
>> -
>> +static void exynos4_enter_aftr(void)
>> +{
>> +       cpu_pm_enter();
>>         exynos_pm_central_suspend();
>>
>>         if (of_machine_is_compatible("samsung,exynos4212") ||
>> @@ -185,13 +205,103 @@ void exynos_enter_aftr(void)
>>         }
>>
>>         exynos_pm_central_resume();
>> +       cpu_pm_exit();
>> +}
>>
>> -       if (of_machine_is_compatible("samsung,exynos3250"))
>> -               exynos_clear_boot_flag(cpuid, C2_STATE);
>> -
>> +static void exynos5_enter_aftr(void)
>> +{
>> +       cpu_pm_enter();
>> +       exynos_pm_central_suspend();
>> +       cpu_suspend(0, exynos_aftr_finisher);
>> +       exynos_pm_central_resume();
>>         cpu_pm_exit();
>>  }
>>
>> +static const struct exynos_s2r_data exynos_common_s2r_data = {
>> +       .enter_aftr             = exynos5_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos3250_s2r_data = {
>> +       .enter_aftr             = exynos3_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos4210_rev11_s2r_data = {
>> +       .enter_aftr             = exynos4_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos4210_rev10_s2r_data = {
>> +       .enter_aftr             = exynos4_enter_aftr,
>> +};
>> +
>> +static const struct exynos_s2r_data exynos4x12_s2r_data = {
>> +       .enter_aftr             = exynos4_enter_aftr,
>> +};
>> +
>> +static const struct soc_device_attribute exynos_soc_revision[] __initconst = {
>> +       {
>> +               .soc_id = "EXYNOS3250",
>> +               .data = &exynos3250_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "11",
>> +               .data = &exynos4210_rev11_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4210",
>> +               .revision = "10",
>> +               .data = &exynos4210_rev10_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4212",
>> +               .data = &exynos4x12_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS4412",
>> +               .data = &exynos4x12_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5250",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5260",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5440",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5410",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5420",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +       {
>> +               .soc_id = "EXYNOS5800",
>> +               .data = &exynos_common_s2r_data
>> +       },
>> +};
>> +
>> +int __init exynos_s2r_init(void)
>> +{
>> +       const struct soc_device_attribute *match;
>> +
>> +       match = soc_device_match(exynos_soc_revision);
>> +
>> +       if (match)
>> +               s2r_data = (const struct exynos_s2r_data *) match->data;
>> +
>> +       if (!s2r_data)
>> +               return -ENODEV;
>> +
>> +       return 0;
>> +}
>> +arch_initcall(exynos_s2r_init);
>> +
> 
> I guess you already found possible probe-order issue. You should
> register all of this after having the soc chipid driver. However it is
> required by cpuidle driver which is being registered in machine_init()
> call....  You cannot use deferred probe here, so maybe the only way is
> to manually order the calls in machine_init():
> 1. exynos_chipid_early_init()
> 2. this one.
> 3. cpuidle driver register.
> 

exynos_s2r_init is not required during early stage of boot, so as Arnd
suggested I can drop arch_initcall here and probably go for

1: late_init
2: Call this directly from machine_init

I prefer first option, as I mentioned my long term plan to move these
files out of arch/arm/mach-exynos/ and if I call it from mach-exynos,
then while moving I have to make this function as export symbol or make
it extern so that mach-exynos/exynos.c should be able to access it. Both
of these approaches have been rejected in past. What do you say?


Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
  2017-04-07 12:04         ` Krzysztof Kozlowski
@ 2017-04-07 14:12           ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:12 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 05:34 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Various Exynos SoC handles CPU power_up and power_down operation
>> differently. To handle this difference until now we were using
>> soc_is_exynosMMM helper functions, in an attempt to remove the dependency
>> of such helper functions specific to each SoC, let's move power_{down,up}
>> functionality as a SoC specific function pointer hooks in
>> struct exynos_cpu_info.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/platsmp.c | 61 +++++++++++++++++++++++++++++++-----------
>>  1 file changed, 46 insertions(+), 15 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
>> index ff369b9..6f08b15 100644
>> --- a/arch/arm/mach-exynos/platsmp.c
>> +++ b/arch/arm/mach-exynos/platsmp.c
>> @@ -37,9 +37,13 @@ extern void exynos4_secondary_startup(void);
>>  /*
>>   * struct exynos_cpu_info - Exynos CPU related info/operations
>>   * @cpu_boot_reg: computes cpu boot address for requested cpu
>> + * @cpu_power_down: handles cpu power down routine for requested cpu
>> + * @cpu_power_up: handles cpu power up routine for requested cpu
>>   */
>>  struct exynos_cpu_info {
>>         void __iomem* (*cpu_boot_reg)(u32 cpu);
>> +       void (*cpu_power_down)(u32 cpu);
>> +       void (*cpu_power_up)(u32 cpu);
>>  };
>>
>>  static const struct exynos_cpu_info *cpu_info;
>> @@ -92,19 +96,29 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
>>  }
>>  #endif /* CONFIG_HOTPLUG_CPU */
>>
>> -/**
>> - * exynos_core_power_down : power down the specified cpu
>> +/*
>> + * exynos_core_power_down - power down the specified cpu
>>   * @cpu : the cpu to power down
>> - *
>> - * Power down the specified cpu. The sequence must be finished by a
>> - * call to cpu_do_idle()
>> - *
>> + * The sequence must be finished by a call to cpu_do_idle()
>>   */
>>  void exynos_cpu_power_down(int cpu)
>>  {
>> +       if (cpu_info && cpu_info->cpu_power_down)
>> +               cpu_info->cpu_power_down(cpu);
>> +}
>> +
>> +static void exynos_common_cpu_power_down(u32 cpu)
>> +{
>>         u32 core_conf;
>>
>> -       if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
>> +       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
>> +       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +}
>> +
>> +static void exynos5420_cpu_power_down(u32 cpu)
>> +{
>> +       if (cpu == 0) {
>>                 /*
>>                  * Bypass power down for CPU0 during suspend. Check for
>>                  * the SYS_PWR_REG value to decide if we are suspending
>> @@ -116,24 +130,31 @@ void exynos_cpu_power_down(int cpu)
>>                         return;
>>         }
>>
>> -       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> -       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
>> -       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +       exynos_common_cpu_power_down(cpu);
>>  }
>>
>> -/**
>> +/*
>>   * exynos_cpu_power_up : power up the specified cpu
>>   * @cpu : the cpu to power up
>> - *
>> - * Power up the specified cpu
>>   */
>>  void exynos_cpu_power_up(int cpu)
>>  {
>> +       if (cpu_info && cpu_info->cpu_power_up)
>> +               cpu_info->cpu_power_up(cpu);
>> +}
>> +
>> +static void exynos_common_cpu_power_up(u32 cpu)
>> +{
>>         u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>> +       pmu_raw_writel(core_conf,
>> +                       EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +}
>>
>> -       if (soc_is_exynos3250())
>> -               core_conf |= S5P_CORE_AUTOWAKEUP_EN;
>> +static void exynos3250_cpu_power_up(u32 cpu)
>> +{
>> +       u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>>
>> +       core_conf |= S5P_CORE_AUTOWAKEUP_EN;
> 
> Maybe just:
>         core_conf = S5P_CORE_LOCAL_PWR_EN \
>                            | S5P_CORE_AUTOWAKEUP_EN;
> ?

OK, it can be done.

Thanks,
Pankaj Dubey
> 
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info
@ 2017-04-07 14:12           ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:12 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 05:34 PM, Krzysztof Kozlowski wrote:
> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>> Various Exynos SoC handles CPU power_up and power_down operation
>> differently. To handle this difference until now we were using
>> soc_is_exynosMMM helper functions, in an attempt to remove the dependency
>> of such helper functions specific to each SoC, let's move power_{down,up}
>> functionality as a SoC specific function pointer hooks in
>> struct exynos_cpu_info.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>> ---
>>  arch/arm/mach-exynos/platsmp.c | 61 +++++++++++++++++++++++++++++++-----------
>>  1 file changed, 46 insertions(+), 15 deletions(-)
>>
>> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
>> index ff369b9..6f08b15 100644
>> --- a/arch/arm/mach-exynos/platsmp.c
>> +++ b/arch/arm/mach-exynos/platsmp.c
>> @@ -37,9 +37,13 @@ extern void exynos4_secondary_startup(void);
>>  /*
>>   * struct exynos_cpu_info - Exynos CPU related info/operations
>>   * @cpu_boot_reg: computes cpu boot address for requested cpu
>> + * @cpu_power_down: handles cpu power down routine for requested cpu
>> + * @cpu_power_up: handles cpu power up routine for requested cpu
>>   */
>>  struct exynos_cpu_info {
>>         void __iomem* (*cpu_boot_reg)(u32 cpu);
>> +       void (*cpu_power_down)(u32 cpu);
>> +       void (*cpu_power_up)(u32 cpu);
>>  };
>>
>>  static const struct exynos_cpu_info *cpu_info;
>> @@ -92,19 +96,29 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
>>  }
>>  #endif /* CONFIG_HOTPLUG_CPU */
>>
>> -/**
>> - * exynos_core_power_down : power down the specified cpu
>> +/*
>> + * exynos_core_power_down - power down the specified cpu
>>   * @cpu : the cpu to power down
>> - *
>> - * Power down the specified cpu. The sequence must be finished by a
>> - * call to cpu_do_idle()
>> - *
>> + * The sequence must be finished by a call to cpu_do_idle()
>>   */
>>  void exynos_cpu_power_down(int cpu)
>>  {
>> +       if (cpu_info && cpu_info->cpu_power_down)
>> +               cpu_info->cpu_power_down(cpu);
>> +}
>> +
>> +static void exynos_common_cpu_power_down(u32 cpu)
>> +{
>>         u32 core_conf;
>>
>> -       if (cpu == 0 && (soc_is_exynos5420() || soc_is_exynos5800())) {
>> +       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
>> +       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +}
>> +
>> +static void exynos5420_cpu_power_down(u32 cpu)
>> +{
>> +       if (cpu == 0) {
>>                 /*
>>                  * Bypass power down for CPU0 during suspend. Check for
>>                  * the SYS_PWR_REG value to decide if we are suspending
>> @@ -116,24 +130,31 @@ void exynos_cpu_power_down(int cpu)
>>                         return;
>>         }
>>
>> -       core_conf = pmu_raw_readl(EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> -       core_conf &= ~S5P_CORE_LOCAL_PWR_EN;
>> -       pmu_raw_writel(core_conf, EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +       exynos_common_cpu_power_down(cpu);
>>  }
>>
>> -/**
>> +/*
>>   * exynos_cpu_power_up : power up the specified cpu
>>   * @cpu : the cpu to power up
>> - *
>> - * Power up the specified cpu
>>   */
>>  void exynos_cpu_power_up(int cpu)
>>  {
>> +       if (cpu_info && cpu_info->cpu_power_up)
>> +               cpu_info->cpu_power_up(cpu);
>> +}
>> +
>> +static void exynos_common_cpu_power_up(u32 cpu)
>> +{
>>         u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>> +       pmu_raw_writel(core_conf,
>> +                       EXYNOS_ARM_CORE_CONFIGURATION(cpu));
>> +}
>>
>> -       if (soc_is_exynos3250())
>> -               core_conf |= S5P_CORE_AUTOWAKEUP_EN;
>> +static void exynos3250_cpu_power_up(u32 cpu)
>> +{
>> +       u32 core_conf = S5P_CORE_LOCAL_PWR_EN;
>>
>> +       core_conf |= S5P_CORE_AUTOWAKEUP_EN;
> 
> Maybe just:
>         core_conf = S5P_CORE_LOCAL_PWR_EN \
>                            | S5P_CORE_AUTOWAKEUP_EN;
> ?

OK, it can be done.

Thanks,
Pankaj Dubey
> 
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
  2017-04-07 12:24             ` Krzysztof Kozlowski
@ 2017-04-07 14:13               ` pankaj.dubey
  -1 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:13 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas



On Friday 07 April 2017 05:54 PM, Krzysztof Kozlowski wrote:
> On Fri, Apr 7, 2017 at 2:12 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>>
>>
>> On Friday 07 April 2017 01:54 PM, Krzysztof Kozlowski wrote:
>>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
>>>> driver, so let's remove/minimize usage of any such helper function usage
>>>> from pm.c.
>>>>
>>>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>>> ---
>>>>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>>>>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>>>>  2 files changed, 15 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>>>> index 1a7e5b5..4a73b02 100644
>>>> --- a/arch/arm/mach-exynos/pm.c
>>>> +++ b/arch/arm/mach-exynos/pm.c
>>>> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>>>>  }
>>>>
>>>>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
>>>> -static void exynos_set_wakeupmask(long mask)
>>>> +static void exynos_set_wakeupmask(void)
>>>>  {
>>>> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
>>>> -       if (soc_is_exynos3250())
>>>> +       if (of_machine_is_compatible("samsung,exynos3250")) {
>>>> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>>>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
>>>> +       } else
>>>> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>>
>>> You need {} around this too. Checkpatch should complain about it as
>>> well so be sure to run it.
>>>
>>
>> I ran checkpatch before posting, but it didn't complain about this. Here
>> is the result when I ran it again today on the same patch.
>>
>> ./scripts/checkpatch.pl
>> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
>>
>> total: 0 errors, 0 warnings, 81 lines checked
>>
>> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
>> has no obvious style problems and is ready for submission.
> 
> Ahh, okay, my bad. :)
> But anyway please fix it.

OK will take care in next patchset.

Thanks,
Pankaj Dubey
> 
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c
@ 2017-04-07 14:13               ` pankaj.dubey
  0 siblings, 0 replies; 98+ messages in thread
From: pankaj.dubey @ 2017-04-07 14:13 UTC (permalink / raw)
  To: linux-arm-kernel



On Friday 07 April 2017 05:54 PM, Krzysztof Kozlowski wrote:
> On Fri, Apr 7, 2017 at 2:12 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>>
>>
>> On Friday 07 April 2017 01:54 PM, Krzysztof Kozlowski wrote:
>>> On Thu, Mar 30, 2017 at 3:16 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>>> soc_is_exynosMMMM is staged for removal after adopting to exynos-chipid
>>>> driver, so let's remove/minimize usage of any such helper function usage
>>>> from pm.c.
>>>>
>>>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>>> ---
>>>>  arch/arm/mach-exynos/pm.c                   | 22 ++++++++++++----------
>>>>  include/linux/soc/samsung/exynos-regs-pmu.h |  3 +++
>>>>  2 files changed, 15 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
>>>> index 1a7e5b5..4a73b02 100644
>>>> --- a/arch/arm/mach-exynos/pm.c
>>>> +++ b/arch/arm/mach-exynos/pm.c
>>>> @@ -123,11 +123,13 @@ int exynos_pm_central_resume(void)
>>>>  }
>>>>
>>>>  /* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
>>>> -static void exynos_set_wakeupmask(long mask)
>>>> +static void exynos_set_wakeupmask(void)
>>>>  {
>>>> -       pmu_raw_writel(mask, S5P_WAKEUP_MASK);
>>>> -       if (soc_is_exynos3250())
>>>> +       if (of_machine_is_compatible("samsung,exynos3250")) {
>>>> +               pmu_raw_writel(EXYNOS3_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>>>                 pmu_raw_writel(0x0, S5P_WAKEUP_MASK2);
>>>> +       } else
>>>> +               pmu_raw_writel(EXYNOS_WAKEUP_MASK_VAL, S5P_WAKEUP_MASK);
>>>
>>> You need {} around this too. Checkpatch should complain about it as
>>> well so be sure to run it.
>>>
>>
>> I ran checkpatch before posting, but it didn't complain about this. Here
>> is the result when I ran it again today on the same patch.
>>
>> ./scripts/checkpatch.pl
>> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
>>
>> total: 0 errors, 0 warnings, 81 lines checked
>>
>> exynos-chipid-v9/0002-ARM-EXYNOS-remove-usage-of-soc_is_exynosMMMM-from-pm.patch
>> has no obvious style problems and is ready for submission.
> 
> Ahh, okay, my bad. :)
> But anyway please fix it.

OK will take care in next patchset.

Thanks,
Pankaj Dubey
> 
> Best regards,
> Krzysztof
> 
> 
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
  2017-04-07 14:00           ` pankaj.dubey
@ 2017-04-07 14:18             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 14:18 UTC (permalink / raw)
  To: pankaj.dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Fri, Apr 7, 2017 at 4:00 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>
>
> On Friday 07 April 2017 04:11 PM, Krzysztof Kozlowski wrote:
>> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>> Various Exynos SoC has different CPU related information, such as CPU
>>> boot register, programming sequence making CPU up/down. Currently this
>>> is handled by adding lots of soc_is_exynosMMM checks in the code, in
>>> an attempt to remove the dependency of such helper functions specific to
>>> each SoC, let's separate this information pertaining to CPU by introducing
>>> a new "struct exynos_cpu_info". This struct will contain differences
>>> associated with CPU on various Exynos SoC. This can be matched by using
>>> generic API "soc_device_match".
>>>
>>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>> ---
>>>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>>>  1 file changed, 135 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
>>> index cb6d199..ff369b9 100644
>>> --- a/arch/arm/mach-exynos/platsmp.c
>>> +++ b/arch/arm/mach-exynos/platsmp.c
>>> @@ -19,6 +19,7 @@
>>>  #include <linux/smp.h>
>>>  #include <linux/io.h>
>>>  #include <linux/of_address.h>
>>> +#include <linux/sys_soc.h>
>>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>>
>>>  #include <asm/cacheflush.h>
>>> @@ -33,6 +34,16 @@
>>>
>>>  extern void exynos4_secondary_startup(void);
>>>
>>> +/*
>>> + * struct exynos_cpu_info - Exynos CPU related info/operations
>>> + * @cpu_boot_reg: computes cpu boot address for requested cpu
>>> + */
>>> +struct exynos_cpu_info {
>>> +       void __iomem* (*cpu_boot_reg)(u32 cpu);
>>> +};
>>
>> Beside Marek comments, I think we are getting too many structures for
>> differentiating Exynos. Actually all of them describe the same -
>> difference between Exynos revisions. Having many separate structures
>> means that you have to initialize all of them in different places in
>> different (probably) order. The good benefit is however making them
>> local (static) so the scope is limited... but anyway I dislike the
>> duplication.
>>
>
> OK, regarding duplication, only the way they are initialized is getting
> duplicated. But again, my long term goal was to remove dependency of
> pm.c and suspend.c from arm/mach-exynos/{exynos.c,platsmp.c} or common.h
> in mach-exynos. So that we could move these files as a Exynos Power
> Management driver in drivers/soc/ where we already moved pm_domain.c, as
> you see these three files pm.c, suspend.c and pm_domain.c are heavily
> dependent on PMU driver, and handles Power Management states.
>
> So I feel keeping CPU specific data separate from PM specific data makes
> sense and will help in moving these files as a platform driver one day?
>
> Surely I will work out and see how I can minimize duplication.

Hm, in that case it would make sense. However I am not quite sure what
is the benefit of moving this from arm/mach to drivers/soc. This code
will not be re-used on any other platform, unlike existing
drivers/soc/samsung drivers which are used also on ARMv8.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct
@ 2017-04-07 14:18             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 14:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 7, 2017 at 4:00 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:
>
>
> On Friday 07 April 2017 04:11 PM, Krzysztof Kozlowski wrote:
>> On Thu, Mar 30, 2017 at 3:17 PM, Pankaj Dubey <pankaj.dubey@samsung.com> wrote:
>>> Various Exynos SoC has different CPU related information, such as CPU
>>> boot register, programming sequence making CPU up/down. Currently this
>>> is handled by adding lots of soc_is_exynosMMM checks in the code, in
>>> an attempt to remove the dependency of such helper functions specific to
>>> each SoC, let's separate this information pertaining to CPU by introducing
>>> a new "struct exynos_cpu_info". This struct will contain differences
>>> associated with CPU on various Exynos SoC. This can be matched by using
>>> generic API "soc_device_match".
>>>
>>> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>> ---
>>>  arch/arm/mach-exynos/platsmp.c | 146 +++++++++++++++++++++++++++++++++++++----
>>>  1 file changed, 135 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
>>> index cb6d199..ff369b9 100644
>>> --- a/arch/arm/mach-exynos/platsmp.c
>>> +++ b/arch/arm/mach-exynos/platsmp.c
>>> @@ -19,6 +19,7 @@
>>>  #include <linux/smp.h>
>>>  #include <linux/io.h>
>>>  #include <linux/of_address.h>
>>> +#include <linux/sys_soc.h>
>>>  #include <linux/soc/samsung/exynos-regs-pmu.h>
>>>
>>>  #include <asm/cacheflush.h>
>>> @@ -33,6 +34,16 @@
>>>
>>>  extern void exynos4_secondary_startup(void);
>>>
>>> +/*
>>> + * struct exynos_cpu_info - Exynos CPU related info/operations
>>> + * @cpu_boot_reg: computes cpu boot address for requested cpu
>>> + */
>>> +struct exynos_cpu_info {
>>> +       void __iomem* (*cpu_boot_reg)(u32 cpu);
>>> +};
>>
>> Beside Marek comments, I think we are getting too many structures for
>> differentiating Exynos. Actually all of them describe the same -
>> difference between Exynos revisions. Having many separate structures
>> means that you have to initialize all of them in different places in
>> different (probably) order. The good benefit is however making them
>> local (static) so the scope is limited... but anyway I dislike the
>> duplication.
>>
>
> OK, regarding duplication, only the way they are initialized is getting
> duplicated. But again, my long term goal was to remove dependency of
> pm.c and suspend.c from arm/mach-exynos/{exynos.c,platsmp.c} or common.h
> in mach-exynos. So that we could move these files as a Exynos Power
> Management driver in drivers/soc/ where we already moved pm_domain.c, as
> you see these three files pm.c, suspend.c and pm_domain.c are heavily
> dependent on PMU driver, and handles Power Management states.
>
> So I feel keeping CPU specific data separate from PM specific data makes
> sense and will help in moving these files as a platform driver one day?
>
> Surely I will work out and see how I can minimize duplication.

Hm, in that case it would make sense. However I am not quite sure what
is the benefit of moving this from arm/mach to drivers/soc. This code
will not be re-used on any other platform, unlike existing
drivers/soc/samsung drivers which are used also on ARMv8.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
  2017-04-07 14:11           ` pankaj.dubey
@ 2017-04-07 14:57             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 14:57 UTC (permalink / raw)
  To: pankaj.dubey
  Cc: linux-samsung-soc, linux-arm-kernel, arnd, Marek Szyprowski,
	kgene, m.reichl, a.hajda, cwchoi00, Javier Martinez Canillas

On Fri, Apr 7, 2017 at 4:11 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:

(...)

>>> +int __init exynos_s2r_init(void)
>>> +{
>>> +       const struct soc_device_attribute *match;
>>> +
>>> +       match = soc_device_match(exynos_soc_revision);
>>> +
>>> +       if (match)
>>> +               s2r_data = (const struct exynos_s2r_data *) match->data;
>>> +
>>> +       if (!s2r_data)
>>> +               return -ENODEV;
>>> +
>>> +       return 0;
>>> +}
>>> +arch_initcall(exynos_s2r_init);
>>> +
>>
>> I guess you already found possible probe-order issue. You should
>> register all of this after having the soc chipid driver. However it is
>> required by cpuidle driver which is being registered in machine_init()
>> call....  You cannot use deferred probe here, so maybe the only way is
>> to manually order the calls in machine_init():
>> 1. exynos_chipid_early_init()
>> 2. this one.
>> 3. cpuidle driver register.
>>
>
> exynos_s2r_init is not required during early stage of boot, so as Arnd
> suggested I can drop arch_initcall here and probably go for
>
> 1: late_init
> 2: Call this directly from machine_init

I think this will be used on first AFTR which might happen few moments
after exynos_dt_machine_init() because it registers the cpuidle
platform devices thus probing them. This is before late_init. You
might call it from machine_init, but again mind the order.

>
> I prefer first option, as I mentioned my long term plan to move these
> files out of arch/arm/mach-exynos/ and if I call it from mach-exynos,
> then while moving I have to make this function as export symbol or make
> it extern so that mach-exynos/exynos.c should be able to access it. Both
> of these approaches have been rejected in past. What do you say?

Because of the cpuidle I think late_initcall is too late.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops
@ 2017-04-07 14:57             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 98+ messages in thread
From: Krzysztof Kozlowski @ 2017-04-07 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Apr 7, 2017 at 4:11 PM, pankaj.dubey <pankaj.dubey@samsung.com> wrote:

(...)

>>> +int __init exynos_s2r_init(void)
>>> +{
>>> +       const struct soc_device_attribute *match;
>>> +
>>> +       match = soc_device_match(exynos_soc_revision);
>>> +
>>> +       if (match)
>>> +               s2r_data = (const struct exynos_s2r_data *) match->data;
>>> +
>>> +       if (!s2r_data)
>>> +               return -ENODEV;
>>> +
>>> +       return 0;
>>> +}
>>> +arch_initcall(exynos_s2r_init);
>>> +
>>
>> I guess you already found possible probe-order issue. You should
>> register all of this after having the soc chipid driver. However it is
>> required by cpuidle driver which is being registered in machine_init()
>> call....  You cannot use deferred probe here, so maybe the only way is
>> to manually order the calls in machine_init():
>> 1. exynos_chipid_early_init()
>> 2. this one.
>> 3. cpuidle driver register.
>>
>
> exynos_s2r_init is not required during early stage of boot, so as Arnd
> suggested I can drop arch_initcall here and probably go for
>
> 1: late_init
> 2: Call this directly from machine_init

I think this will be used on first AFTR which might happen few moments
after exynos_dt_machine_init() because it registers the cpuidle
platform devices thus probing them. This is before late_init. You
might call it from machine_init, but again mind the order.

>
> I prefer first option, as I mentioned my long term plan to move these
> files out of arch/arm/mach-exynos/ and if I call it from mach-exynos,
> then while moving I have to make this function as export symbol or make
> it extern so that mach-exynos/exynos.c should be able to access it. Both
> of these approaches have been rejected in past. What do you say?

Because of the cpuidle I think late_initcall is too late.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2017-04-07 15:05 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20170330131417epcas1p48a7f41b90177294b7918ecf31df130d1@epcas1p4.samsung.com>
2017-03-30 13:16 ` [PATCH v9 00/12] Introducing Exynos ChipId driver Pankaj Dubey
2017-03-30 13:16   ` Pankaj Dubey
     [not found]   ` <CGME20170330131419epcas5p4ac36250d3a9225643e327e60f47956c2@epcas5p4.samsung.com>
2017-03-30 13:16     ` [PATCH v9 01/12] ARM: EXYNOS: refactor firmware specific routines Pankaj Dubey
2017-03-30 13:16       ` Pankaj Dubey
2017-04-07  7:45       ` Krzysztof Kozlowski
2017-04-07  7:45         ` Krzysztof Kozlowski
2017-04-07  8:06         ` pankaj.dubey
2017-04-07  8:06           ` pankaj.dubey
     [not found]   ` <CGME20170330131421epcas5p40b0ad9c1003d3ab807667ae2b05d25bc@epcas5p4.samsung.com>
2017-03-30 13:16     ` [PATCH v9 02/12] ARM: EXYNOS: remove usage of soc_is_exynosMMMM from pm.c Pankaj Dubey
2017-03-30 13:16       ` Pankaj Dubey
2017-04-07  8:24       ` Krzysztof Kozlowski
2017-04-07  8:24         ` Krzysztof Kozlowski
2017-04-07 12:12         ` pankaj.dubey
2017-04-07 12:12           ` pankaj.dubey
2017-04-07 12:24           ` Krzysztof Kozlowski
2017-04-07 12:24             ` Krzysztof Kozlowski
2017-04-07 14:13             ` pankaj.dubey
2017-04-07 14:13               ` pankaj.dubey
     [not found]   ` <CGME20170330131424epcas5p4fccfab06e5d77d70d09c3835c3332ee5@epcas5p4.samsung.com>
2017-03-30 13:16     ` [PATCH v9 03/12] ARM: EXYNOS: remove secondary startup initialization from smp_prepare_cpus Pankaj Dubey
2017-03-30 13:16       ` Pankaj Dubey
2017-04-07  8:31       ` Krzysztof Kozlowski
2017-04-07  8:31         ` Krzysztof Kozlowski
2017-04-07 12:15         ` pankaj.dubey
2017-04-07 12:15           ` pankaj.dubey
     [not found]   ` <CGME20170330131427epcas5p4c3d238022dc75694ad3baa8a1018ea04@epcas5p4.samsung.com>
2017-03-30 13:16     ` [PATCH v9 04/12] soc: samsung: add exynos chipid driver support Pankaj Dubey
2017-03-30 13:16       ` Pankaj Dubey
2017-03-30 13:50       ` Arnd Bergmann
2017-03-30 13:50         ` Arnd Bergmann
2017-03-31  5:36         ` pankaj.dubey
2017-03-31  5:36           ` pankaj.dubey
2017-03-31  8:09           ` Arnd Bergmann
2017-03-31  8:09             ` Arnd Bergmann
2017-04-03  9:21             ` pankaj.dubey
2017-04-03  9:21               ` pankaj.dubey
2017-04-03  7:57       ` Marek Szyprowski
2017-04-03  7:57         ` Marek Szyprowski
2017-04-03  9:35         ` pankaj.dubey
2017-04-03  9:35           ` pankaj.dubey
2017-04-07  9:13       ` Krzysztof Kozlowski
2017-04-07  9:13         ` Krzysztof Kozlowski
2017-04-07 12:18         ` pankaj.dubey
2017-04-07 12:18           ` pankaj.dubey
     [not found]   ` <CGME20170330131429epcas5p414565c5a9f2c38f3f6660b72f9ad68a2@epcas5p4.samsung.com>
2017-03-30 13:16     ` [PATCH v9 05/12] ARM: EXYNOS: enable exynos_chipid for ARCH_EXYNOS Pankaj Dubey
2017-03-30 13:16       ` Pankaj Dubey
     [not found]   ` <CGME20170330131431epcas5p447a730e1bb194162f262a819ae665efb@epcas5p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 06/12] ARM64: " Pankaj Dubey
2017-03-30 13:17       ` Pankaj Dubey
2017-03-30 13:51       ` Arnd Bergmann
2017-03-30 13:51         ` Arnd Bergmann
     [not found]   ` <CGME20170330131434epcas1p4e42fe06bae3456c39e0f93a2f8ae4bc0@epcas1p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 07/12] ARM: EXYNOS: introduce soc specific pm ops Pankaj Dubey
2017-03-30 13:17       ` Pankaj Dubey
2017-03-30 14:03       ` Arnd Bergmann
2017-03-30 14:03         ` Arnd Bergmann
2017-04-07  9:24       ` Krzysztof Kozlowski
2017-04-07  9:24         ` Krzysztof Kozlowski
2017-04-07 14:11         ` pankaj.dubey
2017-04-07 14:11           ` pankaj.dubey
2017-04-07 14:57           ` Krzysztof Kozlowski
2017-04-07 14:57             ` Krzysztof Kozlowski
     [not found]   ` <CGME20170330131436epcas1p4a4f8bf7b64b4a5ff9ee692adc4e7d001@epcas1p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr,flag} ops to exynos_s2r_data Pankaj Dubey
2017-03-30 13:17       ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} " Pankaj Dubey
2017-04-07 10:32       ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr,flag} " Krzysztof Kozlowski
2017-04-07 10:32         ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} " Krzysztof Kozlowski
2017-04-07 13:52         ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr,flag} " pankaj.dubey
2017-04-07 13:52           ` [PATCH v9 08/12] ARM: EXYNOS: move exynos_boot_vector_{addr, flag} " pankaj.dubey
     [not found]   ` <CGME20170330131438epcas1p459ce93da17fcd05249eddaef18d5021e@epcas1p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 09/12] ARM: EXYNOS: introduce exynos_cpu_info struct Pankaj Dubey
2017-03-30 13:17       ` Pankaj Dubey
2017-04-03  7:57       ` Marek Szyprowski
2017-04-03  7:57         ` Marek Szyprowski
2017-04-03  9:54         ` pankaj.dubey
2017-04-03  9:54           ` pankaj.dubey
2017-04-07 10:41       ` Krzysztof Kozlowski
2017-04-07 10:41         ` Krzysztof Kozlowski
2017-04-07 14:00         ` pankaj.dubey
2017-04-07 14:00           ` pankaj.dubey
2017-04-07 14:18           ` Krzysztof Kozlowski
2017-04-07 14:18             ` Krzysztof Kozlowski
2017-04-07 10:47       ` Krzysztof Kozlowski
2017-04-07 10:47         ` Krzysztof Kozlowski
     [not found]   ` <CGME20170330131440epcas1p4f27192272761aa593b6cf083453e8adc@epcas1p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} to per SoC struct exynos_cpu_info Pankaj Dubey
2017-03-30 13:17       ` [PATCH v9 10/12] ARM: EXYNOS: move power_{down, up} " Pankaj Dubey
2017-04-07 12:04       ` [PATCH v9 10/12] ARM: EXYNOS: move power_{down,up} " Krzysztof Kozlowski
2017-04-07 12:04         ` Krzysztof Kozlowski
2017-04-07 14:12         ` pankaj.dubey
2017-04-07 14:12           ` pankaj.dubey
     [not found]   ` <CGME20170330131442epcas5p4f2be72cb3ec506847d8e832675e682c4@epcas5p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 11/12] ARM: EXYNOS: move cpu_restart as a SoC specific hook to exynos_cpu_info Pankaj Dubey
2017-03-30 13:17       ` Pankaj Dubey
2017-04-07 12:23       ` Krzysztof Kozlowski
2017-04-07 12:23         ` Krzysztof Kozlowski
     [not found]   ` <CGME20170330131444epcas5p45051cf7e6ec7a993c2c9f84254b89a19@epcas5p4.samsung.com>
2017-03-30 13:17     ` [PATCH v9 12/12] ARM: EXYNOS: refactor of mach-exynos to use chipid information Pankaj Dubey
2017-03-30 13:17       ` Pankaj Dubey
2017-03-30 14:01       ` Arnd Bergmann
2017-03-30 14:01         ` Arnd Bergmann
2017-03-31  6:01         ` pankaj.dubey
2017-03-31  6:01           ` pankaj.dubey
2017-03-31  8:22           ` Arnd Bergmann
2017-03-31  8:22             ` Arnd Bergmann
2017-04-03  9:25             ` pankaj.dubey
2017-04-03  9:25               ` pankaj.dubey

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.