Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 4/9] soc: samsung: Add generic power-management driver for Exynos
From: Chanwoo Choi @ 2018-01-09  7:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515484746-10656-1-git-send-email-cw00.choi@samsung.com>

To enter suspend, Exynos SoC requires the some machine dependent procedures.
This patch introduces the generic power-management driver to support
those requirements and generic interface for power state management.

Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 arch/arm/mach-exynos/common.h         |   1 -
 arch/arm/mach-exynos/exynos.c         |  23 +----
 drivers/soc/samsung/Makefile          |   2 +-
 drivers/soc/samsung/exynos-pm.c       | 176 ++++++++++++++++++++++++++++++++++
 include/linux/soc/samsung/exynos-pm.h |  21 ++++
 5 files changed, 199 insertions(+), 24 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-pm.c
 create mode 100644 include/linux/soc/samsung/exynos-pm.h

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index afbc143a3d5d..ad482c0fc131 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -119,7 +119,6 @@ enum {
  * Magic values for bootloader indicating chosen low power mode.
  * See also Documentation/arm/Samsung/Bootloader-interface.txt
  */
-#define EXYNOS_SLEEP_MAGIC	0x00000bad
 #define EXYNOS_AFTR_MAGIC	0xfcba0d10

 void exynos_set_boot_flag(unsigned int cpu, unsigned int mode);
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index fbd108ce8745..0d5265d175c4 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -12,6 +12,7 @@
 #include <linux/of_fdt.h>
 #include <linux/platform_device.h>
 #include <linux/irqchip.h>
+#include <linux/soc/samsung/exynos-pm.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>

 #include <asm/cacheflush.h>
@@ -41,28 +42,6 @@
 	.id                = -1,
 };

-void __iomem *sysram_base_addr __ro_after_init;
-void __iomem *sysram_ns_base_addr __ro_after_init;
-
-void __init exynos_sysram_init(void)
-{
-	struct device_node *node;
-
-	for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram") {
-		if (!of_device_is_available(node))
-			continue;
-		sysram_base_addr = of_iomap(node, 0);
-		break;
-	}
-
-	for_each_compatible_node(node, NULL, "samsung,exynos4210-sysram-ns") {
-		if (!of_device_is_available(node))
-			continue;
-		sysram_ns_base_addr = of_iomap(node, 0);
-		break;
-	}
-}
-
 static void __init exynos_init_late(void)
 {
 	if (of_machine_is_compatible("samsung,exynos5440"))
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index d2e637339a45..58ca5bdabf1f 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
+obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o exynos-pm.o

 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
 					exynos5250-pmu.o exynos5420-pmu.o \
diff --git a/drivers/soc/samsung/exynos-pm.c b/drivers/soc/samsung/exynos-pm.c
new file mode 100644
index 000000000000..45d84bbe5e61
--- /dev/null
+++ b/drivers/soc/samsung/exynos-pm.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// based on arch/arm/mach-exynos/suspend.c
+// Copyright (c) 2018 Samsung Electronics Co., Ltd.
+//
+// Exynos Power Management support driver
+
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/kernel.h>
+#include <linux/regulator/machine.h>
+#include <linux/syscore_ops.h>
+#include <linux/suspend.h>
+
+#include <asm/cpuidle.h>
+#include <asm/io.h>
+#include <asm/suspend.h>
+
+#include <linux/soc/samsung/exynos-pm.h>
+#include <linux/soc/samsung/exynos-pmu.h>
+
+/*
+ * The struct exynos_pm_data contains the callbacks of
+ * both struct platform_suspend_ops and syscore_ops.
+ * This structure is listed according to the call order,
+ * because the callback call order for the two structures is mixed.
+ */
+struct exynos_pm_data {
+	int (*prepare)(void);			/* for platform_suspend_ops */
+	int (*suspend)(void);			/* for syscore_ops */
+	int (*enter)(suspend_state_t state);	/* for platform_suspend_ops */
+	void (*resume)(void);			/* for syscore_ops */
+	void (*finish)(void);			/* for platform_suspend_ops */
+};
+
+static struct platform_suspend_ops exynos_pm_suspend_ops;
+static struct syscore_ops exynos_pm_syscore_ops;
+static const struct exynos_pm_data *pm_data  __ro_after_init;
+
+void __iomem *sysram_base_addr __ro_after_init;
+void __iomem *sysram_ns_base_addr __ro_after_init;
+
+static int exynos_pm_prepare(void)
+{
+	int ret;
+
+	/*
+	 * REVISIT: It would be better if struct platform_suspend_ops
+	 * .prepare handler get the suspend_state_t as a parameter to
+	 * avoid hard-coding the suspend to mem state. It's safe to do
+	 * it now only because the suspend_valid_only_mem function is
+	 * used as the .valid callback used to check if a given state
+	 * is supported by the platform anyways.
+	 */
+	ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
+	if (ret) {
+		pr_err("Failed to prepare regulators for suspend (%d)\n", ret);
+		return ret;
+	}
+
+	if (pm_data->prepare) {
+		ret = pm_data->prepare();
+		if (ret) {
+			pr_err("Failed to prepare for suspend (%d)\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int exynos_pm_suspend(void)
+{
+	if (pm_data->suspend)
+		return pm_data->suspend();
+
+	return 0;
+}
+
+static int exynos_pm_enter(suspend_state_t state)
+{
+	int ret;
+
+	exynos_sys_powerdown_conf(SYS_SLEEP);
+
+	ret = pm_data->enter(state);
+	if (ret) {
+		pr_err("Failed to enter sleep\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void exynos_pm_resume(void)
+{
+	exynos_sys_powerup_conf(SYS_SLEEP);
+
+	if (pm_data->resume)
+		pm_data->resume();
+}
+
+static void exynos_pm_finish(void)
+{
+	int ret;
+
+	ret = regulator_suspend_finish();
+	if (ret)
+		pr_warn("Failed to resume regulators from suspend (%d)\n", ret);
+
+	if (pm_data->finish)
+		pm_data->finish();
+}
+
+/*
+ * Split the data between ARM architectures because it is relatively big
+ * and useless on other arch.
+ */
+#ifdef CONFIG_EXYNOS_PMU_ARM_DRIVERS
+#define exynos_pm_data_arm_ptr(data)	(&data)
+#else
+#define exynos_pm_data_arm_ptr(data)	NULL
+#endif
+
+static const struct of_device_id exynos_pm_of_device_ids[] = {
+	{ /*sentinel*/ },
+};
+
+void __init exynos_sysram_init(void)
+{
+	struct device_node *np;
+
+	for_each_compatible_node(np, NULL, "samsung,exynos4210-sysram") {
+		if (!of_device_is_available(np))
+			continue;
+		sysram_base_addr = of_iomap(np, 0);
+		break;
+	}
+
+	for_each_compatible_node(np, NULL, "samsung,exynos4210-sysram-ns") {
+		if (!of_device_is_available(np))
+			continue;
+		sysram_ns_base_addr = of_iomap(np, 0);
+		break;
+	}
+}
+
+static int __init exynos_pm_init(void)
+{
+	const struct of_device_id *match;
+	struct device_node *np;
+
+	np = of_find_matching_node_and_match(NULL,
+					exynos_pm_of_device_ids, &match);
+	if (!np) {
+		pr_err("Failed to find PMU node for Exynos Power-Management\n");
+		return -ENODEV;
+	}
+	pm_data = (const struct exynos_pm_data *) match->data;
+
+	exynos_sysram_init();
+
+	exynos_pm_suspend_ops.valid	= suspend_valid_only_mem;
+	exynos_pm_suspend_ops.prepare	= exynos_pm_prepare;
+	exynos_pm_syscore_ops.suspend	= exynos_pm_suspend;
+	exynos_pm_suspend_ops.enter	= exynos_pm_enter;
+	exynos_pm_syscore_ops.resume	= exynos_pm_resume;
+	exynos_pm_suspend_ops.finish	= exynos_pm_finish;
+
+	register_syscore_ops(&exynos_pm_syscore_ops);
+	suspend_set_ops(&exynos_pm_suspend_ops);
+
+	return 0;
+}
+postcore_initcall(exynos_pm_init);
diff --git a/include/linux/soc/samsung/exynos-pm.h b/include/linux/soc/samsung/exynos-pm.h
new file mode 100644
index 000000000000..b1afe95ed10c
--- /dev/null
+++ b/include/linux/soc/samsung/exynos-pm.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 Samsung Electronics Co., Ltd.
+//
+// Header for Exynos Power-Management support driver
+
+#ifndef __LINUX_SOC_EXYNOS_PM_H
+#define __LINUX_SOC_EXYNOS_PM_H
+
+/*
+ * Magic values for bootloader indicating chosen low power mode.
+ * See also Documentation/arm/Samsung/Bootloader-interface.txt
+ */
+#define EXYNOS_SLEEP_MAGIC	0x00000bad
+
+extern void __iomem *sysram_base_addr;
+extern void __iomem *sysram_ns_base_addr;
+
+extern void exynos_sysram_init(void);
+
+#endif /* __LINUX_SOC_EXYNOS_PMU_H */
--
1.9.1

^ permalink raw reply related

* [PATCH 3/9] soc: samsung: pmu: Add the PMU data of exynos5433 to support low-power state
From: Chanwoo Choi @ 2018-01-09  7:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515484746-10656-1-git-send-email-cw00.choi@samsung.com>

This patch adds the PMU (Power Management Unit) data of exynos5433 SoC
in order to support the various power modes. Each power mode has
the different value for reducing the power-consumption.

Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 arch/arm/mach-exynos/common.h               |   2 -
 drivers/soc/samsung/Makefile                |   3 +-
 drivers/soc/samsung/exynos-pmu.c            |   1 +
 drivers/soc/samsung/exynos-pmu.h            |   2 +
 drivers/soc/samsung/exynos5433-pmu.c        | 286 ++++++++++++++++++++++++++++
 include/linux/soc/samsung/exynos-regs-pmu.h | 148 ++++++++++++++
 6 files changed, 439 insertions(+), 3 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos5433-pmu.c

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 098f84a149a3..afbc143a3d5d 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -125,8 +125,6 @@ enum {
 void exynos_set_boot_flag(unsigned int cpu, unsigned int mode);
 void exynos_clear_boot_flag(unsigned int cpu, unsigned int mode);
 
-extern u32 exynos_get_eint_wake_mask(void);
-
 #ifdef CONFIG_PM_SLEEP
 extern void __init exynos_pm_init(void);
 #else
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 29f294baac6e..d2e637339a45 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -2,5 +2,6 @@
 obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
 
 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
-					exynos5250-pmu.o exynos5420-pmu.o
+					exynos5250-pmu.o exynos5420-pmu.o \
+					exynos5433-pmu.o
 obj-$(CONFIG_EXYNOS_PM_DOMAINS) += pm_domains.o
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index cfc9de518344..7112d7b2749b 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -97,6 +97,7 @@ void exynos_sys_powerup_conf(enum sys_powerdown mode)
 		.data = exynos_pmu_data_arm_ptr(exynos5420_pmu_data),
 	}, {
 		.compatible = "samsung,exynos5433-pmu",
+		.data = exynos_pmu_data_arm_ptr(exynos5433_pmu_data),
 	},
 	{ /*sentinel*/ },
 };
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
index efbaf8929252..895c786a2f4c 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -28,6 +28,7 @@ struct exynos_pmu_data {
 };
 
 extern void __iomem *pmu_base_addr;
+extern u32 exynos_get_eint_wake_mask(void);
 
 #ifdef CONFIG_EXYNOS_PMU_ARM_DRIVERS
 /* list of all exported SoC specific data */
@@ -36,6 +37,7 @@ struct exynos_pmu_data {
 extern const struct exynos_pmu_data exynos4412_pmu_data;
 extern const struct exynos_pmu_data exynos5250_pmu_data;
 extern const struct exynos_pmu_data exynos5420_pmu_data;
+extern const struct exynos_pmu_data exynos5433_pmu_data;
 #endif
 
 extern void pmu_raw_writel(u32 val, u32 offset);
diff --git a/drivers/soc/samsung/exynos5433-pmu.c b/drivers/soc/samsung/exynos5433-pmu.c
new file mode 100644
index 000000000000..2571e61522f0
--- /dev/null
+++ b/drivers/soc/samsung/exynos5433-pmu.c
@@ -0,0 +1,286 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018 Samsung Electronics Co., Ltd.
+// Copyright (c) Jonghwa Lee <jonghwa3.lee@samsung.com>
+// Copyright (c) Chanwoo Choi <cw00.choi@samsung.com>
+//
+// EXYNOS5433 - CPU PMU (Power Management Unit) support
+
+#include <linux/soc/samsung/exynos-regs-pmu.h>
+#include <linux/soc/samsung/exynos-pmu.h>
+
+#include "exynos-pmu.h"
+
+static struct exynos_pmu_conf exynos5433_pmu_config[] = {
+	/* { .offset = address,	.val = { AFTR, LPA, SLEEP } } */
+	{ EXYNOS5433_ATLAS_CPU0_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_ATLAS_CPU0_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_ATLAS_CPU1_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_ATLAS_CPU1_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_ATLAS_CPU2_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_ATLAS_CPU2_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_ATLAS_CPU3_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_ATLAS_CPU3_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_APOLLO_CPU0_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_APOLLO_CPU0_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_APOLLO_CPU1_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_APOLLO_CPU1_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_APOLLO_CPU2_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_APOLLO_CPU2_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_APOLLO_CPU3_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_DIS_IRQ_APOLLO_CPU3_CENTRAL_SYS_PWR_REG,	{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_ATLAS_NONCPU_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_APOLLO_NONCPU_SYS_PWR_REG,			{ 0x0, 0x0, 0x8 } },
+	{ EXYNOS5433_A5IS_SYS_PWR_REG,				{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_DIS_IRQ_A5IS_LOCAL_SYS_PWR_REG,		{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_DIS_IRQ_A5IS_CENTRAL_SYS_PWR_REG,		{ 0x0, 0x0, 0x0 } },
+	{ EXYNOS5433_ATLAS_L2_SYS_PWR_REG,			{ 0x0, 0x0, 0x7 } },
+	{ EXYNOS5433_APOLLO_L2_SYS_PWR_REG,			{ 0x0, 0x0, 0x7 } },
+	{ EXYNOS5433_CLKSTOP_CMU_TOP_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_CLKRUN_CMU_TOP_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_RESET_CMU_TOP_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_RESET_CPUCLKSTOP_SYS_PWR_REG,		{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_CLKSTOP_CMU_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_CLKRUN_CMU_MIF_SYS_PWR_REG,		{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_RESET_CMU_MIF_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_DDRPHY_DLLLOCK_SYS_PWR_REG,		{ 0x1, 0x1, 0x1 } },
+	{ EXYNOS5433_DISABLE_PLL_CMU_TOP_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_DISABLE_PLL_AUD_PLL_SYS_PWR_REG,		{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_DISABLE_PLL_CMU_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_TOP_BUS_SYS_PWR_REG,			{ 0x7, 0x0, 0x0 } },
+	{ EXYNOS5433_TOP_RETENTION_SYS_PWR_REG,			{ 0x1, 0x0, 0x1 } },
+	{ EXYNOS5433_TOP_PWR_SYS_PWR_REG,			{ 0x3, 0x0, 0x3 } },
+	{ EXYNOS5433_TOP_BUS_MIF_SYS_PWR_REG,			{ 0x7, 0x0, 0x0 } },
+	{ EXYNOS5433_TOP_RETENTION_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x1 } },
+	{ EXYNOS5433_TOP_PWR_MIF_SYS_PWR_REG,			{ 0x3, 0x0, 0x3 } },
+	{ EXYNOS5433_LOGIC_RESET_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_OSCCLK_GATE_SYS_PWR_REG,			{ 0x1, 0x0, 0x1 } },
+	{ EXYNOS5433_SLEEP_RESET_SYS_PWR_REG,			{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_LOGIC_RESET_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_OSCCLK_GATE_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x1 } },
+	{ EXYNOS5433_SLEEP_RESET_MIF_SYS_PWR_REG,		{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_MEMORY_TOP_SYS_PWR_REG,			{ 0x3, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_LPDDR3_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_JTAG_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_TOP_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_UART_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_EBIA_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_EBIB_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_SPI_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_ISOLATION_SYS_PWR_REG,			{ 0x1, 0x0, 0x1 } },
+	{ EXYNOS5433_PAD_RETENTION_USBXTI_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_RETENTION_BOOTLDO_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_ISOLATION_MIF_SYS_PWR_REG,		{ 0x1, 0x0, 0x1 } },
+	{ EXYNOS5433_PAD_RETENTION_FSYSGENIO_SYS_PWR_REG,	{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_PAD_ALV_SEL_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_XXTI_SYS_PWR_REG,				{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_XXTI26_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_EXT_REGULATOR_SYS_PWR_REG,			{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_GPIO_MODE_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_GPIO_MODE_FSYS0_SYS_PWR_REG,		{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_GPIO_MODE_MIF_SYS_PWR_REG,			{ 0x1, 0x0, 0x0 } },
+	{ EXYNOS5433_GPIO_MODE_AUD_SYS_PWR_REG,			{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_GSCL_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_CAM0_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_MSCL_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_G3D_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_DISP_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_CAM1_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_AUD_SYS_PWR_REG,				{ 0xF, 0xF, 0x0 } },
+	{ EXYNOS5433_FSYS_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_BUS2_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_G2D_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_ISP0_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_MFC_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_HEVC_SYS_PWR_REG,				{ 0xF, 0x0, 0x0 } },
+	{ EXYNOS5433_RESET_SLEEP_FSYS_SYS_PWR_REG,		{ 0x1, 0x1, 0x0 } },
+	{ EXYNOS5433_RESET_SLEEP_BUS2_SYS_PWR_REG,		{ 0x1, 0x1, 0x0 } },
+	{ PMU_TABLE_END, },
+};
+
+static unsigned int const exynos5433_list_feed[] = {
+	EXYNOS5433_ATLAS_NONCPU_OPTION,
+	EXYNOS5433_APOLLO_NONCPU_OPTION,
+	EXYNOS5433_TOP_PWR_OPTION,
+	EXYNOS5433_TOP_PWR_MIF_OPTION,
+	EXYNOS5433_AUD_OPTION,
+	EXYNOS5433_CAM0_OPTION,
+	EXYNOS5433_DISP_OPTION,
+	EXYNOS5433_G2D_OPTION,
+	EXYNOS5433_G3D_OPTION,
+	EXYNOS5433_HEVC_OPTION,
+	EXYNOS5433_MSCL_OPTION,
+	EXYNOS5433_MFC_OPTION,
+	EXYNOS5433_GSCL_OPTION,
+	EXYNOS5433_FSYS_OPTION,
+	EXYNOS5433_ISP_OPTION,
+	EXYNOS5433_BUS2_OPTION,
+};
+
+static unsigned int const exynos5433_list_pad_retention[] = {
+	EXYNOS5433_PAD_RETENTION_LPDDR3_OPTION,
+	EXYNOS5433_PAD_RETENTION_AUD_OPTION,
+	EXYNOS5433_PAD_RETENTION_MMC2_OPTION,
+	EXYNOS5433_PAD_RETENTION_TOP_OPTION,
+	EXYNOS5433_PAD_RETENTION_UART_OPTION,
+	EXYNOS5433_PAD_RETENTION_MMC0_OPTION,
+	EXYNOS5433_PAD_RETENTION_MMC1_OPTION,
+	EXYNOS5433_PAD_RETENTION_EBIA_OPTION,
+	EXYNOS5433_PAD_RETENTION_EBIB_OPTION,
+	EXYNOS5433_PAD_RETENTION_SPI_OPTION,
+	EXYNOS5433_PAD_RETENTION_MIF_OPTION,
+	EXYNOS5433_PAD_RETENTION_USBXTI_OPTION,
+	EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION,
+	EXYNOS5433_PAD_RETENTION_UFS_OPTION,
+	EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION,
+};
+
+static void exynos5433_set_wakeupmask(enum sys_powerdown mode)
+{
+	u32 intmask = 0;
+
+	pmu_raw_writel(exynos_get_eint_wake_mask(),
+					EXYNOS5433_EINT_WAKEUP_MASK);
+
+	/* Disable WAKEUP event monitor */
+	intmask = pmu_raw_readl(EXYNOS5433_WAKEUP_MASK);
+	intmask &= ~(1 << 31);
+	pmu_raw_writel(intmask, EXYNOS5433_WAKEUP_MASK);
+
+	pmu_raw_writel(0xFFFF0000, EXYNOS5433_WAKEUP_MASK2);
+	pmu_raw_writel(0xFFFF0000, EXYNOS5433_WAKEUP_MASK3);
+}
+
+static void exynos5433_pmu_central_seq(bool enable)
+{
+	unsigned int tmp;
+
+	tmp = pmu_raw_readl(EXYNOS5433_CENTRAL_SEQ_CONFIGURATION);
+	if (enable)
+		tmp &= ~EXYNOS5433_CENTRALSEQ_PWR_CFG;
+	else
+		tmp |= EXYNOS5433_CENTRALSEQ_PWR_CFG;
+	pmu_raw_writel(tmp, EXYNOS5433_CENTRAL_SEQ_CONFIGURATION);
+
+	tmp = pmu_raw_readl(EXYNOS5433_CENTRAL_SEQ_MIF_CONFIGURATION);
+	if (enable)
+		tmp &= ~EXYNOS5433_CENTRALSEQ_PWR_CFG;
+	else
+		tmp |= EXYNOS5433_CENTRALSEQ_PWR_CFG;
+	pmu_raw_writel(tmp, EXYNOS5433_CENTRAL_SEQ_MIF_CONFIGURATION);
+}
+
+static void exynos5433_pmu_pad_retention_release(void)
+{
+	unsigned int tmp;
+	int i;
+
+	for (i = 0 ; i < ARRAY_SIZE(exynos5433_list_pad_retention) ; i++) {
+		tmp = pmu_raw_readl(exynos5433_list_pad_retention[i]);
+		tmp |= EXYNOS5433_INITIATE_WAKEUP_FROM_LOWPOWER;
+		pmu_raw_writel(tmp, exynos5433_list_pad_retention[i]);
+	}
+}
+
+static void exynos5433_pmu_init(void)
+{
+	unsigned int tmp;
+	int i, cluster, cpu;
+
+	/* Enable non retention flip-flop reset for wakeup */
+	tmp = pmu_raw_readl(EXYNOS5433_PMU_SPARE0);
+	tmp |= EXYNOS5433_EN_NONRET_RESET;
+	pmu_raw_writel(tmp, EXYNOS5433_PMU_SPARE0);
+
+	 /* Enable only SC_FEEDBACK for the register list */
+	for (i = 0 ; i < ARRAY_SIZE(exynos5433_list_feed) ; i++) {
+		tmp = pmu_raw_readl(exynos5433_list_feed[i]);
+		tmp &= ~EXYNOS5_USE_SC_COUNTER;
+		tmp |= EXYNOS5_USE_SC_FEEDBACK;
+		pmu_raw_writel(tmp, exynos5433_list_feed[i]);
+	}
+
+	/*
+	 * Disable automatic L2 flush, Disable L2 retention and
+	 * Enable STANDBYWFIL2, ACE/ACP
+	 */
+	for (cluster = 0; cluster < 2; cluster++) {
+		tmp = pmu_raw_readl(EXYNOS5433_ATLAS_L2_OPTION + (cluster * 0x20));
+		tmp &= ~(EXYNOS5433_USE_AUTO_L2FLUSHREQ | EXYNOS5433_USE_RETENTION);
+
+		if (cluster == 0) {
+			tmp |= (EXYNOS5433_USE_STANDBYWFIL2 |
+				EXYNOS5433_USE_DEACTIVATE_ACE |
+				EXYNOS5433_USE_DEACTIVATE_ACP);
+		}
+		pmu_raw_writel(tmp, EXYNOS5433_ATLAS_L2_OPTION + (cluster * 0x20));
+	}
+
+	/*
+	 * Enable both SC_COUNTER and SC_FEEDBACK for the CPUs
+	 * Use STANDBYWFI and SMPEN to indicate that core is ready to enter
+	 * low power mode
+	 */
+	for (cpu = 0; cpu < 8; cpu++) {
+		tmp = pmu_raw_readl(EXYNOS5433_CPU_OPTION(cpu));
+		tmp |= (EXYNOS5_USE_SC_FEEDBACK | EXYNOS5_USE_SC_COUNTER);
+		tmp |= EXYNOS5433_USE_SMPEN;
+		tmp |= EXYNOS5433_USE_STANDBYWFI;
+		tmp &= ~EXYNOS5433_USE_STANDBYWFE;
+		pmu_raw_writel(tmp, EXYNOS5433_CPU_OPTION(cpu));
+
+		tmp = pmu_raw_readl(EXYNOS5433_CPU_DURATION(cpu));
+		tmp |= EXYNOS5433_DUR_WAIT_RESET;
+		tmp &= ~EXYNOS5433_DUR_SCALL;
+		tmp |= EXYNOS5433_DUR_SCALL_VALUE;
+		pmu_raw_writel(tmp, EXYNOS5433_CPU_DURATION(cpu));
+	}
+
+	/* Skip atlas block power-off during automatic power down sequence */
+	tmp = pmu_raw_readl(EXYNOS5433_ATLAS_CPUSEQUENCER_OPTION);
+	tmp |= EXYNOS5433_SKIP_BLK_PWR_DOWN;
+	pmu_raw_writel(tmp, EXYNOS5433_ATLAS_CPUSEQUENCER_OPTION);
+
+	/* Limit in-rush current during local power up of cores */
+	tmp = pmu_raw_readl(EXYNOS5433_UP_SCHEDULER);
+	tmp |= EXYNOS5433_ENABLE_ATLAS_CPU;
+	pmu_raw_writel(tmp, EXYNOS5433_UP_SCHEDULER);
+}
+
+static void exynos5433_powerdown_conf(enum sys_powerdown mode)
+{
+	switch (mode) {
+	case SYS_SLEEP:
+		exynos5433_set_wakeupmask(mode);
+		exynos5433_pmu_central_seq(true);
+		break;
+	default:
+		break;
+	};
+}
+
+static void exynos5433_powerup_conf(enum sys_powerdown mode)
+{
+	unsigned int wakeup;
+
+	switch (mode) {
+	case SYS_SLEEP:
+		wakeup = pmu_raw_readl(EXYNOS5433_CENTRAL_SEQ_CONFIGURATION);
+		wakeup &= EXYNOS5433_CENTRALSEQ_PWR_CFG;
+		if (wakeup)
+			exynos5433_pmu_pad_retention_release();
+		else
+			exynos5433_pmu_central_seq(false);
+		break;
+	default:
+		break;
+	};
+}
+
+const struct exynos_pmu_data exynos5433_pmu_data = {
+	.pmu_config		= exynos5433_pmu_config,
+	.pmu_init		= exynos5433_pmu_init,
+	.powerdown_conf		= exynos5433_powerdown_conf,
+	.powerup_conf		= exynos5433_powerup_conf,
+};
diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
index bebdde5dccd6..93a52d133ba1 100644
--- a/include/linux/soc/samsung/exynos-regs-pmu.h
+++ b/include/linux/soc/samsung/exynos-regs-pmu.h
@@ -645,7 +645,110 @@
 					 | EXYNOS5420_KFC_USE_STANDBY_WFI3)
 
 /* For EXYNOS5433 */
+#define EXYNOS5433_UP_SCHEDULER					(0x0120)
+#define EXYNOS5433_CENTRAL_SEQ_CONFIGURATION			(0x0200)
+#define EXYNOS5433_CENTRAL_SEQ_MIF_CONFIGURATION		(0x0240)
+#define EXYNOS5433_EINT_WAKEUP_MASK				(0x060C)
+#define EXYNOS5433_WAKEUP_MASK					(0x0610)
+#define EXYNOS5433_WAKEUP_MASK2					(0x0614)
+#define EXYNOS5433_WAKEUP_MASK3					(0x0618)
+#define EXYNOS5433_EINT_WAKEUP_MASK1				(0x062C)
 #define EXYNOS5433_USBHOST30_PHY_CONTROL			(0x0728)
+#define EXYNOS5433_PMU_SPARE0					(0x0900)
+#define EXYNOS5433_ATLAS_CPU0_SYS_PWR_REG			(0x1000)
+#define EXYNOS5433_DIS_IRQ_ATLAS_CPU0_CENTRAL_SYS_PWR_REG	(0x1008)
+#define EXYNOS5433_ATLAS_CPU1_SYS_PWR_REG			(0x1010)
+#define EXYNOS5433_DIS_IRQ_ATLAS_CPU1_CENTRAL_SYS_PWR_REG	(0x1018)
+#define EXYNOS5433_ATLAS_CPU2_SYS_PWR_REG			(0x1020)
+#define EXYNOS5433_DIS_IRQ_ATLAS_CPU2_CENTRAL_SYS_PWR_REG	(0x1028)
+#define EXYNOS5433_ATLAS_CPU3_SYS_PWR_REG			(0x1030)
+#define EXYNOS5433_DIS_IRQ_ATLAS_CPU3_CENTRAL_SYS_PWR_REG	(0x1038)
+#define EXYNOS5433_APOLLO_CPU0_SYS_PWR_REG			(0x1040)
+#define EXYNOS5433_DIS_IRQ_APOLLO_CPU0_CENTRAL_SYS_PWR_REG	(0x1048)
+#define EXYNOS5433_APOLLO_CPU1_SYS_PWR_REG			(0x1050)
+#define EXYNOS5433_DIS_IRQ_APOLLO_CPU1_CENTRAL_SYS_PWR_REG	(0x1058)
+#define EXYNOS5433_APOLLO_CPU2_SYS_PWR_REG			(0x1060)
+#define EXYNOS5433_DIS_IRQ_APOLLO_CPU2_CENTRAL_SYS_PWR_REG	(0x1068)
+#define EXYNOS5433_APOLLO_CPU3_SYS_PWR_REG			(0x1070)
+#define EXYNOS5433_DIS_IRQ_APOLLO_CPU3_CENTRAL_SYS_PWR_REG	(0x1078)
+#define EXYNOS5433_ATLAS_NONCPU_SYS_PWR_REG			(0x1080)
+#define EXYNOS5433_ATLAS_L2_SYS_PWR_REG				(0x10C0)
+#define EXYNOS5433_APOLLO_L2_SYS_PWR_REG			(0x10C4)
+#define EXYNOS5433_APOLLO_NONCPU_SYS_PWR_REG			(0x1084)
+#define EXYNOS5433_A5IS_SYS_PWR_REG				(0x10B0)
+#define EXYNOS5433_DIS_IRQ_A5IS_LOCAL_SYS_PWR_REG		(0x10B4)
+#define EXYNOS5433_DIS_IRQ_A5IS_CENTRAL_SYS_PWR_REG		(0x10B8)
+#define EXYNOS5433_CLKSTOP_CMU_TOP_SYS_PWR_REG			(0x1100)
+#define EXYNOS5433_CLKRUN_CMU_TOP_SYS_PWR_REG			(0x1104)
+#define EXYNOS5433_RESET_CMU_TOP_SYS_PWR_REG			(0x110C)
+#define EXYNOS5433_RESET_CPUCLKSTOP_SYS_PWR_REG			(0x111C)
+#define EXYNOS5433_CLKSTOP_CMU_MIF_SYS_PWR_REG			(0x1120)
+#define EXYNOS5433_CLKRUN_CMU_MIF_SYS_PWR_REG			(0x1124)
+#define EXYNOS5433_RESET_CMU_MIF_SYS_PWR_REG			(0x112C)
+#define EXYNOS5433_DDRPHY_DLLLOCK_SYS_PWR_REG			(0x1138)
+#define EXYNOS5433_DISABLE_PLL_CMU_TOP_SYS_PWR_REG		(0x1140)
+#define EXYNOS5433_DISABLE_PLL_AUD_PLL_SYS_PWR_REG		(0x1144)
+#define EXYNOS5433_DISABLE_PLL_CMU_MIF_SYS_PWR_REG		(0x1160)
+#define EXYNOS5433_TOP_BUS_SYS_PWR_REG				(0x1180)
+#define EXYNOS5433_TOP_RETENTION_SYS_PWR_REG			(0x1184)
+#define EXYNOS5433_TOP_PWR_SYS_PWR_REG				(0x1188)
+#define EXYNOS5433_TOP_BUS_MIF_SYS_PWR_REG			(0x1190)
+#define EXYNOS5433_TOP_RETENTION_MIF_SYS_PWR_REG		(0x1194)
+#define EXYNOS5433_TOP_PWR_MIF_SYS_PWR_REG			(0x1198)
+#define EXYNOS5433_LOGIC_RESET_SYS_PWR_REG			(0x11A0)
+#define EXYNOS5433_OSCCLK_GATE_SYS_PWR_REG			(0x11A4)
+#define EXYNOS5433_SLEEP_RESET_SYS_PWR_REG			(0x11A8)
+#define EXYNOS5433_LOGIC_RESET_MIF_SYS_PWR_REG			(0x11B0)
+#define EXYNOS5433_OSCCLK_GATE_MIF_SYS_PWR_REG			(0x11B4)
+#define EXYNOS5433_SLEEP_RESET_MIF_SYS_PWR_REG			(0x11B8)
+#define EXYNOS5433_MEMORY_TOP_SYS_PWR_REG			(0x11C0)
+#define EXYNOS5433_PAD_RETENTION_LPDDR3_SYS_PWR_REG		(0x1200)
+#define EXYNOS5433_PAD_RETENTION_JTAG_SYS_PWR_REG		(0x1208)
+#define EXYNOS5433_PAD_RETENTION_TOP_SYS_PWR_REG		(0x1220)
+#define EXYNOS5433_PAD_RETENTION_UART_SYS_PWR_REG		(0x1224)
+#define EXYNOS5433_PAD_RETENTION_EBIA_SYS_PWR_REG		(0x1230)
+#define EXYNOS5433_PAD_RETENTION_EBIB_SYS_PWR_REG		(0x1234)
+#define EXYNOS5433_PAD_RETENTION_SPI_SYS_PWR_REG		(0x1238)
+#define EXYNOS5433_PAD_RETENTION_MIF_SYS_PWR_REG		(0x123C)
+#define EXYNOS5433_PAD_ISOLATION_SYS_PWR_REG			(0x1240)
+#define EXYNOS5433_PAD_RETENTION_USBXTI_SYS_PWR_REG		(0x1244)
+#define EXYNOS5433_PAD_RETENTION_BOOTLDO_SYS_PWR_REG		(0x1248)
+#define EXYNOS5433_PAD_ISOLATION_MIF_SYS_PWR_REG		(0x1250)
+#define EXYNOS5433_PAD_RETENTION_FSYSGENIO_SYS_PWR_REG		(0x1254)
+#define EXYNOS5433_PAD_ALV_SEL_SYS_PWR_REG			(0x1260)
+#define EXYNOS5433_XXTI_SYS_PWR_REG				(0x1284)
+#define EXYNOS5433_XXTI26_SYS_PWR_REG				(0x1288)
+#define EXYNOS5433_EXT_REGULATOR_SYS_PWR_REG			(0x12C0)
+#define EXYNOS5433_GPIO_MODE_SYS_PWR_REG			(0x1300)
+#define EXYNOS5433_GPIO_MODE_FSYS0_SYS_PWR_REG			(0x1304)
+#define EXYNOS5433_GPIO_MODE_MIF_SYS_PWR_REG			(0x1320)
+#define EXYNOS5433_GPIO_MODE_AUD_SYS_PWR_REG			(0x1340)
+#define EXYNOS5433_GSCL_SYS_PWR_REG				(0x1400)
+#define EXYNOS5433_CAM0_SYS_PWR_REG				(0x1404)
+#define EXYNOS5433_MSCL_SYS_PWR_REG				(0x1408)
+#define EXYNOS5433_G3D_SYS_PWR_REG				(0x140C)
+#define EXYNOS5433_DISP_SYS_PWR_REG				(0x1410)
+#define EXYNOS5433_CAM1_SYS_PWR_REG				(0x1414)
+#define EXYNOS5433_AUD_SYS_PWR_REG				(0x1418)
+#define EXYNOS5433_FSYS_SYS_PWR_REG				(0x141C)
+#define EXYNOS5433_BUS2_SYS_PWR_REG				(0x1420)
+#define EXYNOS5433_G2D_SYS_PWR_REG				(0x1424)
+#define EXYNOS5433_ISP0_SYS_PWR_REG				(0x1428)
+#define EXYNOS5433_MFC_SYS_PWR_REG				(0x1430)
+#define EXYNOS5433_HEVC_SYS_PWR_REG				(0x1438)
+#define EXYNOS5433_RESET_SLEEP_FSYS_SYS_PWR_REG			(0x15DC)
+#define EXYNOS5433_RESET_SLEEP_BUS2_SYS_PWR_REG			(0x15E0)
+#define EXYNOS5433_ATLAS_CPU0_OPTION				(0x2008)
+#define EXYNOS5433_CPU_OPTION(_nr)				(EXYNOS5433_ATLAS_CPU0_OPTION + (_nr) * 0x80)
+#define EXYNOS5433_ATLAS_CPU0_DURATION0				(0x2010)
+#define EXYNOS5433_CPU_DURATION(_nr)				(EXYNOS5433_ATLAS_CPU0_DURATION0 + (_nr) * 0x80)
+#define EXYNOS5433_ATLAS_NONCPU_OPTION				(0x2408)
+#define EXYNOS5433_APOLLO_NONCPU_OPTION				(0x2428)
+#define EXYNOS5433_ATLAS_CPUSEQUENCER_OPTION			(0x2488)
+#define EXYNOS5433_ATLAS_L2_OPTION				(0x2608)
+#define EXYNOS5433_TOP_PWR_MIF_OPTION				(0x2CC8)
+#define EXYNOS5433_TOP_PWR_OPTION				(0x2C48)
+#define EXYNOS5433_PAD_RETENTION_LPDDR3_OPTION			(0x3008)
 #define EXYNOS5433_PAD_RETENTION_AUD_OPTION			(0x3028)
 #define EXYNOS5433_PAD_RETENTION_MMC2_OPTION			(0x30C8)
 #define EXYNOS5433_PAD_RETENTION_TOP_OPTION			(0x3108)
@@ -660,5 +763,50 @@
 #define EXYNOS5433_PAD_RETENTION_BOOTLDO_OPTION			(0x3248)
 #define EXYNOS5433_PAD_RETENTION_UFS_OPTION			(0x3268)
 #define EXYNOS5433_PAD_RETENTION_FSYSGENIO_OPTION		(0x32A8)
+#define EXYNOS5433_PS_HOLD_CONTROL				(0x330C)
+#define EXYNOS5433_GSCL_OPTION					(0x4008)
+#define EXYNOS5433_CAM0_OPTION					(0x4028)
+#define EXYNOS5433_MSCL_OPTION					(0x4048)
+#define EXYNOS5433_G3D_OPTION					(0x4068)
+#define EXYNOS5433_DISP_OPTION					(0x4088)
+#define EXYNOS5433_AUD_OPTION					(0x40C8)
+#define EXYNOS5433_FSYS_OPTION					(0x40E8)
+#define EXYNOS5433_BUS2_OPTION					(0x4108)
+#define EXYNOS5433_G2D_OPTION					(0x4128)
+#define EXYNOS5433_ISP_OPTION					(0x4148)
+#define EXYNOS5433_MFC_OPTION					(0x4188)
+#define EXYNOS5433_HEVC_OPTION					(0x41C8)
+
+/* EXYNOS5433_PMU_SPARE0 */
+#define EXYNOS5433_EN_NONRET_RESET				(1 << 0)
+
+/* EXYNOS5433_CENTRAL_SEQ_CONFIGURATION */
+#define EXYNOS5433_CENTRALSEQ_PWR_CFG				(0x1 << 16)
+
+/* EXYNOS5433_ATLAS_L2_OPTION */
+#define EXYNOS5433_USE_DEACTIVATE_ACE				(0x1 << 19)
+#define EXYNOS5433_USE_DEACTIVATE_ACP				(0x1 << 18)
+#define EXYNOS5433_USE_AUTO_L2FLUSHREQ				(0x1 << 17)
+#define EXYNOS5433_USE_STANDBYWFIL2				(0x1 << 16)
+#define EXYNOS5433_USE_RETENTION				(0x1 << 4)
+
+/* EXYNOS5433_CPU_OPTION */
+#define EXYNOS5433_USE_SMPEN					(0x1 << 28)
+#define EXYNOS5433_USE_STANDBYWFE				(0x1 << 24)
+#define EXYNOS5433_USE_STANDBYWFI				(0x1 << 16)
+
+/* EXYNOS5433_PAD_RETENTION_*_OPTION */
+#define EXYNOS5433_INITIATE_WAKEUP_FROM_LOWPOWER		(0x1 << 28)
+
+/* EXYNOS5433_CPU_DURATION */
+#define EXYNOS5433_DUR_WAIT_RESET				(0xF << 20)
+#define EXYNOS5433_DUR_SCALL					(0xF << 4)
+#define EXYNOS5433_DUR_SCALL_VALUE				(0x1 << 4)
+
+/* EXYNOS5433_ATLAS_CPUSEQUENCER_OPTION */
+#define EXYNOS5433_SKIP_BLK_PWR_DOWN				(0x1 << 8)
+
+/* EXYNOS5433_UP_SCHEDULER */
+#define EXYNOS5433_ENABLE_ATLAS_CPU				(0x1 << 0)
 
 #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/9] soc: samsung: pmu: Add powerup_conf callback
From: Chanwoo Choi @ 2018-01-09  7:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515484746-10656-1-git-send-email-cw00.choi@samsung.com>

This patch adds the powerup_conf callback which is used to re-initialize
the PMU registers during the resume state.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/soc/samsung/exynos-pmu.c       | 8 ++++++++
 drivers/soc/samsung/exynos-pmu.h       | 1 +
 include/linux/soc/samsung/exynos-pmu.h | 1 +
 3 files changed, 10 insertions(+)

diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index f56adbd9fb8b..cfc9de518344 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -58,6 +58,14 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode)
 		pmu_data->powerdown_conf_extra(mode);
 }
 
+void exynos_sys_powerup_conf(enum sys_powerdown mode)
+{
+	const struct exynos_pmu_data *pmu_data = pmu_context->pmu_data;
+
+	if (pmu_data->powerup_conf)
+		pmu_data->powerup_conf(mode);
+}
+
 /*
  * Split the data between ARM architectures because it is relatively big
  * and useless on other arch.
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
index 977e4daf5a0f..efbaf8929252 100644
--- a/drivers/soc/samsung/exynos-pmu.h
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -24,6 +24,7 @@ struct exynos_pmu_data {
 	void (*pmu_init)(void);
 	void (*powerdown_conf)(enum sys_powerdown);
 	void (*powerdown_conf_extra)(enum sys_powerdown);
+	void (*powerup_conf)(enum sys_powerdown);
 };
 
 extern void __iomem *pmu_base_addr;
diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h
index e57eb4b6cc5a..3aacf7b18401 100644
--- a/include/linux/soc/samsung/exynos-pmu.h
+++ b/include/linux/soc/samsung/exynos-pmu.h
@@ -22,6 +22,7 @@ enum sys_powerdown {
 };
 
 extern void exynos_sys_powerdown_conf(enum sys_powerdown mode);
+extern void exynos_sys_powerup_conf(enum sys_powerdown mode);
 #ifdef CONFIG_EXYNOS_PMU
 extern struct regmap *exynos_get_pmu_regmap(void);
 #else
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/9] clk: samsung: exynos5433: Add clock flag to support suspend-to-ram
From: Chanwoo Choi @ 2018-01-09  7:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515484746-10656-1-git-send-email-cw00.choi@samsung.com>

This patch adds the CLK_IS_CRITICAL and CLK_IGNORE_UNUSED flag
to some clocks in order to avoid the hang-out in the suspend mode.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Cc: Tomasz Figa <tomasz.figa@gmail.com>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: linux-clk at vger.kernel.org
---
 drivers/clk/samsung/clk-exynos5433.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index db270908037a..3dc53cd0c730 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -583,25 +583,25 @@
 			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
 	GATE(CLK_ACLK_CAM1_333, "aclk_cam1_333", "div_aclk_cam1_333",
 			ENABLE_ACLK_TOP, 13,
-			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_CAM1_400, "aclk_cam1_400", "div_aclk_cam1_400",
 			ENABLE_ACLK_TOP, 12,
 			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_CAM1_552, "aclk_cam1_552", "div_aclk_cam1_552",
 			ENABLE_ACLK_TOP, 11,
-			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_CAM0_333, "aclk_cam0_333", "div_aclk_cam0_333",
 			ENABLE_ACLK_TOP, 10,
-			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_CAM0_400, "aclk_cam0_400", "div_aclk_cam0_400",
 			ENABLE_ACLK_TOP, 9,
 			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_CAM0_552, "aclk_cam0_552", "div_aclk_cam0_552",
 			ENABLE_ACLK_TOP, 8,
-			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_ISP_DIS_400, "aclk_isp_dis_400", "div_aclk_isp_dis_400",
 			ENABLE_ACLK_TOP, 7,
-			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0),
+			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_ACLK_ISP_400, "aclk_isp_400", "div_aclk_isp_400",
 			ENABLE_ACLK_TOP, 6,
 			CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
@@ -624,11 +624,11 @@

 	/* ENABLE_SCLK_TOP_CAM1 */
 	GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "div_sclk_isp_sensor2_b",
-			ENABLE_SCLK_TOP_CAM1, 7, 0, 0),
+			ENABLE_SCLK_TOP_CAM1, 7, CLK_IGNORE_UNUSED, 0),
 	GATE(CLK_SCLK_ISP_SENSOR1, "sclk_isp_sensor1", "div_sclk_isp_sensor1_b",
 			ENABLE_SCLK_TOP_CAM1, 6, 0, 0),
 	GATE(CLK_SCLK_ISP_SENSOR0, "sclk_isp_sensor0", "div_sclk_isp_sensor0_b",
-			ENABLE_SCLK_TOP_CAM1, 5, 0, 0),
+			ENABLE_SCLK_TOP_CAM1, 5, CLK_IGNORE_UNUSED, 0),
 	GATE(CLK_SCLK_ISP_MCTADC_CAM1, "sclk_isp_mctadc_cam1", "oscclk",
 			ENABLE_SCLK_TOP_CAM1, 4, 0, 0),
 	GATE(CLK_SCLK_ISP_UART_CAM1, "sclk_isp_uart_cam1", "div_sclk_isp_uart",
@@ -636,7 +636,7 @@
 	GATE(CLK_SCLK_ISP_SPI1_CAM1, "sclk_isp_spi1_cam1", "div_sclk_isp_spi1_b",
 			ENABLE_SCLK_TOP_CAM1, 1, 0, 0),
 	GATE(CLK_SCLK_ISP_SPI0_CAM1, "sclk_isp_spi0_cam1", "div_sclk_isp_spi0_b",
-			ENABLE_SCLK_TOP_CAM1, 0, 0, 0),
+			ENABLE_SCLK_TOP_CAM1, 0, CLK_IGNORE_UNUSED, 0),

 	/* ENABLE_SCLK_TOP_DISP */
 	GATE(CLK_SCLK_HDMI_SPDIF_DISP, "sclk_hdmi_spdif_disp",
@@ -654,7 +654,7 @@
 			ENABLE_SCLK_TOP_FSYS, 4, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_UFSUNIPRO_FSYS, "sclk_ufsunipro_fsys",
 			"div_sclk_ufsunipro", ENABLE_SCLK_TOP_FSYS,
-			3, CLK_SET_RATE_PARENT, 0),
+			3, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0),
 	GATE(CLK_SCLK_USBHOST30_FSYS, "sclk_usbhost30_fsys",
 			"div_sclk_usbhost30", ENABLE_SCLK_TOP_FSYS,
 			1, CLK_SET_RATE_PARENT, 0),
@@ -2982,7 +2982,7 @@ static void __init exynos5433_cmu_peris_init(struct device_node *np)
 	GATE(CLK_PCLK_AUD_SLIMBUS, "pclk_aud_slimbus", "div_aclk_aud",
 			ENABLE_PCLK_AUD, 6, 0, 0),
 	GATE(CLK_PCLK_AUD_UART, "pclk_aud_uart", "div_aclk_aud",
-			ENABLE_PCLK_AUD, 5, 0, 0),
+			ENABLE_PCLK_AUD, 5, CLK_IS_CRITICAL, 0),
 	GATE(CLK_PCLK_AUD_PCM, "pclk_aud_pcm", "div_aclk_aud",
 			ENABLE_PCLK_AUD, 4, 0, 0),
 	GATE(CLK_PCLK_AUD_I2S, "pclk_aud_i2s", "div_aclk_aud",
@@ -3008,7 +3008,7 @@ static void __init exynos5433_cmu_peris_init(struct device_node *np)
 	GATE(CLK_SCLK_AUD_SLIMBUS, "sclk_aud_slimbus", "div_sclk_aud_slimbus",
 			ENABLE_SCLK_AUD1, 4, 0, 0),
 	GATE(CLK_SCLK_AUD_UART, "sclk_aud_uart", "div_sclk_aud_uart",
-			ENABLE_SCLK_AUD1, 3, CLK_IGNORE_UNUSED, 0),
+			ENABLE_SCLK_AUD1, 3, CLK_IS_CRITICAL, 0),
 	GATE(CLK_SCLK_AUD_PCM, "sclk_aud_pcm", "div_sclk_aud_pcm",
 			ENABLE_SCLK_AUD1, 2, 0, 0),
 	GATE(CLK_SCLK_I2S_BCLK, "sclk_i2s_bclk", "ioclk_i2s_bclk",
--
1.9.1

^ permalink raw reply related

* [RFC PATCH 0/9] soc: samsung: Add support of suspend-to-RAM on Exynos5433
From: Chanwoo Choi @ 2018-01-09  7:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CGME20180109075904epcas2p302d58aacfbb2195e455a25c90a1c610b@epcas2p3.samsung.com>

In the mainline, there is no case to support the suspend-to-RAM for Samsung
Exynos SoC. This patchset support the suspend-to-RAM for 64bit Exynos SoC.

For 32bit, arch/arm/mach-exynos/* directoy contains the suspend-related
codes such as suspend.c/exynos.c. But, 64bit Exynos should contain
the suspend-related codes in the drivers/soc/samsung/*. So, this patchset
develop the patch4/5 for drivers/soc/samsung/exynos-pm.c. to support suspend
64bit Exynos SoC.

But, I'm not sure what is proper approach for both 32/64bit Exynos.
- Approach1 : Split out the supend-related codes between 32/64bit.
  : arch/arm/mach-exynos/* contains the suspend-related codes for 32bit.
  : drivers/soc/samsung/* contains the suspend-related codes for 64bit.
- Approach2 : Consolidate the all suspend-related codes to drivers/soc/samsung/.

Please let us know your opinion.

The patch1/2/3 and 6/7/8/9 is just general patch. So, I add 'RFC' prefix to
only cover-letter, patch4/5. If you want to add the 'RFC' prefix to all
patches, I'll add 'RFC' prefix on v2.

Based on:
- git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git (branch: for-next)

Need to discuss patch4/5:
- patch4: soc: samsung: Add generic power-management driver for Exynos
- patch5: soc: samsung: pm: Add support for suspend-to-ram of Exynos5433

[Remaining Issues]
- The hang-out happen when disabling the MMC clocks on dw_mmc.c.
  I reported to Jaehoon Chung. He is checking this issue. To test the
  suspend-to-ram temporarily, you need to add CLK_IS_CRITICAL flag to
  'aclk_mmc2/aclk_mmc0/sclk_mmc2/sclk_mmc0'.
- I enabled the at least kernel configuration in order to test
  the suspend-to-RAM. So, I need to test it more time with DRM/Multimedia
  and other. But, the suspend-to-RAM of cpu is successful.
- Exynos5433 SoC has two EXYNOS5433_EINT_WAKEUP_MASKx registers. The
  pinctr-exynos.c need to handle the extra EINT_WAKEUP_MASKx for Exynos5433.
  The suspend-to-ram test is failed on first time and then next tryout is ok.
  I'm developing it.

Chanwoo Choi (9):
  clk: samsung: exynos5433: Add clock flag to support suspend-to-ram
  soc: samsung: pmu: Add powerup_conf callback
  soc: samsung: pmu: Add the PMU data of exynos5433 to support low-power state
  soc: samsung: Add generic power-management driver for Exynos
  soc: samsung: pm: Add support for suspend-to-ram of Exynos5433
  arm64: dts: exynos: Add iRAM device-tree node for Exynos5433
  arm64: dts: exynos: Use power key as a wakeup source on TM2/TM2E board
  arm64: dts: exynos: Add cpu_suspend property of PSCI for exynos5433
  arm64: dts: exynos: Add cpu topology information for Exynos5433 SoC

 arch/arm/mach-exynos/common.h                      |   3 -
 arch/arm/mach-exynos/exynos.c                      |  23 +-
 .../boot/dts/exynos/exynos5433-tm2-common.dtsi     |   1 +
 arch/arm64/boot/dts/exynos/exynos5433.dtsi         |  47 ++++
 drivers/clk/samsung/clk-exynos5433.c               |  22 +-
 drivers/soc/samsung/Makefile                       |   5 +-
 drivers/soc/samsung/exynos-pm.c                    | 214 +++++++++++++++
 drivers/soc/samsung/exynos-pmu.c                   |   9 +
 drivers/soc/samsung/exynos-pmu.h                   |   3 +
 drivers/soc/samsung/exynos5433-pmu.c               | 286 +++++++++++++++++++++
 include/linux/soc/samsung/exynos-pm.h              |  21 ++
 include/linux/soc/samsung/exynos-pmu.h             |   1 +
 include/linux/soc/samsung/exynos-regs-pmu.h        | 148 +++++++++++
 13 files changed, 745 insertions(+), 38 deletions(-)
 create mode 100644 drivers/soc/samsung/exynos-pm.c
 create mode 100644 drivers/soc/samsung/exynos5433-pmu.c
 create mode 100644 include/linux/soc/samsung/exynos-pm.h

--
1.9.1

^ permalink raw reply

* [PATCH 00/12] Marvell NAND controller rework with ->exec_op()
From: Robert Jarzmik @ 2018-01-09  7:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180103215206.5d85b41b@bbrezillon>

Boris Brezillon <boris.brezillon@free-electrons.com> writes:

Ok I recovered my NAND.

For the next try, I'd like you to provide another "temporary patch" to disable
BBT actual writing, just to be sure. Once the driver is working properly, I'll
make another try without the temporary patch.

Tell me when a branch I can pull is ready.

Cheers.

-- 
Robert

^ permalink raw reply

* [PATCH v2 1/4] dmaengine: xilinx_dma: populate dma caps properly
From: Appana Durga Kedareswara Rao @ 2018-01-09  7:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180109050449.GO18649@localhost>

Hi,

	Thanks for the review... 

>On Tue, Jan 09, 2018 at 04:48:10AM +0000, Appana Durga Kedareswara Rao
>wrote:
>> Hi,
>>
>> >On Mon, Jan 08, 2018 at 05:25:01PM +0000, Appana Durga Kedareswara
>> >Rao
>> >wrote:
>> >> Hi,
>> >>
>> >> <Snip>
>> >> >> >> +	xdev->common.dst_addr_widths = BIT(addr_width / 8);
>> >> >> >> +	xdev->common.src_addr_widths = BIT(addr_width / 8);
>> >> >> >
>> >> >> >Do you not support trf of 1byte, 2 bytes, or 4 bytes wide transfers?
>> >> >> >What is value of addr_width here typically? Usually controllers
>> >> >> >can support different widths and this is a surprise that you
>> >> >> >support only one value
>> >> >>
>> >> >> Controller supports address width of 32 and 64.
>> >> >
>> >> >Then this should have both 32 and 64 values here
>> >>
>> >> Address width is configurable parameter at the h/w level.
>> >> Since this IP is a soft IP user can create a design with either
>> >> 32-bit or 64-bit address configuration.
>> >
>> >and not both right?
>>
>> Yes not both at the same time...
>> Axi dma controller can be configured for either 32-bit or 64-bit address...
>
>So my suspicion was correct.  I would suggest you to read up on the
>documentation again. The src/dst_addr_widths has _nothing_ to do with 32/64
>bit addresses used.
>
>It is the capability of the dma controller to do transfers with data width as 8bits,
>16 bits, so on. iKey is "data width" and not address type.
>This typically translates to DMA FIFO configuration of the controller!

Thanks for the detailed explanation... 
I have gone through the spec again controller does supports 1 byte, 2 byte, 4 byte up to 128 byte transfers.
In order to do variable length transfers user needs to drive a valid value to the tkeep strobe signal at the h/w level.
And user needs to configure the below parameters c_m_axis_mm2s_tdata_width or c_m_axis_s2mm_tdata_width
With desired configuration at the h/w level.
Controller supports data width of 8, 16, 32, 64, 128, 256, 512 and 1,024 bits 
(i.e. c_m_axis_mm2s_tdata_width/ c_m_axis_s2mm_tdata_width parameters range)

At the s/w level currently we are getting c_m_axis_mm2s_tdata_width/ c_m_axis_s2mm_tdata_width
Configuration as xlnx,datawidth property in the device-tree.

So proper values for the src/dst_addr width fields should be, datawidth property in bytes.
Please correct me if I am wrong... 

Changes looks like below...
Here width is in bytes based on the h/w configuration... 

--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -2411,6 +2411,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
                chan->direction = DMA_MEM_TO_DEV;
                chan->id = chan_id;
                chan->tdest = chan_id;
+               xdev->common.directions = BIT(DMA_MEM_TO_DEV);
+               xdev->common.src_addr_widths = BIT(width);
 
                chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
                if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
@@ -2428,6 +2430,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
                chan->direction = DMA_DEV_TO_MEM;
                chan->id = chan_id;
                chan->tdest = chan_id - xdev->nr_channels;
+               xdev->common.directions |= BIT(DMA_DEV_TO_MEM);
+               xdev->common.dst_addr_widths = BIT(width);
 
                chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
                if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {


Regards,
Kedar.

>
>--
>~Vinod

^ permalink raw reply

* [PATCH v7 9/9] arm: omap: pdata-quirks: Remove unused timer pdata
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Remove unused timer pdata.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 arch/arm/mach-omap2/pdata-quirks.c | 32 --------------------------------
 1 file changed, 32 deletions(-)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index ad9df86..e7d7fc7 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -24,10 +24,8 @@
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/platform_data/iommu-omap.h>
 #include <linux/platform_data/wkup_m3.h>
-#include <linux/platform_data/pwm_omap_dmtimer.h>
 #include <linux/platform_data/media/ir-rx51.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <clocksource/dmtimer.h>
 
 #include "common.h"
 #include "common-board-devices.h"
@@ -477,33 +475,6 @@ void omap_auxdata_legacy_init(struct device *dev)
 	dev->platform_data = &twl_gpio_auxdata;
 }
 
-/* Dual mode timer PWM callbacks platdata */
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
-	.request_by_node = omap_dm_timer_request_by_node,
-	.request_specific = omap_dm_timer_request_specific,
-	.request = omap_dm_timer_request,
-	.set_source = omap_dm_timer_set_source,
-	.get_irq = omap_dm_timer_get_irq,
-	.set_int_enable = omap_dm_timer_set_int_enable,
-	.set_int_disable = omap_dm_timer_set_int_disable,
-	.free = omap_dm_timer_free,
-	.enable = omap_dm_timer_enable,
-	.disable = omap_dm_timer_disable,
-	.get_fclk = omap_dm_timer_get_fclk,
-	.start = omap_dm_timer_start,
-	.stop = omap_dm_timer_stop,
-	.set_load = omap_dm_timer_set_load,
-	.set_match = omap_dm_timer_set_match,
-	.set_pwm = omap_dm_timer_set_pwm,
-	.set_prescaler = omap_dm_timer_set_prescaler,
-	.read_counter = omap_dm_timer_read_counter,
-	.write_counter = omap_dm_timer_write_counter,
-	.read_status = omap_dm_timer_read_status,
-	.write_status = omap_dm_timer_write_status,
-};
-#endif
-
 static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
 	.set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
 };
@@ -572,9 +543,6 @@ static void __init omap3_mcbsp_init(void) {}
 	OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3",
 		       &wkup_m3_data),
 #endif
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-	OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, &pwm_dmtimer_pdata),
-#endif
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
 	OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
 		       &omap4_iommu_pdata),
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 8/9] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
 drivers/pwm/pwm-omap-dmtimer.c | 68 ++++++++++++++++++++++++++----------------
 1 file changed, 43 insertions(+), 25 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..cc485d9 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/dmtimer-omap.h>
 #include <linux/platform_data/pwm_omap_dmtimer.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
 	struct pwm_chip chip;
 	struct mutex mutex;
 	pwm_omap_dmtimer *dm_timer;
-	struct pwm_omap_dmtimer_pdata *pdata;
+	struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *timer;
+	struct platform_device *timer_pdev;
 	struct pwm_omap_dmtimer_chip *omap;
-	struct pwm_omap_dmtimer_pdata *pdata;
+	struct dmtimer_platform_data *timer_pdata;
+	struct omap_dm_timer_ops *pdata;
 	pwm_omap_dmtimer *dm_timer;
 	u32 v;
-	int status;
+	int status, ret;
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		dev_err(&pdev->dev, "Missing dmtimer platform data\n");
-		return -EINVAL;
+	timer = of_parse_phandle(np, "ti,timers", 0);
+	if (!timer)
+		return -ENODEV;
+
+	timer_pdev = of_find_device_by_node(timer);
+	if (!timer_pdev) {
+		dev_err(&pdev->dev, "Unable to find Timer pdev\n");
+		ret = -ENODEV;
+		goto put;
 	}
 
-	if (!pdata->request_by_node ||
+	timer_pdata = dev_get_platdata(&timer_pdev->dev);
+	if (!timer_pdata) {
+		dev_err(&pdev->dev, "dmtimer pdata structure NULL\n");
+		ret = -EINVAL;
+		goto put;
+	}
+
+	pdata = timer_pdata->timer_ops;
+
+	if (!pdata || !pdata->request_by_node ||
 	    !pdata->free ||
 	    !pdata->enable ||
 	    !pdata->disable ||
@@ -267,37 +284,32 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	    !pdata->set_prescaler ||
 	    !pdata->write_counter) {
 		dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto put;
 	}
 
-	timer = of_parse_phandle(np, "ti,timers", 0);
-	if (!timer)
-		return -ENODEV;
-
 	if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
 		dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto put;
 	}
 
 	dm_timer = pdata->request_by_node(timer);
-	if (!dm_timer)
-		return -EPROBE_DEFER;
+	if (!dm_timer) {
+		ret = -EPROBE_DEFER;
+		goto put;
+	}
 
 	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
 	if (!omap) {
 		pdata->free(dm_timer);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto put;
 	}
 
 	omap->pdata = pdata;
 	omap->dm_timer = dm_timer;
-
-	omap->dm_timer_pdev = of_find_device_by_node(timer);
-	if (!omap->dm_timer_pdev) {
-		dev_err(&pdev->dev, "Unable to find timer pdev\n");
-		omap->pdata->free(dm_timer);
-		return -EINVAL;
-	}
+	omap->dm_timer_pdev = timer_pdev;
 
 	/*
 	 * Ensure that the timer is stopped before we allow PWM core to call
@@ -326,12 +338,18 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	if (status < 0) {
 		dev_err(&pdev->dev, "failed to register PWM\n");
 		omap->pdata->free(omap->dm_timer);
-		return status;
+		ret = status;
+		goto put;
 	}
 
 	platform_set_drvdata(pdev, omap);
 
 	return 0;
+
+put:
+	of_node_put(timer);
+
+	return ret;
 }
 
 static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 7/9] clocksource: timer-dm: Hook device platform data if not already assigned
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

From: Ladislav Michl <ladis@linux-mips.org>

In the case of device tree boot the device platform data is usually
NULL so hook the platform data obtained from the match.
As part of un-constify the platform_data pointer.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 drivers/clocksource/timer-dm.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index 1cbd954..60db173 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -806,14 +806,16 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
 	struct omap_dm_timer *timer;
 	struct resource *mem, *irq;
 	struct device *dev = &pdev->dev;
-	const struct of_device_id *match;
 	const struct dmtimer_platform_data *pdata;
 	int ret;
 
-	match = of_match_device(of_match_ptr(omap_timer_match), dev);
-	pdata = match ? match->data : dev->platform_data;
+	pdata = of_device_get_match_data(dev);
+	if (!pdata)
+		pdata = dev_get_platdata(dev);
+	else
+		dev->platform_data = (void *)pdata;
 
-	if (!pdata && !dev->of_node) {
+	if (!pdata) {
 		dev_err(dev, "%s: no platform data.\n", __func__);
 		return -ENODEV;
 	}
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 6/9] clocksource: dmtimer: Populate the timer ops to the pdata
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Add the timer ops to the platform data

Signed-off-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-dm.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index afe1dc9..1cbd954 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -922,8 +922,33 @@ static int omap_dm_timer_remove(struct platform_device *pdev)
 	return ret;
 }
 
+static struct omap_dm_timer_ops dmtimer_ops = {
+	.request_by_node = omap_dm_timer_request_by_node,
+	.request_specific = omap_dm_timer_request_specific,
+	.request = omap_dm_timer_request,
+	.set_source = omap_dm_timer_set_source,
+	.get_irq = omap_dm_timer_get_irq,
+	.set_int_enable = omap_dm_timer_set_int_enable,
+	.set_int_disable = omap_dm_timer_set_int_disable,
+	.free = omap_dm_timer_free,
+	.enable = omap_dm_timer_enable,
+	.disable = omap_dm_timer_disable,
+	.get_fclk = omap_dm_timer_get_fclk,
+	.start = omap_dm_timer_start,
+	.stop = omap_dm_timer_stop,
+	.set_load = omap_dm_timer_set_load,
+	.set_match = omap_dm_timer_set_match,
+	.set_pwm = omap_dm_timer_set_pwm,
+	.set_prescaler = omap_dm_timer_set_prescaler,
+	.read_counter = omap_dm_timer_read_counter,
+	.write_counter = omap_dm_timer_write_counter,
+	.read_status = omap_dm_timer_read_status,
+	.write_status = omap_dm_timer_write_status,
+};
+
 static const struct dmtimer_platform_data omap3plus_pdata = {
 	.timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+	.timer_ops = &dmtimer_ops,
 };
 
 static const struct of_device_id omap_timer_match[] = {
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 5/9] dmtimer: Add timer ops to the platform data structure
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Add timer ops to the platform data structure

Signed-off-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 include/linux/platform_data/dmtimer-omap.h | 38 ++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h
index a19b78d..a3e1794 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -20,12 +20,50 @@
 #ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__
 #define __PLATFORM_DATA_DMTIMER_OMAP_H__
 
+struct omap_dm_timer_ops {
+	struct omap_dm_timer *(*request_by_node)(struct device_node *np);
+	struct omap_dm_timer *(*request_specific)(int timer_id);
+	struct omap_dm_timer *(*request)(void);
+
+	int	(*free)(struct omap_dm_timer *timer);
+
+	void	(*enable)(struct omap_dm_timer *timer);
+	void	(*disable)(struct omap_dm_timer *timer);
+
+	int	(*get_irq)(struct omap_dm_timer *timer);
+	int	(*set_int_enable)(struct omap_dm_timer *timer,
+				  unsigned int value);
+	int	(*set_int_disable)(struct omap_dm_timer *timer, u32 mask);
+
+	struct clk *(*get_fclk)(struct omap_dm_timer *timer);
+
+	int	(*start)(struct omap_dm_timer *timer);
+	int	(*stop)(struct omap_dm_timer *timer);
+	int	(*set_source)(struct omap_dm_timer *timer, int source);
+
+	int	(*set_load)(struct omap_dm_timer *timer, int autoreload,
+			    unsigned int value);
+	int	(*set_match)(struct omap_dm_timer *timer, int enable,
+			     unsigned int match);
+	int	(*set_pwm)(struct omap_dm_timer *timer, int def_on,
+			   int toggle, int trigger);
+	int	(*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
+
+	unsigned int (*read_counter)(struct omap_dm_timer *timer);
+	int	(*write_counter)(struct omap_dm_timer *timer,
+				 unsigned int value);
+	unsigned int (*read_status)(struct omap_dm_timer *timer);
+	int	(*write_status)(struct omap_dm_timer *timer,
+				unsigned int value);
+};
+
 struct dmtimer_platform_data {
 	/* set_timer_src - Only used for OMAP1 devices */
 	int (*set_timer_src)(struct platform_device *pdev, int source);
 	u32 timer_capability;
 	u32 timer_errata;
 	int (*get_context_loss_count)(struct device *);
+	struct omap_dm_timer_ops *timer_ops;
 };
 
 #endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 4/9] arm: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Move the dmtimer driver out of plat-omap to clocksource.
So that non-omap devices also could use this.

No Code changes done to the driver file only renamed to timer-dm.c.
Also removed the config dependencies for OMAP_DM_TIMER.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 arch/arm/plat-omap/Kconfig                                     | 6 ------
 arch/arm/plat-omap/Makefile                                    | 1 -
 drivers/clocksource/Kconfig                                    | 3 +++
 drivers/clocksource/Makefile                                   | 1 +
 arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c | 0
 5 files changed, 4 insertions(+), 7 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c (100%)

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7276afe..afc1a1d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -106,12 +106,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
 	help
 	  PPA routine service ID for setting L2 auxiliary control register.
 
-config OMAP_DM_TIMER
-	bool "Use dual-mode timer"
-	depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
-	help
-	 Select this option if you want to use OMAP Dual-Mode timers.
-
 config OMAP_SERIAL_WAKE
 	bool "Enable wake-up events for serial ports"
 	depends on ARCH_OMAP1 && OMAP_MUX
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 47e1867..7215ada 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -9,5 +9,4 @@ obj-y := sram.o dma.o counter_32k.o
 
 # omap_device support (OMAP2+ only at the moment)
 
-obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index c729a88..3f799b2 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -21,6 +21,9 @@ config CLKEVT_I8253
 config I8253_LOCK
 	bool
 
+config OMAP_DM_TIMER
+	bool
+
 config CLKBLD_I8253
 	def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1..27b5497 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EM_TIMER_STI)	+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
 obj-$(CONFIG_DIGICOLOR_TIMER)	+= timer-digicolor.o
+obj-$(CONFIG_OMAP_DM_TIMER)	+= timer-dm.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_FTTMR010_TIMER)	+= timer-fttmr010.o
diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-dm.c
similarity index 100%
rename from arch/arm/plat-omap/dmtimer.c
rename to drivers/clocksource/timer-dm.c
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 3/9] arm: omap: Move dmtimer.h out of plat-omap
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

The header file is currently under plat-omap directory
under arch/omap. Move this out to an accessible place.

No Code changes done to the header file.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 arch/arm/mach-omap1/pm.c                                           | 2 +-
 arch/arm/mach-omap1/timer.c                                        | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2420_data.c                         | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2430_data.c                         | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c                 | 2 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c                         | 2 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c                         | 2 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c                         | 2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c                          | 2 +-
 arch/arm/mach-omap2/omap_hwmod_81xx_data.c                         | 2 +-
 arch/arm/mach-omap2/pdata-quirks.c                                 | 2 +-
 arch/arm/mach-omap2/timer.c                                        | 2 +-
 arch/arm/plat-omap/dmtimer.c                                       | 2 +-
 {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h | 0
 14 files changed, 13 insertions(+), 13 deletions(-)
 rename {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h (100%)

diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index f1135bf..a07d47cf 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -55,7 +55,7 @@
 #include <mach/tc.h>
 #include <mach/mux.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include <mach/irqs.h>
 
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index 8fb1ec6..7c057ab 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -27,7 +27,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_data/dmtimer-omap.h>
 
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "soc.h"
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 0afb014..0a8b95f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -16,7 +16,7 @@
 #include <linux/i2c-omap.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 013b26b..16e3d8c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -18,7 +18,7 @@
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 4b094cb..8a65f70 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -11,7 +11,7 @@
 
 #include <linux/platform_data/gpio-omap.h>
 #include <linux/omap-dma.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 1a2f224..b030137 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -25,7 +25,7 @@
 #include "l4_3xxx.h"
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "soc.h"
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index a1901c2..51c7d62 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,7 +30,7 @@
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 988e7ea..530334e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -26,7 +26,7 @@
 #include <linux/omap-dma.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 4c2a05b..2452649 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -26,7 +26,7 @@
 #include <linux/omap-dma.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index 84f1182..94f3bb1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -18,7 +18,7 @@
 #include <linux/platform_data/gpio-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "omap_hwmod_common_data.h"
 #include "cm81xx.h"
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 6b433fc..ad9df86 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -27,7 +27,7 @@
 #include <linux/platform_data/pwm_omap_dmtimer.h>
 #include <linux/platform_data/media/ir-rx51.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 #include "common.h"
 #include "common-board-devices.h"
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index ece09c9..31c1b01 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -26,6 +26,7 @@
  * License. See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#include <clocksource/dmtimer.h>
 #include <linux/init.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
@@ -49,7 +50,6 @@
 #include "omap_hwmod.h"
 #include "omap_device.h"
 #include <plat/counter-32k.h>
-#include <plat/dmtimer.h>
 #include "omap-pm.h"
 
 #include "soc.h"
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 72565fc..afe1dc9 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -47,7 +47,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_data/dmtimer-omap.h>
 
-#include <plat/dmtimer.h>
+#include <clocksource/dmtimer.h>
 
 static u32 omap_reserved_systimers;
 static LIST_HEAD(omap_timer_list);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/include/clocksource/dmtimer.h
similarity index 100%
rename from arch/arm/plat-omap/include/plat/dmtimer.h
rename to include/clocksource/dmtimer.h
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 2/9] arm: omap: timer: Wrap the inline functions under OMAP2PLUS define
From: Keerthy @ 2018-01-09  6:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Wrap the inline functions under OMAP2PLUS/OMAP1 defines.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 arch/arm/plat-omap/include/plat/dmtimer.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index dd79f30..862ad62 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -276,6 +276,12 @@ struct omap_dm_timer {
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\
 		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
 
+/*
+ * The below are inlined to optimize code size for system timers. Other code
+ * should not need these@all, see
+ * include/linux/platform_data/pwm_omap_dmtimer.h
+ */
+#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2PLUS)
 static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
 						int posted)
 {
@@ -414,5 +420,5 @@ static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer,
 {
 	writel_relaxed(value, timer->irq_stat);
 }
-
+#endif /* CONFIG_ARCH_OMAP1 || CONFIG_ARCH_OMAP2PLUS */
 #endif /* __ASM_ARCH_DMTIMER_H */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 1/9] clocksource: dmtimer: Remove all the exports
From: Keerthy @ 2018-01-09  6:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1515478987-5786-1-git-send-email-j-keerthy@ti.com>

Remove all the unwanted exports from the driver

Signed-off-by: Keerthy <j-keerthy@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Tested-by: Ladislav Michl <ladis@linux-mips.org>
---
 arch/arm/plat-omap/dmtimer.c | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index d443e48..72565fc 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -302,7 +302,6 @@ struct omap_dm_timer *omap_dm_timer_request(void)
 {
 	return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
@@ -315,7 +314,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 
 	return _omap_dm_timer_request(REQUEST_BY_ID, &id);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
 /**
  * omap_dm_timer_request_by_cap - Request a timer by capability
@@ -330,7 +328,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
 {
 	return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
 
 /**
  * omap_dm_timer_request_by_node - Request a timer by device-tree node
@@ -346,7 +343,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 
 	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
 
 int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
@@ -359,7 +355,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer)
 	timer->reserved = 0;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_free);
 
 void omap_dm_timer_enable(struct omap_dm_timer *timer)
 {
@@ -379,13 +374,11 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
 		}
 	}
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
 void omap_dm_timer_disable(struct omap_dm_timer *timer)
 {
 	pm_runtime_put_sync(&timer->pdev->dev);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
@@ -393,7 +386,6 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 		return timer->irq;
 	return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
 
 #if defined(CONFIG_ARCH_OMAP1)
 #include <mach/hardware.h>
@@ -429,7 +421,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 	return inputmask;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #else
 
@@ -439,7 +430,6 @@ struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 		return timer->fclk;
 	return NULL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
 
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
@@ -447,7 +437,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #endif
 
@@ -461,7 +450,6 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer)
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
 
 int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
@@ -482,7 +470,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
 	timer->context.tclr = l;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 
 int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
@@ -506,7 +493,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
@@ -569,7 +555,6 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 			    unsigned int load)
@@ -595,7 +580,6 @@ int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
 
 /* Optimized set_load which removes costly spin wait in timer_start */
 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
@@ -625,7 +609,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
 	timer->context.tcrr = load;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
 
 int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 			     unsigned int match)
@@ -650,7 +633,6 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
 
 int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 			   int toggle, int trigger)
@@ -676,7 +658,6 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
 
 int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 {
@@ -699,7 +680,6 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
 
 int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
 				  unsigned int value)
@@ -716,7 +696,6 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
 
 /**
  * omap_dm_timer_set_int_disable - disable timer interrupts
@@ -747,7 +726,6 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 	omap_dm_timer_disable(timer);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable);
 
 unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
@@ -762,7 +740,6 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 
 	return l;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
 
 int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
@@ -773,7 +750,6 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
 
 unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
@@ -784,7 +760,6 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 
 	return __omap_dm_timer_read_counter(timer, timer->posted);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
 
 int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
@@ -799,7 +774,6 @@ int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 	timer->context.tcrr = value;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
 
 int omap_dm_timers_active(void)
 {
@@ -816,7 +790,6 @@ int omap_dm_timers_active(void)
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
 static const struct of_device_id omap_timer_match[];
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v7 0/9] omap: dmtimer: Move driver out of plat-omap
From: Keerthy @ 2018-01-09  6:22 UTC (permalink / raw)
  To: linux-arm-kernel

The series moves dmtimer out of plat-omap to drivers/clocksource.
The series also does a bunch of changes to pwm-omap-dmtimer code
to adapt to the driver migration and clean up plat specific
pdata-quirks and use the dmtimer platform data.

Boot tested on DRA7-EVM and AM437X-GP-EVM.
Compile tested omap1_defconfig.

This is based on top of linux-next branch.

This is tested on on IGEPv2 (OMAP3430 based) by Ladis.

Changes from V6:

  * Fixed error checking for pwm driver patch.
  * Removed one of the fixes from Ladis as per request.

Changes from V5:

  * Added couple of fixes from Ladis for  pwm-dmtimer.

Changes from v4:

  * Made OMAP_DM_TIMER config option silent.
  * Changed the driver name to timer-dm.c

Changes from v3:

  * Reverted to v2 approach of using dev_get_platdata to fetch dmtimer ops.

Changes from V2:

  * Wrapped the inline functions in header file under OMAP2PLUS
  * Added a new of helper function to fetch plat_data from of node. 

Keerthy (8):
  clocksource: dmtimer: Remove all the exports
  arm: omap: timer: Wrap the inline functions under OMAP2PLUS define
  arm: omap: Move dmtimer.h out of plat-omap
  arm: OMAP: Move dmtimer driver out of plat-omap to drivers under
    clocksource
  dmtimer: Add timer ops to the platform data structure
  clocksource: dmtimer: Populate the timer ops to the pdata
  pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops
  arm: omap: pdata-quirks: Remove unused timer pdata

Ladislav Michl (1):
  clocksource: timer-dm: Hook device platform data if not already
    assigned

 arch/arm/mach-omap1/pm.c                           |  2 +-
 arch/arm/mach-omap1/timer.c                        |  2 +-
 arch/arm/mach-omap2/omap_hwmod_2420_data.c         |  2 +-
 arch/arm/mach-omap2/omap_hwmod_2430_data.c         |  2 +-
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |  2 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c         |  2 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c         |  2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c          |  2 +-
 arch/arm/mach-omap2/omap_hwmod_81xx_data.c         |  2 +-
 arch/arm/mach-omap2/pdata-quirks.c                 | 32 ----------
 arch/arm/mach-omap2/timer.c                        |  2 +-
 arch/arm/plat-omap/Kconfig                         |  6 --
 arch/arm/plat-omap/Makefile                        |  1 -
 drivers/clocksource/Kconfig                        |  3 +
 drivers/clocksource/Makefile                       |  1 +
 .../dmtimer.c => drivers/clocksource/timer-dm.c    | 64 ++++++++++----------
 drivers/pwm/pwm-omap-dmtimer.c                     | 68 +++++++++++++---------
 .../include/plat => include/clocksource}/dmtimer.h |  8 ++-
 include/linux/platform_data/dmtimer-omap.h         | 38 ++++++++++++
 20 files changed, 134 insertions(+), 109 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c (94%)
 rename {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h (97%)

-- 
1.9.1

^ permalink raw reply

* [PATCH 2/2] iommu: Clean up of_iommu_init_fn
From: Sricharan R @ 2018-01-09  6:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1eb597bb451da7e723b83369d5dc6ee478e802f5.1515436860.git.robin.murphy@arm.com>



On 1/9/2018 12:12 AM, Robin Murphy wrote:
> Now that no more drivers rely on arbitrary early initialisation via an
> of_iommu_init_fn hook, let's clean up the redundant remnants. The
> IOMMU_OF_DECLARE() macro needs to remain for now, as the probe-deferral
> mechanism has no other nice way to detect built-in drivers before they
> have registered themselves, such that it can make the right decision.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  drivers/iommu/arm-smmu-v3.c  |  2 +-
>  drivers/iommu/arm-smmu.c     | 12 ++++++------
>  drivers/iommu/exynos-iommu.c |  2 +-
>  drivers/iommu/msm_iommu.c    |  2 +-
>  drivers/iommu/of_iommu.c     | 16 ----------------
>  drivers/iommu/qcom_iommu.c   |  2 +-
>  include/linux/of_iommu.h     |  5 +----
>  7 files changed, 11 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 57c92aa3122e..1abbf42a8bd5 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -3009,7 +3009,7 @@ static struct platform_driver arm_smmu_driver = {
>  };
>  module_platform_driver(arm_smmu_driver);
>  
> -IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
> +IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
>  
>  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
>  MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 3bdb799d3b4b..56147a2be3d0 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -2208,12 +2208,12 @@ static struct platform_driver arm_smmu_driver = {
>  };
>  module_platform_driver(arm_smmu_driver);
>  
> -IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
> -IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
> -IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
> -IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
> -IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
> -IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
> +IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
> +IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
> +IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
> +IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
> +IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
> +IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
>  
>  MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
>  MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
> diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
> index f596fcc32898..6a96a4c42153 100644
> --- a/drivers/iommu/exynos-iommu.c
> +++ b/drivers/iommu/exynos-iommu.c
> @@ -1385,4 +1385,4 @@ static int __init exynos_iommu_init(void)
>  }
>  core_initcall(exynos_iommu_init);
>  
> -IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu", NULL);
> +IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu");
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index dda1ce87a070..0d3350463a3f 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -877,7 +877,7 @@ static void __exit msm_iommu_driver_exit(void)
>  subsys_initcall(msm_iommu_driver_init);
>  module_exit(msm_iommu_driver_exit);
>  
> -IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", NULL);
> +IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu");
>  
>  MODULE_LICENSE("GPL v2");
>  MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index 50947ebb6d17..5c36a8b7656a 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -231,19 +231,3 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
>  
>  	return ops;
>  }
> -
> -static int __init of_iommu_init(void)
> -{
> -	struct device_node *np;
> -	const struct of_device_id *match, *matches = &__iommu_of_table;
> -
> -	for_each_matching_node_and_match(np, matches, &match) {
> -		const of_iommu_init_fn init_fn = match->data;
> -
> -		if (init_fn && init_fn(np))
> -			pr_err("Failed to initialise IOMMU %pOF\n", np);
> -	}
> -
> -	return 0;
> -}
> -postcore_initcall_sync(of_iommu_init);
> diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
> index c8a587d034b0..37ecc49deab8 100644
> --- a/drivers/iommu/qcom_iommu.c
> +++ b/drivers/iommu/qcom_iommu.c
> @@ -924,7 +924,7 @@ static void __exit qcom_iommu_exit(void)
>  module_init(qcom_iommu_init);
>  module_exit(qcom_iommu_exit);
>  
> -IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
> +IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
>  
>  MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
> index 13394ac83c66..0cac59db95bc 100644
> --- a/include/linux/of_iommu.h
> +++ b/include/linux/of_iommu.h
> @@ -33,9 +33,6 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
>  
>  extern struct of_device_id __iommu_of_table;
>  
> -typedef int (*of_iommu_init_fn)(struct device_node *);
> -
> -#define IOMMU_OF_DECLARE(name, compat, fn) \
> -	_OF_DECLARE(iommu, name, compat, fn, of_iommu_init_fn)
> +#define IOMMU_OF_DECLARE(name, compat)	OF_DECLARE_1(iommu, name, compat, NULL)
>  
>  #endif /* __OF_IOMMU_H */
> 


Reviewed-by: Sricharan R <sricharan@codeaurora.org>

Regards,
 Sricharan

-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* [PATCH 1/2] iommu/msm: Claim bus ops on probe
From: Sricharan R @ 2018-01-09  6:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f1a506337bf602c54f4d6d417c14ca556a5f3674.1515436860.git.robin.murphy@arm.com>



On 1/9/2018 12:12 AM, Robin Murphy wrote:
> Since the MSM IOMMU driver now probes via DT exclusively rather than
> platform data, dependent masters should be deferred until the IOMMU
> itself is ready. Thus we can do away with the early initialisation
> hook to unconditionally claim the bus ops, and instead do that only
> once an IOMMU is actually probed. Furthermore, this should also make
> the driver safe for multiplatform kernels on non-MSM SoCs.
> 
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> ---
>  drivers/iommu/msm_iommu.c | 16 +++-------------
>  1 file changed, 3 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
> index 04f4d51ffacb..dda1ce87a070 100644
> --- a/drivers/iommu/msm_iommu.c
> +++ b/drivers/iommu/msm_iommu.c
> @@ -823,6 +823,8 @@ static int msm_iommu_probe(struct platform_device *pdev)
>  		goto fail;
>  	}
>  
> +	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
> +
>  	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
>  		iommu->base, iommu->irq, iommu->ncb);
>  
> @@ -875,19 +877,7 @@ static void __exit msm_iommu_driver_exit(void)
>  subsys_initcall(msm_iommu_driver_init);
>  module_exit(msm_iommu_driver_exit);
>  
> -static int __init msm_iommu_init(void)
> -{
> -	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
> -	return 0;
> -}
> -
> -static int __init msm_iommu_of_setup(struct device_node *np)
> -{
> -	msm_iommu_init();
> -	return 0;
> -}
> -
> -IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
> +IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", NULL);
>  
>  MODULE_LICENSE("GPL v2");
>  MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
> 

Reviewed-by: Sricharan R <sricharan@codeaurora.org>

Regards,
 Sricharan
-- 
"QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* [RESEND PATCH] ARM: pinctrl: sunxi-pinctrl: fix pin funtion can not be match correctly.
From: hao_zhang @ 2018-01-09  5:59 UTC (permalink / raw)
  To: linux-arm-kernel

Pin function can not be match correctly when SUNXI_PIN describe with
mutiple variant and same function.

such as:
on pinctrl-sun4i-a10.c

SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
		SUNXI_FUNCTION(0x0, "gpio_in"),
		SUNXI_FUNCTION(0x1, "gpio_out"),
		SUNXI_FUNCTION_VARIANT(0x2, "pwm",    /* PWM0 */
			PINCTRL_SUN4I_A10 |
			PINCTRL_SUN7I_A20),
		SUNXI_FUNCTION_VARIANT(0x3, "pwm",    /* PWM0 */
			PINCTRL_SUN8I_R40)),

it would always match to the first variant function
(PINCTRL_SUN4I_A10, PINCTRL_SUN7I_A20)

so we should add variant compare on it.

Regards
Hao

Signed-off-by: hao_zhang <hao5781286@gmail.com>
---
 drivers/pinctrl/sunxi/pinctrl-sunxi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index 4b6cb25..131adf7 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -83,7 +83,9 @@ sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
 			struct sunxi_desc_function *func = pin->functions;
 
 			while (func->name) {
-				if (!strcmp(func->name, func_name))
+				if (!strcmp(func->name, func_name) &&
+					(!func->variant ||
+					func->variant & pctl->variant))
 					return func;
 
 				func++;
-- 
2.7.4

^ permalink raw reply related

* arm64 crashkernel fails to boot on acpi-only machines due to ACPI regions being no longer mapped as NOMAP
From: AKASHI Takahiro @ 2018-01-09  5:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171226065845.GB5354@dhcp-128-65.nay.redhat.com>

On Tue, Dec 26, 2017 at 02:58:45PM +0800, Dave Young wrote:
> On 12/26/17 at 08:26am, Bhupesh Sharma wrote:
> > On Tue, Dec 26, 2017 at 7:58 AM, AKASHI Takahiro
> > <takahiro.akashi@linaro.org> wrote:
> > > On Tue, Dec 26, 2017 at 09:35:17AM +0800, Dave Young wrote:
> > >> [snip]
> > >> > > > Well, we may be able to change pr_warn() to pr_warn_once() here, but
> > >> > > > I hope that adding "numa=off" to kernel command line should also work.
> > >> > >
> > >> > > Hmm, adding "numa=off" to crashkernel bootargs works, and TBH it was
> > >> > > my initial thought process as well, but I am not sure if this will
> > >> > > cause any regressions on aarch64 systems which use crashdump feature.
> > >> >
> > >> > It should be fine since we use numa=off by default for all other arches
> > >> > ie. x86, ppc64 and s390. Actually disabling numa in kdump kernel can save
> > >> > mm component memory usage.
> > >> >
> > >>
> > >> Forgot to say I means in RHEL and Fedora we use numa=off for kdump..
> > >
> > > Thank you for the clarification.
> > > (It might be better to make numa off automatically if maxcpus == 0 (and 1?).)
> > >
> > 
> > Not sure if we can leave this to the distribution-specific kdump
> > scripts (as the crashkernel boot can be held up for sufficient time
> > and may appear stuck). The distribution scripts may be different (for
> > e.g. ubuntu and RHEL/fedora) across distributions and may have
> > different bootarg options.
> 
> Personally I think distribution should take care of this param as for
> kdump.  But as AKASHI said it could be a issue for 1st kernel with
> nr_cpus=1 booting.  Problem is why we do not see this issue on other
> machines.

The issue won't be kdump-specific. Theoretically, it also takes place
when "mem=" is specified on numa.

Since we can avoid annoying messages by adding "numa=off", I'm reluctant to
suppress most of messages but the first. My suggestion here is to add some
notes in Documentation/kdump/kdump.txt regarding NUMA case.

Thanks,
Takahiro AKASHI


> > 
> > So how about considering a kernel fix only which doesn't require
> > relying on changing the distribution-specific kdump scripts, as we
> > should avoid introducing a regression while trying to fix a regression
> > :)
> > 
> > Just my 2 cents.
> > 
> > Thanks,
> > Bhupesh
> 
> Thanks
> Dave

^ permalink raw reply

* [PATCH v2 1/4] dmaengine: xilinx_dma: populate dma caps properly
From: Vinod Koul @ 2018-01-09  5:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CY1PR02MB1692292DE4B4F346B92BD4EBDC100@CY1PR02MB1692.namprd02.prod.outlook.com>

On Tue, Jan 09, 2018 at 04:48:10AM +0000, Appana Durga Kedareswara Rao wrote:
> Hi,
> 
> >On Mon, Jan 08, 2018 at 05:25:01PM +0000, Appana Durga Kedareswara Rao
> >wrote:
> >> Hi,
> >>
> >> <Snip>
> >> >> >> +	xdev->common.dst_addr_widths = BIT(addr_width / 8);
> >> >> >> +	xdev->common.src_addr_widths = BIT(addr_width / 8);
> >> >> >
> >> >> >Do you not support trf of 1byte, 2 bytes, or 4 bytes wide transfers?
> >> >> >What is value of addr_width here typically? Usually controllers
> >> >> >can support different widths and this is a surprise that you
> >> >> >support only one value
> >> >>
> >> >> Controller supports address width of 32 and 64.
> >> >
> >> >Then this should have both 32 and 64 values here
> >>
> >> Address width is configurable parameter at the h/w level.
> >> Since this IP is a soft IP user can create a design with either 32-bit
> >> or 64-bit address configuration.
> >
> >and not both right?
> 
> Yes not both at the same time... 
> Axi dma controller can be configured for either 32-bit or 64-bit address...

So my suspicion was correct.  I would suggest you to read up on the
documentation again. The src/dst_addr_widths has _nothing_ to do with 32/64
bit addresses used.

It is the capability of the dma controller to do transfers with data width as
8bits, 16 bits, so on. iKey is "data width" and not address type.
This typically translates to DMA FIFO configuration of the controller!

-- 
~Vinod

^ permalink raw reply

* arm64 crashkernel fails to boot on acpi-only machines due to ACPI regions being no longer mapped as NOMAP
From: AKASHI Takahiro @ 2018-01-09  5:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171226065636.GA5354@dhcp-128-65.nay.redhat.com>

On Tue, Dec 26, 2017 at 02:56:36PM +0800, Dave Young wrote:
> On 12/26/17 at 11:28am, AKASHI Takahiro wrote:
> > On Tue, Dec 26, 2017 at 09:35:17AM +0800, Dave Young wrote:
> > > [snip]
> > > > > > Well, we may be able to change pr_warn() to pr_warn_once() here, but
> > > > > > I hope that adding "numa=off" to kernel command line should also work.
> > > > > 
> > > > > Hmm, adding "numa=off" to crashkernel bootargs works, and TBH it was
> > > > > my initial thought process as well, but I am not sure if this will
> > > > > cause any regressions on aarch64 systems which use crashdump feature.
> > > > 
> > > > It should be fine since we use numa=off by default for all other arches
> > > > ie. x86, ppc64 and s390. Actually disabling numa in kdump kernel can save
> > > > mm component memory usage. 
> > > > 
> > > 
> > > Forgot to say I means in RHEL and Fedora we use numa=off for kdump..
> > 
> > Thank you for the clarification.
> > (It might be better to make numa off automatically if maxcpus == 0 (and 1?).)
> 
> Hmm, I did a quick test with qemu/kvm, kdump kernel boot without numa=off
> I'm not sure why I do not see the warning messages on x86
> machines, maybe something arm64 specific?

I didn't see the messages(i.e. "potential offnode page_structs")
on arm64 qemu (with -smp 2 -numa node -numa node).

It seems that qemu doesn't generate acpi slit(inter-node distance table).

Thanks,
-Takahiro AKASHI

> > 
> > -Takahiro AKASHI

^ permalink raw reply

* [PATCH v2 1/4] dmaengine: xilinx_dma: populate dma caps properly
From: Vinod Koul @ 2018-01-09  4:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CY1PR02MB16922B2D20C958D8214F7A23DC130@CY1PR02MB1692.namprd02.prod.outlook.com>

On Mon, Jan 08, 2018 at 05:25:01PM +0000, Appana Durga Kedareswara Rao wrote:
> Hi,
> 
> <Snip>
> >> >> +	xdev->common.dst_addr_widths = BIT(addr_width / 8);
> >> >> +	xdev->common.src_addr_widths = BIT(addr_width / 8);
> >> >
> >> >Do you not support trf of 1byte, 2 bytes, or 4 bytes wide transfers?
> >> >What is value of addr_width here typically? Usually controllers can
> >> >support different widths and this is a surprise that you support only
> >> >one value
> >>
> >> Controller supports address width of 32 and 64.
> >
> >Then this should have both 32 and 64 values here
> 
> Address width is configurable parameter at the h/w level.
> Since this IP is a soft IP user can create a design with either 
> 32-bit or 64-bit address configuration. 

and not both right?

> Currently we are reading this configuration through device-tree (xlnx, addr-width property) 
> https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git/tree/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt#n19
> Based on the h/w configuration setting the dst_addr_widths/src_addr_widths variables in this patch.
> Please let me know if you are still not clear with my explanation will explain in detail... 
> 
> Regards,
> Kedar.
> 
> >
> >> addr_width typical values are 32-bit or 64-bit .
> >> Here addr_width is device-tree parameter...
> >> my understanding of src_addr_widths/dst_addr_widths is, it is a bit
> >> mask of the address with in bytes that DMA supports, please correct if my
> >understanding is wrong.
> >>
> >> Regards,
> >> Kedar.
> >>
> >> >
> >> >--
> >> >~Vinod
> >
> >--
> >~Vinod

-- 
~Vinod

^ permalink raw reply

* [PATCH v2 1/4] dmaengine: xilinx_dma: populate dma caps properly
From: Appana Durga Kedareswara Rao @ 2018-01-09  4:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180109044858.GN18649@localhost>

Hi,

>On Mon, Jan 08, 2018 at 05:25:01PM +0000, Appana Durga Kedareswara Rao
>wrote:
>> Hi,
>>
>> <Snip>
>> >> >> +	xdev->common.dst_addr_widths = BIT(addr_width / 8);
>> >> >> +	xdev->common.src_addr_widths = BIT(addr_width / 8);
>> >> >
>> >> >Do you not support trf of 1byte, 2 bytes, or 4 bytes wide transfers?
>> >> >What is value of addr_width here typically? Usually controllers
>> >> >can support different widths and this is a surprise that you
>> >> >support only one value
>> >>
>> >> Controller supports address width of 32 and 64.
>> >
>> >Then this should have both 32 and 64 values here
>>
>> Address width is configurable parameter at the h/w level.
>> Since this IP is a soft IP user can create a design with either 32-bit
>> or 64-bit address configuration.
>
>and not both right?

Yes not both at the same time... 
Axi dma controller can be configured for either 32-bit or 64-bit address...

Regards,
Kedar.

>
>> Currently we are reading this configuration through device-tree (xlnx,
>> addr-width property)
>> https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git/tr
>> ee/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt#n19
>> Based on the h/w configuration setting the dst_addr_widths/src_addr_widths
>variables in this patch.
>> Please let me know if you are still not clear with my explanation will explain in
>detail...
>>
>> Regards,
>> Kedar.
>>
>> >
>> >> addr_width typical values are 32-bit or 64-bit .
>> >> Here addr_width is device-tree parameter...
>> >> my understanding of src_addr_widths/dst_addr_widths is, it is a bit
>> >> mask of the address with in bytes that DMA supports, please correct
>> >> if my
>> >understanding is wrong.
>> >>
>> >> Regards,
>> >> Kedar.
>> >>
>> >> >
>> >> >--
>> >> >~Vinod
>> >
>> >--
>> >~Vinod
>
>--
>~Vinod
>--
>To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body
>of a message to majordomo at vger.kernel.org More majordomo info at
>http://vger.kernel.org/majordomo-info.html

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox