Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 23/23] clk: renesas: rcar-gen2: Remove obsolete rcar_gen2_clocks_init()
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

The R-Car Gen2 board code no longer calls rcar_gen2_clocks_init().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - Rebased,

v2:
  - No changes.
---
 drivers/clk/renesas/clk-rcar-gen2.c | 7 -------
 include/linux/clk/renesas.h         | 2 --
 2 files changed, 9 deletions(-)

diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c
index 3291fd430ad4e215..f39519edc645ca87 100644
--- a/drivers/clk/renesas/clk-rcar-gen2.c
+++ b/drivers/clk/renesas/clk-rcar-gen2.c
@@ -445,10 +445,3 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 }
 CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
 	       rcar_gen2_cpg_clocks_init);
-
-void __init rcar_gen2_clocks_init(u32 mode)
-{
-	cpg_mode = mode;
-
-	of_clk_init(NULL);
-}
diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h
index 9e969941f3f62878..9ebf1f8243bb57af 100644
--- a/include/linux/clk/renesas.h
+++ b/include/linux/clk/renesas.h
@@ -20,8 +20,6 @@
 struct device_node;
 struct generic_pm_domain;
 
-void rcar_gen2_clocks_init(u32 mode);
-
 void cpg_mstp_add_clk_domain(struct device_node *np);
 #ifdef CONFIG_CLK_RENESAS_CPG_MSTP
 int cpg_mstp_attach_dev(struct generic_pm_domain *unused, struct device *dev);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 22/23] clk: renesas: r8a7779: Remove obsolete r8a7779_clocks_init()
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

The R-Car H1 board code no longer calls r8a7779_clocks_init().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - New.
---
 drivers/clk/renesas/clk-r8a7779.c | 9 ---------
 include/linux/clk/renesas.h       | 1 -
 2 files changed, 10 deletions(-)

diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c
index ca7551bcb1153c3d..27fbfafaf2cd0353 100644
--- a/drivers/clk/renesas/clk-r8a7779.c
+++ b/drivers/clk/renesas/clk-r8a7779.c
@@ -89,8 +89,6 @@ struct cpg_clk_config {
  * Initialization
  */
 
-static u32 cpg_mode __initdata;
-
 static struct clk * __init
 r8a7779_cpg_register_clock(struct device_node *np, struct r8a7779_cpg *cpg,
 			   const struct cpg_clk_config *config,
@@ -178,10 +176,3 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
 }
 CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks",
 	       r8a7779_cpg_clocks_init);
-
-void __init r8a7779_clocks_init(u32 mode)
-{
-	cpg_mode = mode;
-
-	of_clk_init(NULL);
-}
diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h
index 2b663bba1adcc7c1..9e969941f3f62878 100644
--- a/include/linux/clk/renesas.h
+++ b/include/linux/clk/renesas.h
@@ -20,7 +20,6 @@
 struct device_node;
 struct generic_pm_domain;
 
-void r8a7779_clocks_init(u32 mode);
 void rcar_gen2_clocks_init(u32 mode);
 
 void cpg_mstp_add_clk_domain(struct device_node *np);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 21/23] clk: renesas: r8a7778: Remove obsolete r8a7778_clocks_init()
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

The R-Car M1A board code no longer calls r8a7778_clocks_init().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - New.
---
 drivers/clk/renesas/clk-r8a7778.c | 13 -------------
 include/linux/clk/renesas.h       |  1 -
 2 files changed, 14 deletions(-)

diff --git a/drivers/clk/renesas/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c
index 07ea411098a75ad1..886a8380e91247a1 100644
--- a/drivers/clk/renesas/clk-r8a7778.c
+++ b/drivers/clk/renesas/clk-r8a7778.c
@@ -143,16 +143,3 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np)
 
 CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks",
 	       r8a7778_cpg_clocks_init);
-
-void __init r8a7778_clocks_init(u32 mode)
-{
-	BUG_ON(!(mode & BIT(19)));
-
-	cpg_mode_rates = (!!(mode & BIT(18)) << 2) |
-			 (!!(mode & BIT(12)) << 1) |
-			 (!!(mode & BIT(11)));
-	cpg_mode_divs = (!!(mode & BIT(2)) << 1) |
-			(!!(mode & BIT(1)));
-
-	of_clk_init(NULL);
-}
diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h
index ba6fa4148515e5c9..2b663bba1adcc7c1 100644
--- a/include/linux/clk/renesas.h
+++ b/include/linux/clk/renesas.h
@@ -20,7 +20,6 @@
 struct device_node;
 struct generic_pm_domain;
 
-void r8a7778_clocks_init(u32 mode);
 void r8a7779_clocks_init(u32 mode);
 void rcar_gen2_clocks_init(u32 mode);
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 19/23] ARM: shmobile: r8a7779: Stop passing mode pins state to clock driver
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Now the R-Car H1 CPG clock driver obtains the state of the mode pins
from the R-Car RST driver, there's no longer a need to pass this state
explicitly. Hence we can just remove the .init_time() callback, the
generic ARM code will take care of calling of_clk_init() and
clocksource_probe().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - New.
---
 arch/arm/mach-shmobile/setup-r8a7779.c | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 0007ff51d180379f..0686112f243525b6 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -14,8 +14,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-#include <linux/clk/renesas.h>
-#include <linux/clocksource.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
@@ -76,30 +74,6 @@ static void __init r8a7779_init_irq_dt(void)
 	__raw_writel(0x003fee3f, INT2SMSKCR4);
 }
 
-#define MODEMR		0xffcc0020
-
-static u32 __init r8a7779_read_mode_pins(void)
-{
-	static u32 mode;
-	static bool mode_valid;
-
-	if (!mode_valid) {
-		void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
-		BUG_ON(!modemr);
-		mode = ioread32(modemr);
-		iounmap(modemr);
-		mode_valid = true;
-	}
-
-	return mode;
-}
-
-static void __init r8a7779_init_time(void)
-{
-	r8a7779_clocks_init(r8a7779_read_mode_pins());
-	clocksource_probe();
-}
-
 static const char *const r8a7779_compat_dt[] __initconst = {
 	"renesas,r8a7779",
 	NULL,
@@ -109,7 +83,6 @@ static void __init r8a7779_init_time(void)
 	.smp		= smp_ops(r8a7779_smp_ops),
 	.map_io		= r8a7779_map_io,
 	.init_early	= shmobile_init_delay,
-	.init_time	= r8a7779_init_time,
 	.init_irq	= r8a7779_init_irq_dt,
 	.init_late	= shmobile_init_late,
 	.dt_compat	= r8a7779_compat_dt,
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 15/23] clk: renesas: r8a7795: Obtain mode pin values from R-Car RST driver
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Obtain the values of the mode pins from the R-Car RST driver, which
relies on the presence in DT of a device node for the RST module.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v4:
  - Add Acked-by, Reviewed-by,

v3:
  - New.
---
 drivers/clk/renesas/r8a7795-cpg-mssr.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index f255e451e8cafbbf..726c3d7940b491b9 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -15,6 +15,7 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
 
 #include <dt-bindings/clock/r8a7795-cpg-mssr.h>
 
@@ -311,7 +312,12 @@ enum clk_ids {
 static int __init r8a7795_cpg_mssr_init(struct device *dev)
 {
 	const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
-	u32 cpg_mode = rcar_gen3_read_mode_pins();
+	u32 cpg_mode;
+	int error;
+
+	error = rcar_rst_read_mode_pins(&cpg_mode);
+	if (error)
+		return error;
 
 	cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
 	if (!cpg_pll_config->extal_div) {
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 14/23] clk: renesas: rcar-gen2: Obtain mode pin values using RST driver
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Obtain the values of the mode pins from the R-Car RST driver, which
relies on the presence in DT of a device node for the RST module.

Fall back to our own private copy of rcar_gen2_read_mode_pins() for
backward-compatibility with old DTs.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,
  - Use our own private copy of rcar_gen2_read_mode_pins() instead of
    the one in the R-Car Gen2 platform code, as the latter is planned to
    be removed,

v3:
  -  Use the R-Car RST driver instead of syscon/regmap and the
     "renesas,modemr" property in DT,

v2:
  - drivers/clk/shmobile/ was renamed to drivers/clk/renesas/.
---
 drivers/clk/renesas/clk-rcar-gen2.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c
index 00e6aba4b9c09596..3291fd430ad4e215 100644
--- a/drivers/clk/renesas/clk-rcar-gen2.c
+++ b/drivers/clk/renesas/clk-rcar-gen2.c
@@ -19,6 +19,7 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/soc/renesas/rcar-rst.h>
 
 struct rcar_gen2_cpg {
 	struct clk_onecell_data data;
@@ -364,6 +365,23 @@ struct cpg_pll_config {
 						 4, 0, table, &cpg->lock);
 }
 
+/*
+ * Reset register definitions.
+ */
+#define MODEMR	0xe6160060
+
+static u32 __init rcar_gen2_read_mode_pins(void)
+{
+	void __iomem *modemr = ioremap_nocache(MODEMR, 4);
+	u32 mode;
+
+	BUG_ON(!modemr);
+	mode = ioread32(modemr);
+	iounmap(modemr);
+
+	return mode;
+}
+
 static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 {
 	const struct cpg_pll_config *config;
@@ -372,6 +390,13 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 	unsigned int i;
 	int num_clks;
 
+	if (rcar_rst_read_mode_pins(&cpg_mode)) {
+		/* Backward-compatibility with old DT */
+		pr_warn("%s: failed to obtain mode pins from RST\n",
+			np->full_name);
+		cpg_mode = rcar_gen2_read_mode_pins();
+	}
+
 	num_clks = of_property_count_strings(np, "clock-output-names");
 	if (num_clks < 0) {
 		pr_err("%s: failed to count clocks\n", __func__);
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 13/23] clk: renesas: r8a7779: Obtain mode pin values from R-Car RST driver
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Obtain the values of the mode pins from the R-Car RST driver, which
relies on the presence in DT of a device node for the RESET/WDT module.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - New.
---
 drivers/clk/renesas/clk-r8a7779.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c
index cf2a37df03b15e60..ca7551bcb1153c3d 100644
--- a/drivers/clk/renesas/clk-r8a7779.c
+++ b/drivers/clk/renesas/clk-r8a7779.c
@@ -18,6 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/soc/renesas/rcar-rst.h>
 
 #include <dt-bindings/clock/r8a7779-clock.h>
 
@@ -127,6 +128,10 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
 	struct clk **clks;
 	unsigned int i, plla_mult;
 	int num_clks;
+	u32 mode;
+
+	if (rcar_rst_read_mode_pins(&mode))
+		return;
 
 	num_clks = of_property_count_strings(np, "clock-output-names");
 	if (num_clks < 0) {
@@ -148,8 +153,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
 	cpg->data.clks = clks;
 	cpg->data.clk_num = num_clks;
 
-	config = &cpg_clk_configs[CPG_CLK_CONFIG_INDEX(cpg_mode)];
-	plla_mult = cpg_plla_mult[CPG_PLLA_MULT_INDEX(cpg_mode)];
+	config = &cpg_clk_configs[CPG_CLK_CONFIG_INDEX(mode)];
+	plla_mult = cpg_plla_mult[CPG_PLLA_MULT_INDEX(mode)];
 
 	for (i = 0; i < num_clks; ++i) {
 		const char *name;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 11/23] arm64: renesas: r8a7796 dtsi: Add device node for RST module
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Add a device node for the RST module, which provides a.o. reset control
and mode pin monitoring.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - New.
---
 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 9217da9835256573..75c8c55a824835bf 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -233,6 +233,11 @@
 			#power-domain-cells = <0>;
 		};
 
+		rst: reset-controller at e6160000 {
+			compatible = "renesas,r8a7796-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+
 		sysc: system-controller at e6180000 {
 			compatible = "renesas,r8a7796-sysc";
 			reg = <0 0xe6180000 0 0x0400>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 10/23] arm64: renesas: r8a7795 dtsi: Add device node for RST module
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Add a device node for the RST module, which provides a.o. reset control
and mode pin monitoring.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,

v3:
  - Use "renesas,<soctype>-rst" instead of "renesas,rst-<soctype>",
  - Drop "syscon" compatible value,

v2:
  - New.
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 8c15040f2540d63a..625dda713548da78 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -321,6 +321,11 @@
 			#power-domain-cells = <0>;
 		};
 
+		rst: reset-controller at e6160000 {
+			compatible = "renesas,r8a7795-rst";
+			reg = <0 0xe6160000 0 0x0200>;
+		};
+
 		sysc: system-controller at e6180000 {
 			compatible = "renesas,r8a7795-sysc";
 			reg = <0 0xe6180000 0 0x0400>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 07/23] ARM: dts: r8a7792: Add device node for RST module
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Add a device node for the RST module, which provides a.o. reset control
and mode pin monitoring.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v4:
  - New.
---
 arch/arm/boot/dts/r8a7792.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi
index 713141d38b3ea960..6e1f61f65d292b0b 100644
--- a/arch/arm/boot/dts/r8a7792.dtsi
+++ b/arch/arm/boot/dts/r8a7792.dtsi
@@ -118,6 +118,11 @@
 				      IRQ_TYPE_LEVEL_LOW)>;
 		};
 
+		rst: reset-controller at e6160000 {
+			compatible = "renesas,r8a7792-rst";
+			reg = <0 0xe6160000 0 0x0100>;
+		};
+
 		sysc: system-controller at e6180000 {
 			compatible = "renesas,r8a7792-sysc";
 			reg = <0 0xe6180000 0 0x0200>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 02/23] soc: renesas: Add R-Car RST driver
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477055857-17936-1-git-send-email-geert+renesas@glider.be>

Add a driver for the Renesas R-Car Gen1 RESET/WDT and R-Car Gen2/Gen3
and RZ/G RST module.

For now this driver just provides an API to obtain the state of the mode
pins, as latched at reset time.  As this is typically called from the
probe function of a clock driver, which can run much earlier than any
initcall, calling rcar_rst_read_mode_pins() just forces an early
initialization of the driver.

Despite the current simple and almost identical handling for all
supported SoCs, the driver matches against SoC-specific compatible
values, as the features provided by the hardware module differ a lot
across the various SoC families and members.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>
---
v4:
  - Add Acked-by,
  - Remove the initcall and the rcar_rst_base check in rcar_rst_init(),
    as rcar_rst_init() is only used as a support function for
    rcar_rst_read_mode_pins(),
  - Refer to rcar_rst_gen2 for R-Car Gen3 instead of providing an
    identical copy,
  - Add RZ/G1M and RZ/G1E,

v3:
  - New.
---
 drivers/soc/renesas/Makefile         |  5 ++
 drivers/soc/renesas/rcar-rst.c       | 92 ++++++++++++++++++++++++++++++++++++
 include/linux/soc/renesas/rcar-rst.h |  6 +++
 3 files changed, 103 insertions(+)
 create mode 100644 drivers/soc/renesas/rcar-rst.c
 create mode 100644 include/linux/soc/renesas/rcar-rst.h

diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index 623039c3514cdc34..86cc78cd1962701a 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -1,3 +1,8 @@
+obj-$(CONFIG_ARCH_RCAR_GEN1)	+= rcar-rst.o
+obj-$(CONFIG_ARCH_RCAR_GEN2)	+= rcar-rst.o
+obj-$(CONFIG_ARCH_R8A7795)	+= rcar-rst.o
+obj-$(CONFIG_ARCH_R8A7796)	+= rcar-rst.o
+
 obj-$(CONFIG_ARCH_R8A7779)	+= rcar-sysc.o r8a7779-sysc.o
 obj-$(CONFIG_ARCH_R8A7790)	+= rcar-sysc.o r8a7790-sysc.o
 obj-$(CONFIG_ARCH_R8A7791)	+= rcar-sysc.o r8a7791-sysc.o
diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
new file mode 100644
index 0000000000000000..a6d1c26d31675cf3
--- /dev/null
+++ b/drivers/soc/renesas/rcar-rst.c
@@ -0,0 +1,92 @@
+/*
+ * R-Car Gen1 RESET/WDT, R-Car Gen2, Gen3, and RZ/G RST Driver
+ *
+ * Copyright (C) 2016 Glider bvba
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+struct rst_config {
+	unsigned int modemr;	/* Mode Monitoring Register Offset */
+};
+
+static const struct rst_config rcar_rst_gen1 __initconst = {
+	.modemr = 0x20,
+};
+
+static const struct rst_config rcar_rst_gen2 __initconst = {
+	.modemr = 0x60,
+};
+
+static const struct of_device_id rcar_rst_matches[] __initconst = {
+	/* RZ/G is handled like R-Car Gen2 */
+	{ .compatible = "renesas,r8a7743-rst", .data = &rcar_rst_gen2 },
+	{ .compatible = "renesas,r8a7745-rst", .data = &rcar_rst_gen2 },
+	/* R-Car Gen1 */
+	{ .compatible = "renesas,r8a7778-reset-wdt", .data = &rcar_rst_gen1 },
+	{ .compatible = "renesas,r8a7779-reset-wdt", .data = &rcar_rst_gen1 },
+	/* R-Car Gen2 */
+	{ .compatible = "renesas,r8a7790-rst", .data = &rcar_rst_gen2 },
+	{ .compatible = "renesas,r8a7791-rst", .data = &rcar_rst_gen2 },
+	{ .compatible = "renesas,r8a7792-rst", .data = &rcar_rst_gen2 },
+	{ .compatible = "renesas,r8a7793-rst", .data = &rcar_rst_gen2 },
+	{ .compatible = "renesas,r8a7794-rst", .data = &rcar_rst_gen2 },
+	/* R-Car Gen3 is handled like R-Car Gen2 */
+	{ .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 },
+	{ .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
+	{ /* sentinel */ }
+};
+
+static void __iomem *rcar_rst_base __initdata;
+static u32 saved_mode __initdata;
+
+static int __init rcar_rst_init(void)
+{
+	const struct of_device_id *match;
+	const struct rst_config *cfg;
+	struct device_node *np;
+	void __iomem *base;
+	int error = 0;
+
+	np = of_find_matching_node_and_match(NULL, rcar_rst_matches, &match);
+	if (!np)
+		return -ENODEV;
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_warn("%s: Cannot map regs\n", np->full_name);
+		error = -ENOMEM;
+		goto out_put;
+	}
+
+	rcar_rst_base = base;
+	cfg = match->data;
+	saved_mode = ioread32(base + cfg->modemr);
+
+	pr_debug("%s: MODE = 0x%08x\n", np->full_name, saved_mode);
+
+out_put:
+	of_node_put(np);
+	return error;
+}
+
+int __init rcar_rst_read_mode_pins(u32 *mode)
+{
+	int error;
+
+	if (!rcar_rst_base) {
+		error = rcar_rst_init();
+		if (error)
+			return error;
+	}
+
+	*mode = saved_mode;
+	return 0;
+}
diff --git a/include/linux/soc/renesas/rcar-rst.h b/include/linux/soc/renesas/rcar-rst.h
new file mode 100644
index 0000000000000000..a18e0783946b66ec
--- /dev/null
+++ b/include/linux/soc/renesas/rcar-rst.h
@@ -0,0 +1,6 @@
+#ifndef __LINUX_SOC_RENESAS_RCAR_RST_H__
+#define __LINUX_SOC_RENESAS_RCAR_RST_H__
+
+int rcar_rst_read_mode_pins(u32 *mode);
+
+#endif /* __LINUX_SOC_RENESAS_RCAR_RST_H__ */
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4 00/23] soc: renesas: Add R-Car RST driver for obtaining mode pin state
From: Geert Uytterhoeven @ 2016-10-21 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

        Hi Philipp, Mike, Stephen, Simon, Magnus,
	(see questions *** below!)

Currently the R-Car Clock Pulse Generator (CPG) drivers obtains the
state of the mode pins either by a call from the platform code, or
directly by using a hardcoded register access. This is a bit messy, and
creates a dependency between driver and platform code.

This patch series converts the various Renesas R-Car clock drivers
and support code from reading the mode pin states using a hardcoded
register access to using a new minimalistic R-Car RST driver.

All R-Car clock drivers will rely on the presence in DT of a device node
for the RST module.  Backwards compatibility with old DTBs is retained
only for R-Car Gen2, which has fallback code using its own private copy
of rcar_gen2_read_mode_pins().

After this, there is still one remaining user of
rcar_gen2_read_mode_pins() left in platform code. A patch series to
remove that user has already been posted, though ("[PATCH/RFT 0/4] ARM:
shmobile: R-Car Gen2: Allow booting secondary CPU cores in debug mode").
Since v3, the other user has been removed in commit 9f5ce39ddb8f68b3
("ARM: shmobile: rcar-gen2: Obtain extal frequency from DT").

This series consists of 5 parts:
  A. Patches 1 and 2 add DT bindings and driver code for the R-Car RST
     driver,
  B. Patches 3-11 add device nodes for the RST modules to the R-Car DTS
     files,
  C. Patches 12-17 convert the clock drivers to call into the new R-Car
     RST driver,
  D. Patches 18-20 remove passing mode pin state to the clock drivers
     from the platform code,
  E. Patches 21-23 remove dead code from the clock drivers.

As is usually the case with moving functionality from platform code to
DT, there are lots of hard dependencies:
  - The DT updates in Part B can be merged as soon as the DT bindings in
    Part A have been approved,
  - The clock driver updates in Part C depend functionally on the driver
    code in Part A, and on the DT updates in Part B,
  - The board code cleanups in Part D depend on the clock driver updates
    in Part C,
  - The block driver cleanups in part E depend on the board code
    cleanups in part D.

Hence to maintain the required lockstep between SoC driver, clock
drivers, shmobile platform code, and shmobile DT, I propose to queue up
all patches in a single branch against v4.9-rc1, and send pull requests
to both Mike/Stephen (clock) and Simon (rest).

***

  - Philip: While this is a driver for a reset-controller, currently it
    doesn't provide any reset-controller functionality. Hence I added it
    to drivers/soc/renesas/. Is that OK for you?

  - Mike/Stephen/Simon/Magnus: Are you OK with the suggested merge
    approach above?

This series has evolved over time, cfr.:
  - "[PATCH/RFC v3 00/22] soc: renesas: Add R-Car RST driver for
    obtaining mode pin state"
    (http://www.spinics.net/lists/linux-renesas-soc/msg04289.html),
  - "[PATCH/RFC 00/11] ARM: shmobile: Let CPG use syscon for MD pin
    values" (http://www.spinics.net/lists/linux-clk/msg01478.html),
  - "[PATCH 00/10] arm64: renesas: Obtain MD pin values using
    syscon/regmap".
    (http://www.spinics.net/lists/linux-sh/msg44757.html)

Changes compared to v3:
  - Add Acked-by, Reviewed-by,
  - Add support for R-Car V2H,
  - Add support for RZ/G1M and RZ/G1E,
  - Remove the initcall and the rcar_rst_base check in rcar_rst_init(),
    as rcar_rst_init() is only used as a support function for
    rcar_rst_read_mode_pins(),
  - Refer to rcar_rst_gen2 for R-Car Gen3 instead of providing an
    identical copy,
  - Use our own private copy of rcar_gen2_read_mode_pins() instead of
    the one in the R-Car Gen2 platform code, as the latter is planned to
    be removed,
  - Rebase on top of "ARM: shmobile: rcar-gen2: Obtain extal frequency
    from DT",

Changes compared to v2:
  - Use "renesas,<soctype>-rst" instead of "renesas,rst-<soctype>",
  - Drop "syscon" compatible value and "renesas,modemr" property, use a
    real driver instead,
  - Add support for R-Car M1A, H1, and M3-W.

Changes compared to v1:
  - Add support for R-Car H3.

This patch series is against v4.9-rc1. When applying it to
renesas-devel-20161021-v4.9-rc1, there's a small conflict in
drivers/soc/renesas/Makefile (both sides added lines).

For your convenience, this series is also available in the
topic/rcar-rst-v4 branch of my renesas-drivers git repository at
git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git
This has been tested on r8a7778/bockw, r8a7779/marzen, r8a7791/koelsch,
r8a7795/salvator-x, and r8a7796/salvator-x.

Thanks!

Geert Uytterhoeven (23):
  reset: Add renesas,rst DT bindings
  soc: renesas: Add R-Car RST driver
  ARM: dts: r8a7778: Add device node for RESET/WDT module
  ARM: dts: r8a7779: Add device node for RESET/WDT module
  ARM: dts: r8a7790: Add device node for RST module
  ARM: dts: r8a7791: Add device node for RST module
  ARM: dts: r8a7792: Add device node for RST module
  ARM: dts: r8a7793: Add device node for RST module
  ARM: dts: r8a7794: Add device node for RST module
  arm64: renesas: r8a7795 dtsi: Add device node for RST module
  arm64: renesas: r8a7796 dtsi: Add device node for RST module
  clk: renesas: r8a7778: Obtain mode pin values using R-Car RST driver
  clk: renesas: r8a7779: Obtain mode pin values from R-Car RST driver
  clk: renesas: rcar-gen2: Obtain mode pin values using RST driver
  clk: renesas: r8a7795: Obtain mode pin values from R-Car RST driver
  clk: renesas: r8a7796: Obtain mode pin values from R-Car RST driver
  clk: renesas: rcar-gen3-cpg: Remove obsolete
    rcar_gen3_read_mode_pins()
  ARM: shmobile: r8a7778: Stop passing mode pins state to clock driver
  ARM: shmobile: r8a7779: Stop passing mode pins state to clock driver
  ARM: shmobile: rcar-gen2: Stop passing mode pins state to clock driver
  clk: renesas: r8a7778: Remove obsolete r8a7778_clocks_init()
  clk: renesas: r8a7779: Remove obsolete r8a7779_clocks_init()
  clk: renesas: rcar-gen2: Remove obsolete rcar_gen2_clocks_init()

 .../devicetree/bindings/reset/renesas,rst.txt      | 37 +++++++++
 arch/arm/boot/dts/r8a7778.dtsi                     |  5 ++
 arch/arm/boot/dts/r8a7779.dtsi                     |  5 ++
 arch/arm/boot/dts/r8a7790.dtsi                     |  5 ++
 arch/arm/boot/dts/r8a7791.dtsi                     |  5 ++
 arch/arm/boot/dts/r8a7792.dtsi                     |  5 ++
 arch/arm/boot/dts/r8a7793.dtsi                     |  5 ++
 arch/arm/boot/dts/r8a7794.dtsi                     |  5 ++
 arch/arm/mach-shmobile/setup-r8a7778.c             | 15 ----
 arch/arm/mach-shmobile/setup-r8a7779.c             | 27 -------
 arch/arm/mach-shmobile/setup-rcar-gen2.c           |  5 +-
 arch/arm64/boot/dts/renesas/r8a7795.dtsi           |  5 ++
 arch/arm64/boot/dts/renesas/r8a7796.dtsi           |  5 ++
 drivers/clk/renesas/clk-r8a7778.c                  | 26 +++---
 drivers/clk/renesas/clk-r8a7779.c                  | 18 ++---
 drivers/clk/renesas/clk-rcar-gen2.c                | 32 ++++++--
 drivers/clk/renesas/r8a7795-cpg-mssr.c             |  8 +-
 drivers/clk/renesas/r8a7796-cpg-mssr.c             |  8 +-
 drivers/clk/renesas/rcar-gen3-cpg.c                | 17 ----
 drivers/clk/renesas/rcar-gen3-cpg.h                |  1 -
 drivers/soc/renesas/Makefile                       |  5 ++
 drivers/soc/renesas/rcar-rst.c                     | 92 ++++++++++++++++++++++
 include/linux/clk/renesas.h                        |  4 -
 include/linux/soc/renesas/rcar-rst.h               |  6 ++
 24 files changed, 246 insertions(+), 100 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/reset/renesas,rst.txt
 create mode 100644 drivers/soc/renesas/rcar-rst.c
 create mode 100644 include/linux/soc/renesas/rcar-rst.h

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply

* [PATCH 2/2] gpio: mxs: fix duplicate level interrupts
From: Sascha Hauer @ 2016-10-21 13:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161021131138.10467-1-s.hauer@pengutronix.de>

According to the reference manual level interrupts can't be acked
using the IRQSTAT registers. The effect is that when a level interrupt
triggers the following ack is a no-op and the same interrupt triggers
again right after it has been unmasked after running the interrupt
handler.

The reference manual says:

Status bits for pins configured as level sensitive interrupts cannot be
cleared unless either the actual pin is in the non-interrupting state, or
the pin has been disabled as an interrupt source by clearing its bit in
HW_PINCTRL_PIN2IRQ.

To work around the duplicated interrupts we can use the PIN2IRQ
rather than the IRQEN registers to mask the interrupts. This
probably does not work for the edge interrupts, so we have to split up
the irq chip into two chip types, one for the level interrupts and
one for the edge interrupts. We now make use of two different enable
registers, so we have to take care to always enable the right one,
especially during switching of the interrupt type. An easy way
to accomplish this is to use the IRQCHIP_SET_TYPE_MASKED which
makes sure that set_irq_type is called with masked interrupts. With this
the flow to change the irq type is like:

- core masks interrupt (using the current chip type)
- mxs_gpio_set_irq_type() changes chip type if necessary
- mxs_gpio_set_irq_type() unconditionally sets the enable bit in the
  now unused enable register
- core eventually unmasks the interrupt (using the new chip type)

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/gpio/gpio-mxs.c | 38 +++++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 1cf579f..62061f7 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -87,10 +87,15 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
 	u32 val;
 	u32 pin_mask = 1 << d->hwirq;
 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct irq_chip_type *ct = irq_data_get_chip_type(d);
 	struct mxs_gpio_port *port = gc->private;
 	void __iomem *pin_addr;
 	int edge;
 
+	if (!(ct->type & type))
+		if (irq_setup_alt_chip(d, type))
+			return -EINVAL;
+
 	port->both_edges &= ~pin_mask;
 	switch (type) {
 	case IRQ_TYPE_EDGE_BOTH:
@@ -119,10 +124,13 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
 
 	/* set level or edge */
 	pin_addr = port->base + PINCTRL_IRQLEV(port);
-	if (edge & GPIO_INT_LEV_MASK)
+	if (edge & GPIO_INT_LEV_MASK) {
 		writel(pin_mask, pin_addr + MXS_SET);
-	else
+		writel(pin_mask, port->base + PINCTRL_IRQEN(port) + MXS_SET);
+	} else {
 		writel(pin_mask, pin_addr + MXS_CLR);
+		writel(pin_mask, port->base + PINCTRL_PIN2IRQ(port) + MXS_SET);
+	}
 
 	/* set polarity */
 	pin_addr = port->base + PINCTRL_IRQPOL(port);
@@ -202,22 +210,37 @@ static int __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	gc = irq_alloc_generic_chip("gpio-mxs", 1, irq_base,
+	gc = irq_alloc_generic_chip("gpio-mxs", 2, irq_base,
 				    port->base, handle_level_irq);
 	if (!gc)
 		return -ENOMEM;
 
 	gc->private = port;
 
-	ct = gc->chip_types;
+	ct = &gc->chip_types[0];
+	ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
+	ct->chip.irq_ack = irq_gc_ack_set_bit;
+	ct->chip.irq_mask = irq_gc_mask_disable_reg;
+	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+	ct->chip.irq_set_type = mxs_gpio_set_irq_type;
+	ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
+	ct->chip.flags = IRQCHIP_SET_TYPE_MASKED;
+	ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
+	ct->regs.enable = PINCTRL_PIN2IRQ(port) + MXS_SET;
+	ct->regs.disable = PINCTRL_PIN2IRQ(port) + MXS_CLR;
+
+	ct = &gc->chip_types[1];
+	ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
 	ct->chip.irq_ack = irq_gc_ack_set_bit;
 	ct->chip.irq_mask = irq_gc_mask_disable_reg;
 	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
 	ct->chip.irq_set_type = mxs_gpio_set_irq_type;
 	ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
+	ct->chip.flags = IRQCHIP_SET_TYPE_MASKED;
 	ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
 	ct->regs.enable = PINCTRL_IRQEN(port) + MXS_SET;
 	ct->regs.disable = PINCTRL_IRQEN(port) + MXS_CLR;
+	ct->handler = handle_level_irq;
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
 			       IRQ_NOREQUEST, 0);
@@ -298,11 +321,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)
 	}
 	port->base = base;
 
-	/*
-	 * select the pin interrupt functionality but initially
-	 * disable the interrupts
-	 */
-	writel(~0U, port->base + PINCTRL_PIN2IRQ(port));
+	/* initially disable the interrupts */
+	writel(0, port->base + PINCTRL_PIN2IRQ(port));
 	writel(0, port->base + PINCTRL_IRQEN(port));
 
 	/* clear address has to be used to clear IRQSTAT bits */
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/2] gpio: mxs: use enable/disable regs to (un)mask irqs
From: Sascha Hauer @ 2016-10-21 13:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161021131138.10467-1-s.hauer@pengutronix.de>

The mxs gpio controller does not only have a mask register to mask
interrupts, but also enable/disable registers. Use the enable/disable
registers rather than the mask register. This does not have any
advantage for now, but makes the next patch simpler.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/gpio/gpio-mxs.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index b9daa0b..1cf579f 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -211,12 +211,13 @@ static int __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
 
 	ct = gc->chip_types;
 	ct->chip.irq_ack = irq_gc_ack_set_bit;
-	ct->chip.irq_mask = irq_gc_mask_clr_bit;
-	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->chip.irq_mask = irq_gc_mask_disable_reg;
+	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
 	ct->chip.irq_set_type = mxs_gpio_set_irq_type;
 	ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
 	ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
-	ct->regs.mask = PINCTRL_IRQEN(port);
+	ct->regs.enable = PINCTRL_IRQEN(port) + MXS_SET;
+	ct->regs.disable = PINCTRL_IRQEN(port) + MXS_CLR;
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_NESTED_LOCK,
 			       IRQ_NOREQUEST, 0);
-- 
2.9.3

^ permalink raw reply related

* gpio: mxs: fix duplicate level interrupts
From: Sascha Hauer @ 2016-10-21 13:11 UTC (permalink / raw)
  To: linux-arm-kernel

We observed that each level interrupt triggers two interrupts. This
is because the driver erroneously uses the IRQSTAT register to 
acknowledge level interrupts which according to the reference manual
is not possible. Patch 2/2 fixes that, look for its commit message
for a detailed description what happens and how it is fixed.

Sascha

----------------------------------------------------------------
Sascha Hauer (2):
      gpio: mxs: use enable/disable regs to (un)mask irqs
      gpio: mxs: fix duplicate level interrupts

^ permalink raw reply

* [PATCH v3 0/8] PM / Domains: DT support for domain idle states & atomic PM domains
From: Rafael J. Wysocki @ 2016-10-21 13:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161021013326.GA50423@linaro.org>

On Fri, Oct 21, 2016 at 3:33 AM, Lina Iyer <lina.iyer@linaro.org> wrote:
> On Fri, Oct 21 2016 at 16:48 -0600, Rafael J. Wysocki wrote:
>>
>> On Fri, Oct 21, 2016 at 12:44 AM, Lina Iyer <lina.iyer@linaro.org> wrote:
>>>
>>> On Mon, Oct 17 2016 at 01:30 -0600, Ulf Hansson wrote:
>>>>
>>>>
>>>> On 14 October 2016 at 19:47, Lina Iyer <lina.iyer@linaro.org> wrote:
>>>>>
>>>>>
>>>>> Hi all,
>>>>>
>>>>> Changes since v2 [3] -
>>>>> - Addressed review comments from v2.
>>>>>         - domain-idle-states documentation updated
>>>>>         - fixed compiler issues with imx driver
>>>>>         - minor code change in pm_domains.c
>>>>> - The series is available at [4].
>>>>>
>>>>> Changes since v1 [2] -
>>>>> - Addressed review comments from v1.
>>>>>         - Fixes around dynamic allocation of genpd states
>>>>>         - Used OF method for iterating phandles
>>>>>         - Updated documentation, examples
>>>>>         - Rename state variable (provider -> fwnode)
>>>>> - The series is available at [3].
>>>>>
>>>>> The changes from [1] are -
>>>>> - Allocating memory for domain idle states dynamically
>>>>> - Conform to naming conventions for internal and exported genpd
>>>>> functions
>>>>> - DT binding example for domain-idle-state
>>>>> - Use fwnode instead of of_node
>>>>> - Handle atomic case for removal of PM Domain
>>>>> - Rebase on top of Rafael's pm/genpd tree
>>>>>
>>>>> Thanks,
>>>>> Lina
>>>>>
>>>>> Lina Iyer (8):
>>>>>   PM / Domains: Make genpd state allocation dynamic
>>>>>   PM / Domain: Add residency property to genpd states
>>>>>   PM / Domains: Allow domain power states to be read from DT
>>>>>   PM / Domains: Save the fwnode in genpd_power_state
>>>>>   dt/bindings: Update binding for PM domain idle states
>>>>>   PM / Domains: Abstract genpd locking
>>>>>   PM / Domains: Support IRQ safe PM domains
>>>>>   PM / doc: Update device documentation for devices in IRQ safe PM
>>>>>     domains
>>>>>
>>>>>  .../devicetree/bindings/power/power_domain.txt     |  43 +++
>>>>>  Documentation/power/devices.txt                    |   9 +-
>>>>>  arch/arm/mach-imx/gpc.c                            |  17 +-
>>>>>  drivers/base/power/domain.c                        | 358
>>>>> +++++++++++++++++----
>>>>>  include/linux/pm_domain.h                          |  28 +-
>>>>>  5 files changed, 383 insertions(+), 72 deletions(-)
>>>>>
>>>>
>>>> Rafael, Lina,
>>>>
>>>> This looks good to me! Unless any other objections, I suggest to apply
>>>> this to get it tested in linux-next.
>>>>
>>>> Kind regards
>>>> Uffe
>>>>
>>> Rafael,
>>>
>>> If there are no objections, could you pick this patch for linux-next?
>>
>>
>> It is in my queue, but not at the top yet.
>>
> Thank you Rafael.

OK, I'm queuing up patches [1-7/8] as I don't see anything
particularly objectionable in them.

The documentation one needs some more work, however, and I've sent
comments on that one already.

Thanks,
Rafael

^ permalink raw reply

* [PATCH v5 3/9] vcodec: mediatek: Add Mediatek V4L2 Video Decoder Driver
From: Mauro Carvalho Chehab @ 2016-10-21 13:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161021110104.5733240e@vento.lan>

Em Fri, 21 Oct 2016 11:01:04 -0200
Mauro Carvalho Chehab <mchehab@osg.samsung.com> escreveu:

> Em Fri, 2 Sep 2016 20:19:54 +0800
> Tiffany Lin <tiffany.lin@mediatek.com> escreveu:
> 
> > Add v4l2 layer decoder driver for MT8173
> > 
> > Signed-off-by: Tiffany Lin <tiffany.lin@mediatek.com>  
> 
> > +int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
> > +{
> > +	int ret = 0;
> > +
> > +	switch (fourcc) {
> > +	case V4L2_PIX_FMT_H264:
> > +	case V4L2_PIX_FMT_VP8:
> > +	default:
> > +		return -EINVAL;
> > +	}  
> 
> Did you ever test this driver? The above code will *always* return
> -EINVAL, with will cause vidioc_vdec_s_fmt() to always fail!
> 
> I suspect that what you wanted to do, instead, is:
> 
> 	switch (fourcc) {
> 	case V4L2_PIX_FMT_H264:
> 	case V4L2_PIX_FMT_VP8:
> 		break;
> 	default:
> 		return -EINVAL;

Yeah, a latter patch in this series added a break there.

Thanks,
Mauro

^ permalink raw reply

* [PATCH v3 8/8] PM / doc: Update device documentation for devices in IRQ safe PM domains
From: Rafael J. Wysocki @ 2016-10-21 13:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-9-git-send-email-lina.iyer@linaro.org>

On Fri, Oct 14, 2016 at 7:47 PM, Lina Iyer <lina.iyer@linaro.org> wrote:
> Update documentation to reflect the changes made to support IRQ safe PM
> domains.
>
> Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
> Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
> ---
>  Documentation/power/devices.txt | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
> index 8ba6625..0401b53 100644
> --- a/Documentation/power/devices.txt
> +++ b/Documentation/power/devices.txt
> @@ -607,7 +607,14 @@ individually.  Instead, a set of devices sharing a power resource can be put
>  into a low-power state together at the same time by turning off the shared
>  power resource.  Of course, they also need to be put into the full-power state
>  together, by turning the shared power resource on.  A set of devices with this
> -property is often referred to as a power domain.
> +property is often referred to as a power domain. A power domain may also be
> +nested inside another power domain.
> +
> +Devices and PM domains may be defined as IRQ-safe, if they can be powered
> +on/off even when the IRQs are disabled. An IRQ-safe device in a domain will
> +disallow power management on the domain, unless the domain is also defined as
> +IRQ-safe. The restriction this framework imposes on the parent domain of an
> +IRQ-safe domain is that it must also be defined as IRQ-safe.

I would put this paragraph below, before the last paragraph in the section.

Also I suppose that a domain should only be defined as "IRQ-safe" if
all of the devices in it are "IRQ-safe" (or there will be problems at
least in principle).  If that is the case, it should be stated clearly
in the paragraph you are adding as well.

Thanks,
Rafael

^ permalink raw reply

* [PATCH 2/3] ARM: convert to generated system call tables
From: Arnd Bergmann @ 2016-10-21 13:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161019155325.GR1041@n2100.armlinux.org.uk>

On Wednesday, October 19, 2016 4:53:25 PM CEST Russell King - ARM Linux wrote:
> On Wed, Oct 19, 2016 at 05:30:49PM +0200, Arnd Bergmann wrote:
> > On Tuesday, October 18, 2016 8:31:38 PM CEST Russell King wrote:
> > > Convert ARM to use a similar mechanism to x86 to generate the unistd.h
> > > system call numbers and the various kernel system call tables.  This
> > > means that rather than having to edit three places (asm/unistd.h for
> > > the total number of system calls, uapi/asm/unistd.h for the system call
> > > numbers, and arch/arm/kernel/calls.S for the call table) we have only
> > > one place to edit, making the process much more simple.
> > > 
> > > The scripts have knowledge of the table padding requirements, so there's
> > > no need to worry about __NR_syscalls not fitting within the immediate
> > > constant field of ALU instructions anymore.
> > > 
> > > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > 
> > Ah, very nice!
> > 
> > I have some vague plans to do something like this for all architectures,
> > so having it done for one of the more complex examples (there are very
> > few architectures with more than one table) simplifies it a lot.
> > 
> > The next step is probably to do it for asm-generic/unistd.h, which
> > covers a lot of architectures, and then we can introduce a shared
> > table for all future additions so we only have to add the new calls
> > in one place, and change the scripts so they can merge two input
> > files into one.
> 
> Architecture maintainers like to verify that the system call works on
> their architecture before they push it out into the wild; your idea
> effectively bypasses architecture maintainer review and testing, so
> is bad.  For something as critical as system call interfaces, that
> step is critical: introducing a new system call across all architectures
> that then fails to work correctly on a particular architecture invites
> userspace to work around the problem, and the brokenness then becomes
> user API which can't be fixed.

I see your point, but I think there are serious issues with the current
approach as well:

- a lot of the less common architectures just don't get updated
  in time, out of 22 architectures that don't use asm-generic/unistd.h,
  only 12 have pwritev2 in linux-next, and only three have pkey_mprotect

- some architectures that add all syscalls sometimes make a mistake
  and forget one, e.g. alpha apparently never added __NR_bpf, but it
  did add the later __NR_execveat.

- when glibc updates their minimum supported kernel version, they
  would like to drop obsolete syscalls, but when each architecture
  adds the calls at a different time, it's hard to tell when a
  replacement syscall is guaranteed to be available

- linux-next produces warnings about missing syscalls on most
  architectures half of the time since it's impossible for an
  arch maintainer to hook up the number before the implementation
  is merged 

Regarding the review process, I'd really hope we've improved enough
that we can rely on the review on linux-arch/linux-api to catch
all serious issues like system call that cannot be defined the same
way on all architectures. If we fail at this, there is a more
serious issue with the review process.

Since all syscalls now go through SYSCALL_DEFINEx(), we have
covered the hardest part (sign/zero extending short arguments),
and a lot more people are aware of problems with struct alignment
since it differs between i386 and x86_64 and also affects all
ioctl interfaces. I think the last time a syscall made it in that
didn't just work on all architectures was sync_file_range, and
that was nine years ago.

> > > +# Where abi is:
> > > +#  common - for system calls shared between oabi and eabi
> > > +#  oabi   - for oabi-only system calls (may have compat)
> > > +#  eabi   - for eabi-only system calls
> > 
> > Why do we need all three? I would have guessed that these two are
> > sufficient to cover all cases:
> > 
> > arm	- one entry for eabi, optional second entry for oabi if different
> > oabi	- only one entry for oabi, syscall is not used on eabi
> 
> You haven't quite understood if you think the second entry gets used
> for OABI - but that's not surprising because the issues here are
> quite complex.
> 
> For OABI-only, all the oabi and first entry in common gets used.
> For EABI-only, all the eabi and first entry in common gets used.
> For EABI with OABI compat, EABI uses eabi and the first entry in common,
> but the OABI compat table uses the oabi and common entries, prefering
> the second entry where present.

Got it, I missed the fact that we support native OABI kernels.

> Yes, for the cases where we list the oabi and eabi together like you
> quoted, currently there are no differences between the system calls,
> and in my latest version, they've already been modified down to just
> a single "common" entry, leaving us without any eabi entries.
>
> However, I want to retain the ability to have separate eabi entries
> if needs be.  Such a case would be a system call which needs a helper
> for arguments passed in >4 registers on EABI but not OABI (eg, because
> of an non-naturally aligned 64-bit quantity passed in r1/r2 on OABI
> but r2/r3 in EABI.)

If we hit this case, why not just use the wrapper on both EABI
and OABI for simplicity? It's not like we care a lot about
micro-optimizing OABI any more.

> You'll find the latest version in the next linux-next, or my current
> for-next branch.

Ok. After rebasing my randconfig tree on today's linux-next, I needed
this hunk to avoid a warning:

<stdin>:1143:2: error: #warning syscall sync_file_range not implemented [-Werror=cpp]

diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index 70558e4459fd..7da1bbe69e56 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -355,7 +355,8 @@
 338	common	set_robust_list		sys_set_robust_list
 339	common	get_robust_list		sys_get_robust_list
 340	common	splice			sys_splice
-341	common	arm_sync_file_range	sys_sync_file_range2
+341	common	sync_file_range2		sys_sync_file_range2
+341	common	arm_sync_file_range
 342	common	tee			sys_tee
 343	common	vmsplice		sys_vmsplice
 344	common	move_pages		sys_move_pages

(or alternatively, add "#define sync_file_range2 arm_sync_file_range"
to uapi/asm/unistd.h).

> > > diff --git a/arch/arm/tools/syscallhdr.sh b/arch/arm/tools/syscallhdr.sh
> > > new file mode 100644
> > > index 000000000000..72d4b2e3bdec
> > > --- /dev/null
> > > +++ b/arch/arm/tools/syscallhdr.sh
> > 
> > The scripts are still very similar to the x86 version. Any chance
> > we can move them to a top-level scripts/syscall/ directory and make
> > them work for both architectures? It would be good to avoid duplicating
> > them for all the other architectures too, so starting out with a common
> > version could make that easier.
> 
> The fileguard prefix would have to be specified as an additional
> argument to achieve that, but I don't see that as a big problem.

Agreed, I saw the same thing there.

> The syscalltbl.sh script is particularly architecture specific, as
> our "compat" isn't the same as x86's "compat" requirements.

That brings up an interesting issue: it would be nice to use the
same input file for arch/arm/ and the compat mode of arch/arm64,
like x86 does. If we handle both oabi and arm64-compat in the same
file, we end up with a superset of what x86 does, and we could
use a single script again, and generate all four tables for
ARM (native OABI, OABI-on-EABI, native EABI, EABI-on-arm64).

Another related case in asm-generic, which defines three tables:
native 32-bit, native 64-bit and compat 32-bit. This one not only
needs to have three different function pointers (e.g. sys_fcntl64,
sys_fcntl and compat_sys_fcntl64) but also different macros (e.g.
__NR_fcntl64 and __NR_fcntl).

Anything wrong with this approach:?

/* ARM */
221  oabi  fcntl64                 sys_fcntl64             sys_oabi_fcntl64
221  eabi  fcntl64                 sys_fcntl64             compat_sys_fcntl64

/* asm-generic */
25   32    fcntl64                 sys_fcntl64             compat_sys_fcntl64
25   64    fcntl                   sys_fcntl

> The syscallnr.sh script kind-of looks like a candidate, but it has
> ARM arch specifics to it (knowing that the number of system calls
> needs to fit within the 8-bit value plus 4-bit shift constant
> representation of ARM ALU instructions.)  Maybe a generic version
> without that knowledge would work, provided architectures can
> override it.

syscallnr.sh isn't used on x86, and probably won't be needed on
most (or all) others, right? 

Generally speaking I'd think that having a check for the ${ARCH}
variable and doing this conditionally in that one script is fine
here, if we need other architecture specific versions, they we can
use case/esac.

Similar checks exist in scripts/recordmcount.pl,
scripts/package/builddeb, scripts/tags.sh etc.

	Arnd

^ permalink raw reply related

* [PATCH v5 3/9] vcodec: mediatek: Add Mediatek V4L2 Video Decoder Driver
From: Mauro Carvalho Chehab @ 2016-10-21 13:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1472818800-22558-4-git-send-email-tiffany.lin@mediatek.com>

Em Fri, 2 Sep 2016 20:19:54 +0800
Tiffany Lin <tiffany.lin@mediatek.com> escreveu:

> Add v4l2 layer decoder driver for MT8173
> 
> Signed-off-by: Tiffany Lin <tiffany.lin@mediatek.com>

> +int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
> +{
> +	int ret = 0;
> +
> +	switch (fourcc) {
> +	case V4L2_PIX_FMT_H264:
> +	case V4L2_PIX_FMT_VP8:
> +	default:
> +		return -EINVAL;
> +	}

Did you ever test this driver? The above code will *always* return
-EINVAL, with will cause vidioc_vdec_s_fmt() to always fail!

I suspect that what you wanted to do, instead, is:

	switch (fourcc) {
	case V4L2_PIX_FMT_H264:
	case V4L2_PIX_FMT_VP8:
		break;
	default:
		return -EINVAL;

Btw, this patch series has also several issues that were pointed by
checkpatch. Please *always* run checkpatch when submitting your work.

You should take a look at the Kernel documentation about how to
submit patches, at:
	https://mchehab.fedorapeople.org/kernel_docs/process/index.html

PS.: this time, I fixed the checkpatch issues for you. So, let me know
if the patch below is OK, and I'll merge it at media upstream,
assuming that the other patches in this series are ok.

-- 
Thanks,
Mauro

[PATCH] mtk-vcodec: fix some smatch warnings

Fix this bug:
	drivers/media/platform/mtk-vcodec/vdec_drv_if.c:38 vdec_if_init() info: ignoring unreachable code.

With is indeed a real problem that prevents the driver to work!

While here, also remove an used var, as reported by smatch:

	drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c: In function 'mtk_vcodec_init_dec_pm':
	drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c:29:17: warning: variable 'dev' set but not used [-Wunused-but-set-variable]
	  struct device *dev;
	                 ^~~

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 18182f5676d8..79ca03ac449c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -26,14 +26,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 {
 	struct device_node *node;
 	struct platform_device *pdev;
-	struct device *dev;
 	struct mtk_vcodec_pm *pm;
 	int ret = 0;
 
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	pm->mtkdev = mtkdev;
-	dev = &pdev->dev;
 	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
 		mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 3cb04ef45144..9813b2ffd5fa 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -31,6 +31,7 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264:
 	case V4L2_PIX_FMT_VP8:
+		break;
 	default:
 		return -EINVAL;
 	}

^ permalink raw reply related

* [PATCH] ahci: use pci_alloc_irq_vectors
From: Christoph Hellwig @ 2016-10-21 12:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161020154722.GH22012@rric.localdomain>

Hi Robert,

can you try the latest fixed in the libata tree:

https://git.kernel.org/cgit/linux/kernel/git/tj/libata.git/log/?h=for-4.9-fixes

^ permalink raw reply

* [PATCH] arm64: fix show_regs fallout from KERN_CONT changes
From: Mark Rutland @ 2016-10-21 12:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3a8485da-3f7d-07f8-95db-281e0115494d@arm.com>

Hi,

On Fri, Oct 21, 2016 at 12:34:11PM +0100, Robin Murphy wrote:
> > diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> > index ddce61b..3f31cf93 100644
> > --- a/arch/arm64/kernel/process.c
> > +++ b/arch/arm64/kernel/process.c
> > @@ -187,10 +187,19 @@ void __show_regs(struct pt_regs *regs)
> >  	printk("pc : [<%016llx>] lr : [<%016llx>] pstate: %08llx\n",
> >  	       regs->pc, lr, regs->pstate);
> >  	printk("sp : %016llx\n", sp);
> > -	for (i = top_reg; i >= 0; i--) {
> > +
> > +	i = top_reg;
> > +
> > +	while (i >= 0) {
> >  		printk("x%-2d: %016llx ", i, regs->regs[i]);
> > -		if (i % 2 == 0)
> > -			printk("\n");
> > +		i--;
> > +
> > +		if (i % 2 == 0) {
> > +			pr_cont("x%-2d: %016llx ", i, regs->regs[i]);
> > +			i--;
> > +		}
> > +
> > +		pr_cont("\n");
> >  	}
> 
> Might it be nicer to simply do this (or thereabouts)?

I don't think so; top_reg is either 12 (for compat), or 29 (for native),
so for the compat case, with the existing code the first line should be
one register (r12), with r1; r0 on the final line.

> 	for (i = top_reg; i > 1; i -= 2)
> 		printk("x%-2d: %016llx x%-2d: %016llx\n", i-1,
> 			regs->regs[i-1], i, regs->regs[i]);

... whereas here the first line would be two (r12 and r11) ... 

> 	if (i > 0)
> 		printk("x%-2d: %016llx\n", i-1, regs->regs[i-1]);

... and then r0 on its own.

Perhaps that's fine, but it would differ from the existing behaviour,
and make native and compat noticeably different.

We could try fixing up the first line prior to the loop, but that still
requires duplicating the format string thrice, manipulation of i, etc.

It looks like Will's taken my patch as-is, but if we can clean this up
further it would certainly be nice.

Thanks,
Mark.

^ permalink raw reply

* [PATCH 3/3] clk: keystone: Add sci-clk driver support
From: Tero Kristo @ 2016-10-21 12:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477053961-27128-1-git-send-email-t-kristo@ti.com>

In K2G, the clock handling is done through firmware executing on a
separate core. Linux kernel needs to communicate to the firmware
through TI system control interface to access any power management
related resources, including clocks.

The keystone sci-clk driver does this, by communicating to the
firmware through the TI SCI driver. The driver adds support for
registering clocks through DT, and basic required clock operations
like prepare/get_rate, etc.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 MAINTAINERS                    |   1 +
 drivers/clk/Kconfig            |   9 +
 drivers/clk/keystone/Makefile  |   1 +
 drivers/clk/keystone/sci-clk.c | 589 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 600 insertions(+)
 create mode 100644 drivers/clk/keystone/sci-clk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 960deb6..3f51df6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11897,6 +11897,7 @@ F:	include/dt-bindings/genpd/k2g.h
 F:	drivers/soc/ti/ti_sci_pm_domains.c
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	include/dt-bindings/clock/k2g.h
+F:	drivers/clk/keystone/sci-clk.c
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 6a8ac04..dce08a7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -169,6 +169,15 @@ config COMMON_CLK_NXP
 	---help---
 	  Support for clock providers on NXP platforms.
 
+config TI_SCI_CLK
+	tristate "TI System Control Interface clock drivers"
+	depends on (TI_SCI_PROTOCOL && COMMON_CLK_KEYSTONE) || COMPILE_TEST
+	default TI_SCI_PROTOCOL
+	---help---
+	  This adds the clock driver support over TI System Control Interface.
+	  If you wish to use clock resources from the PMMC firmware, say Y.
+	  Otherwise, say N.
+
 config COMMON_CLK_PALMAS
 	tristate "Clock driver for TI Palmas devices"
 	depends on MFD_PALMAS
diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
index 0477cf6..0e7993d 100644
--- a/drivers/clk/keystone/Makefile
+++ b/drivers/clk/keystone/Makefile
@@ -1 +1,2 @@
 obj-y			+= pll.o gate.o
+obj-$(CONFIG_TI_SCI_CLK)	+= sci-clk.o
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
new file mode 100644
index 0000000..f6af5bd
--- /dev/null
+++ b/drivers/clk/keystone/sci-clk.c
@@ -0,0 +1,589 @@
+/*
+ * SCI Clock driver for keystone based devices
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *	Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include <dt-bindings/clock/k2g.h>
+#include <dt-bindings/genpd/k2g.h>
+
+#define SCI_CLK_SSC_ENABLE		BIT(0)
+#define SCI_CLK_ALLOW_FREQ_CHANGE	BIT(1)
+#define SCI_CLK_INPUT_TERMINATION	BIT(2)
+
+/**
+ * struct sci_clk_data - TI SCI clock data
+ * @dev: device index
+ * @num_clks: number of clocks for this device
+ * @clocks: clocks array for this device
+ */
+struct sci_clk_data {
+	u16 dev;
+	u16 num_clks;
+	struct clk_hw **clocks;
+};
+
+/**
+ * struct sci_clk_provider - TI SCI clock provider representation
+ * @sci:    Handle to the System Control Interface protocol handler
+ * @ops:    Pointer to the SCI ops to be used by the clocks
+ * @dev:    Device pointer for the clock provider
+ * @clocks:	Clock data
+ */
+struct sci_clk_provider {
+	const struct ti_sci_handle *sci;
+	const struct ti_sci_clk_ops *ops;
+	struct device *dev;
+	struct sci_clk_data *clocks;
+};
+
+/**
+ * struct sci_clk - TI SCI clock representation
+ * @hw:		 Hardware clock cookie for common clock framework
+ * @dev_id:	 Device index
+ * @clk_id:	 Clock index
+ * @node:	 Clocks list link
+ * @provider:	 Master clock provider
+ * @flags:	 Flags for the clock
+ */
+struct sci_clk {
+	struct clk_hw hw;
+	u16 dev_id;
+	u8 clk_id;
+	struct list_head node;
+	struct sci_clk_provider *provider;
+	u8 flags;
+};
+
+#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
+
+/**
+ * sci_clk_prepare - Prepare (enable) a TI SCI clock
+ * @hw: clock to prepare
+ *
+ * Prepares a clock to be actively used. Returns the SCI protocol status.
+ */
+static int sci_clk_prepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE;
+	bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE;
+	bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION;
+
+	return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, enable_ssc,
+					     allow_freq_change,
+					     input_termination);
+}
+
+/**
+ * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
+ * @hw: clock to unprepare
+ *
+ * Un-prepares a clock from active state.
+ */
+static void sci_clk_unprepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+
+	ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id,
+					    clk->clk_id);
+	if (ret)
+		dev_err(clk->provider->dev,
+			"unprepare failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+}
+
+/**
+ * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
+ * @hw: clock to check status for
+ *
+ * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
+ * value if clock is enabled, zero otherwise.
+ */
+static int sci_clk_is_prepared(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool req_state, current_state;
+	int ret;
+
+	ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id,
+					clk->clk_id, &req_state,
+					&current_state);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"is_prepared failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return req_state;
+}
+
+/**
+ * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a TI SCI clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u64 freq;
+	int ret;
+
+	ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
+					   clk->clk_id, &freq);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return (u32)freq;
+}
+
+/**
+ * sci_clk_determine_rate - Determines a clock rate a clock can be set to
+ * @hw: clock to change rate for
+ * @req: requested rate configuration for the clock
+ *
+ * Determines a suitable clock rate and parent for a TI SCI clock.
+ * The parent handling is un-used, as generally the parent clock rates
+ * are not known by the kernel; instead these are internally handled
+ * by the firmware. Returns 0 on success, negative error value on failure.
+ */
+static int sci_clk_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+	u64 new_rate;
+
+	ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
+						      clk->dev_id,
+						      clk->clk_id,
+						      req->min_rate,
+						      req->rate,
+						      req->max_rate,
+						      &new_rate);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"determine-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return ret;
+	}
+
+	req->rate = new_rate;
+
+	return 0;
+}
+
+/**
+ * sci_clk_set_rate - Set rate for a TI SCI clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for TI SCI clocks
+ *
+ * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
+ * protocol status.
+ */
+static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
+					    clk->clk_id, rate, rate, rate);
+}
+
+/**
+ * sci_clk_get_parent - Get the current parent of a TI SCI clock
+ * @hw: clock to get parent for
+ *
+ * Returns the index of the currently selected parent for a TI SCI clock.
+ */
+static u8 sci_clk_get_parent(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u8 parent_id;
+	int ret;
+
+	ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, &parent_id);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"get-parent failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return parent_id - clk->clk_id - 1;
+}
+
+/**
+ * sci_clk_set_parent - Set the parent of a TI SCI clock
+ * @hw: clock to set parent for
+ * @index: new parent index for the clock
+ *
+ * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
+ */
+static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
+					      clk->clk_id,
+					      index + 1 + clk->clk_id);
+}
+
+static const struct clk_ops sci_clk_ops = {
+	.prepare = sci_clk_prepare,
+	.unprepare = sci_clk_unprepare,
+	.is_prepared = sci_clk_is_prepared,
+	.recalc_rate = sci_clk_recalc_rate,
+	.determine_rate = sci_clk_determine_rate,
+	.set_rate = sci_clk_set_rate,
+	.get_parent = sci_clk_get_parent,
+	.set_parent = sci_clk_set_parent,
+};
+
+/**
+ * _sci_clk_get - Gets a handle for an SCI clock
+ * @provider: Handle to SCI clock provider
+ * @dev_id: device ID for the clock to register
+ * @clk_id: clock ID for the clock to register
+ *
+ * Gets a handle to an existing TI SCI hw clock, or builds a new clock
+ * entry and registers it with the common clock framework. Called from
+ * the common clock framework, when a corresponding of_clk_get call is
+ * executed, or recursively from itself when parsing parent clocks.
+ * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
+				     u16 dev_id, u8 clk_id)
+{
+	struct clk_init_data init = { NULL };
+	struct sci_clk *sci_clk = NULL;
+	char *name = NULL;
+	char **parent_names = NULL;
+	int i;
+	int ret;
+
+	sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
+	if (!sci_clk)
+		return ERR_PTR(-ENOMEM);
+
+	sci_clk->dev_id = dev_id;
+	sci_clk->clk_id = clk_id;
+	sci_clk->provider = provider;
+
+	ret = provider->ops->get_num_parents(provider->sci, dev_id,
+					     clk_id,
+					     &init.num_parents);
+	if (ret)
+		goto err;
+
+	name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
+			 sci_clk->dev_id, sci_clk->clk_id);
+
+	init.name = name;
+
+	if (init.num_parents < 2)
+		init.num_parents = 0;
+
+	if (init.num_parents) {
+		parent_names = devm_kcalloc(provider->dev, init.num_parents,
+					    sizeof(char *), GFP_KERNEL);
+
+		if (!parent_names) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		for (i = 0; i < init.num_parents; i++) {
+			char *parent_name;
+
+			parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d",
+						dev_name(provider->dev),
+						sci_clk->dev_id,
+						sci_clk->clk_id + 1 + i);
+			if (!parent_name) {
+				ret = -ENOMEM;
+				goto err;
+			}
+			parent_names[i] = parent_name;
+		}
+		init.parent_names = (const char * const *)parent_names;
+	}
+
+	init.ops = &sci_clk_ops;
+	sci_clk->hw.init = &init;
+
+	ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
+	if (ret) {
+		dev_err(provider->dev, "failed clk register with %d\n", ret);
+		goto err;
+	}
+	kfree(name);
+
+	return &sci_clk->hw;
+
+err:
+	if (parent_names) {
+		for (i = 0; i < init.num_parents; i++)
+			devm_kfree(provider->dev, parent_names[i]);
+
+		devm_kfree(provider->dev, parent_names);
+	}
+
+	devm_kfree(provider->dev, sci_clk);
+
+	kfree(name);
+
+	return ERR_PTR(ret);
+}
+
+/**
+ * sci_clk_get - Xlate function for getting clock handles
+ * @clkspec: device tree clock specifier
+ * @data: pointer to the clock provider
+ *
+ * Xlate function for retrieving clock TI SCI hw clock handles based on
+ * device tree clock specifier. Called from the common clock framework,
+ * when a corresponding of_clk_get call is executed. Returns a pointer
+ * to the TI SCI hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct sci_clk_provider *provider = data;
+	u16 dev_id;
+	u8 clk_id;
+	struct sci_clk_data *clks = provider->clocks;
+
+	if (clkspec->args_count != 2)
+		return ERR_PTR(-EINVAL);
+
+	dev_id = clkspec->args[0];
+	clk_id = clkspec->args[1];
+
+	while (clks->num_clks) {
+		if (clks->dev == dev_id) {
+			if (clk_id >= clks->num_clks)
+				return ERR_PTR(-EINVAL);
+
+			return clks->clocks[clk_id];
+		}
+
+		clks++;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+
+static int ti_sci_init_clocks(struct sci_clk_provider *p)
+{
+	struct sci_clk_data *data = p->clocks;
+	struct clk_hw *hw;
+	int i;
+
+	while (data->num_clks) {
+		data->clocks = devm_kcalloc(p->dev, data->num_clks,
+					    sizeof(struct sci_clk),
+					    GFP_KERNEL);
+		if (!data->clocks)
+			return -ENOMEM;
+
+		for (i = 0; i < data->num_clks; i++) {
+			hw = _sci_clk_build(p, data->dev, i);
+			if (!IS_ERR(hw)) {
+				data->clocks[i] = hw;
+				continue;
+			}
+
+			/* Skip any holes in the clock lists */
+			if (PTR_ERR(hw) == -ENODEV)
+				continue;
+
+			return PTR_ERR(hw);
+		}
+		data++;
+	}
+
+	return 0;
+}
+
+static const struct sci_clk_data k2g_clk_data[] = {
+	{ .dev = K2G_DEV_PMMC0, .num_clks = K2G_DEV_PMMC_MPM_DAP_CLK + 1 },
+	{ .dev = K2G_DEV_MLB0, .num_clks = K2G_DEV_MLB_MLBP_IO_CLK + 1 },
+	{ .dev = K2G_DEV_DSS0, .num_clks = K2G_DEV_DSS_PI_DSS_VP_CLK + 1 },
+	{ .dev = K2G_DEV_MCBSP0, .num_clks = K2G_DEV_MCBSP_CLKS_PARENT_UART_PLL + 1 },
+	{ .dev = K2G_DEV_MCASP0, .num_clks = K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL + 1 },
+	{ .dev = K2G_DEV_MCASP1, .num_clks = K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL + 1 },
+	{ .dev = K2G_DEV_MCASP2, .num_clks = K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL + 1 },
+	{ .dev = K2G_DEV_DCAN0, .num_clks = K2G_DEV_DCAN_CAN_CLK + 1 },
+	{ .dev = K2G_DEV_DCAN1, .num_clks = K2G_DEV_DCAN_CAN_CLK + 1 },
+	{ .dev = K2G_DEV_EMIF0, .num_clks = K2G_DEV_EMIF_VBUSP_CLK + 1 },
+	{ .dev = K2G_DEV_MMCHS0, .num_clks = K2G_DEV_MMCHS_CLK32K + 1 },
+	{ .dev = K2G_DEV_MMCHS1, .num_clks = K2G_DEV_MMCHS_CLK32K + 1 },
+	{ .dev = K2G_DEV_GPMC0, .num_clks = K2G_DEV_GPMC_GPMC_FCLK + 1 },
+	{ .dev = K2G_DEV_ELM0, .num_clks = K2G_DEV_ELM_CLK + 1 },
+	{ .dev = K2G_DEV_SPI0, .num_clks = K2G_DEV_SPI_VBUSP_CLK + 1 },
+	{ .dev = K2G_DEV_SPI1, .num_clks = K2G_DEV_SPI_VBUSP_CLK + 1 },
+	{ .dev = K2G_DEV_SPI2, .num_clks = K2G_DEV_SPI_VBUSP_CLK + 1 },
+	{ .dev = K2G_DEV_SPI3, .num_clks = K2G_DEV_SPI_VBUSP_CLK + 1 },
+	{ .dev = K2G_DEV_ICSS0, .num_clks = K2G_DEV_ICSS_IEPCLK_CLK + 1 },
+	{ .dev = K2G_DEV_ICSS1, .num_clks = K2G_DEV_ICSS_IEPCLK_CLK + 1 },
+	{ .dev = K2G_DEV_USB0, .num_clks = K2G_DEV_USB_CLKCORE + 1 },
+	{ .dev = K2G_DEV_USB1, .num_clks = K2G_DEV_USB_CLKCORE + 1 },
+	{ .dev = K2G_DEV_NSS0, .num_clks = K2G_DEV_NSS_RMII_MHZ_50_CLK + 1 },
+	{ .dev = K2G_DEV_PCIE0, .num_clks = K2G_DEV_PCIE_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_GPIO0, .num_clks = K2G_DEV_GPIO_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_GPIO1, .num_clks = K2G_DEV_GPIO_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_TIMER64_0, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_TIMER64_1, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_TIMER64_2, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_TIMER64_3, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_TIMER64_4, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_TIMER64_5, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_TIMER64_6, .num_clks = K2G_DEV_TIMER64_TOUTH + 1 },
+	{ .dev = K2G_DEV_MSGMGR0, .num_clks = K2G_DEV_MSGMGR_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_BOOTCFG0, .num_clks = K2G_DEV_BOOTCFG_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_ARM_BOOTROM0, .num_clks = K2G_DEV_ARM_BOOTROM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_DSP_BOOTROM0, .num_clks = K2G_DEV_DSP_BOOTROM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_DEBUGSS0, .num_clks = K2G_DEV_DEBUGSS_STMXPT_CLK + 1 },
+	{ .dev = K2G_DEV_UART0, .num_clks = K2G_DEV_UART_CBA_CLK_PI + 1 },
+	{ .dev = K2G_DEV_UART1, .num_clks = K2G_DEV_UART_CBA_CLK_PI + 1 },
+	{ .dev = K2G_DEV_UART2, .num_clks = K2G_DEV_UART_CBA_CLK_PI + 1 },
+	{ .dev = K2G_DEV_EHRPWM0, .num_clks = K2G_DEV_EHRPWM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EHRPWM1, .num_clks = K2G_DEV_EHRPWM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EHRPWM2, .num_clks = K2G_DEV_EHRPWM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EHRPWM3, .num_clks = K2G_DEV_EHRPWM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EHRPWM4, .num_clks = K2G_DEV_EHRPWM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EHRPWM5, .num_clks = K2G_DEV_EHRPWM_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EQEP0, .num_clks = K2G_DEV_EQEP_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EQEP1, .num_clks = K2G_DEV_EQEP_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EQEP2, .num_clks = K2G_DEV_EQEP_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_ECAP0, .num_clks = K2G_DEV_ECAP_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_ECAP1, .num_clks = K2G_DEV_ECAP_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_I2C0, .num_clks = K2G_DEV_I2C_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_I2C1, .num_clks = K2G_DEV_I2C_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_I2C2, .num_clks = K2G_DEV_I2C_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_EDMA0, .num_clks = K2G_DEV_EDMA_TPCC_CLK + 1 },
+	{ .dev = K2G_DEV_SEMAPHORE0, .num_clks = K2G_DEV_SEMAPHORE_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_INTC0, .num_clks = K2G_DEV_INTC_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_GIC0, .num_clks = K2G_DEV_GIC_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_QSPI0, .num_clks = K2G_DEV_QSPI_QSPI_CLK_I + 1 },
+	{ .dev = K2G_DEV_ARM_64B_COUNTER0, .num_clks = K2G_DEV_ARM_64B_COUNTER_VBUSP_CLK + 1 },
+	{ .dev = K2G_DEV_TETRIS0, .num_clks = K2G_DEV_TETRIS_SUBSYS_CLK + 1 },
+	{ .dev = K2G_DEV_CGEM0, .num_clks = K2G_DEV_CGEM_TRACE_CLK + 1 },
+	{ .dev = K2G_DEV_MSMC0, .num_clks = K2G_DEV_MSMC_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_CBASS0, .num_clks = K2G_DEV_CBASS_VBUS_CLK + 1 },
+	{ .dev = K2G_DEV_BOARD0, .num_clks = K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5H + 1 },
+	{ .dev = K2G_DEV_EDMA1, .num_clks = K2G_DEV_EDMA_TPCC_CLK + 1 },
+	{ .num_clks = 0 },
+};
+
+static const struct of_device_id ti_sci_clk_of_match[] = {
+	{ .compatible = "ti,k2g-sci-clk", .data = &k2g_clk_data },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
+
+/**
+ * ti_sci_clk_probe - Probe function for the TI SCI clock driver
+ * @pdev: platform device pointer to be probed
+ *
+ * Probes the TI SCI clock device. Allocates a new clock provider
+ * and registers this to the common clock framework. Also applies
+ * any required flags to the identified clocks via clock lists
+ * supplied from DT. Returns 0 for success, negative error value
+ * for failure.
+ */
+static int ti_sci_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct sci_clk_provider *provider;
+	const struct ti_sci_handle *handle;
+	struct sci_clk_data *data;
+	int ret;
+
+	data = (struct sci_clk_data *)
+		of_match_node(ti_sci_clk_of_match, np)->data;
+
+	handle = devm_ti_sci_get_handle(dev);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	provider->clocks = data;
+
+	provider->sci = handle;
+	provider->ops = &handle->ops.clk_ops;
+	provider->dev = dev;
+
+	ti_sci_init_clocks(provider);
+
+	ret = of_clk_add_hw_provider(np, sci_clk_get, provider);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_remove - Remove TI SCI clock device
+ * @pdev: platform device pointer for the device to be removed
+ *
+ * Removes the TI SCI device. Unregisters the clock provider registered
+ * via common clock framework. Any memory allocated for the device will
+ * be free'd silently via the devm framework. Returns 0 always.
+ */
+static int ti_sci_clk_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static struct platform_driver ti_sci_clk_driver = {
+	.probe = ti_sci_clk_probe,
+	.remove = ti_sci_clk_remove,
+	.driver = {
+		.name = "ti-sci-clk",
+		.of_match_table = of_match_ptr(ti_sci_clk_of_match),
+	},
+};
+module_platform_driver(ti_sci_clk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
+MODULE_AUTHOR("Tero Kristo");
+MODULE_ALIAS("platform:ti-sci-clk");
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/3] dt-binding: clock: Add k2g clock definitions
From: Tero Kristo @ 2016-10-21 12:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477053961-27128-1-git-send-email-t-kristo@ti.com>

Add identifiers for the K2G clocks managed by the PMMC.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 MAINTAINERS                     |   1 +
 include/dt-bindings/clock/k2g.h | 234 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 235 insertions(+)
 create mode 100644 include/dt-bindings/clock/k2g.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3ee7c7a..960deb6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11896,6 +11896,7 @@ F:	Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
 F:	include/dt-bindings/genpd/k2g.h
 F:	drivers/soc/ti/ti_sci_pm_domains.c
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
+F:	include/dt-bindings/clock/k2g.h
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/include/dt-bindings/clock/k2g.h b/include/dt-bindings/clock/k2g.h
new file mode 100644
index 0000000..cddffc3
--- /dev/null
+++ b/include/dt-bindings/clock/k2g.h
@@ -0,0 +1,234 @@
+/*
+ * TI K2G SoC clock definitions
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DT_BINDINGS_CLOCK_K2G_H__
+#define __DT_BINDINGS_CLOCK_K2G_H__
+
+/*
+ * The clock IDs listed in this file are describing the clocks at IP's
+ * boundaries. The firmware is not exposing any of the generic clocks
+ * from the system, those are handled internally by the firmware.
+ */
+#define K2G_DEV_PMMC_MPM_VBUS_CLK		0
+#define K2G_DEV_PMMC_MPM_FUNC_32K_CLK		1
+#define K2G_DEV_PMMC_MPM_FUNC_OSC_CLK		2
+#define K2G_DEV_PMMC_MPM_DAP_CLK		3
+
+#define K2G_DEV_MLB_MLB_SYS_CLK			0
+#define K2G_DEV_MLB_MLB_SHB_OCP_CLK		1
+#define K2G_DEV_MLB_MLB_SPB_OCP_CLK		2
+#define K2G_DEV_MLB_MLB_IO_CLK			3
+#define K2G_DEV_MLB_MLBP_IO_CLK			4
+
+#define K2G_DEV_DSS_PI_DSS_OCP_CLK		0
+#define K2G_DEV_DSS_PI_DSS_VP_CLK		1
+
+#define K2G_DEV_MCBSP_VBUS_CLK			0
+#define K2G_DEV_MCBSP_CLKS			1
+#define K2G_DEV_MCBSP_CLKS_PARENT_AUDIO_OSC	2
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLB_IO_CLK	3
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCBSP_CLKS_PARENT_SYS_OSCCLK	5
+#define K2G_DEV_MCBSP_CLKS_PARENT_XREFCLK	6
+#define K2G_DEV_MCBSP_CLKS_PARENT_UART_PLL	7
+
+#define K2G_DEV_MCASP_VBUS_CLK			0
+#define K2G_DEV_MCASP_AUX_CLK			1
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_AUDIO_OSC		2
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLB_IO_CLK		3
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_SYS_OSCCLK		5
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_XREFCLK		6
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL		7
+
+#define K2G_DEV_DCAN_VBUS_CLK			0
+#define K2G_DEV_DCAN_CAN_CLK			1
+
+#define K2G_DEV_EMIF_V_CLK			0
+#define K2G_DEV_EMIF_M_CLK			1
+#define K2G_DEV_EMIF_DFT_LOCAL_CLK		2
+#define K2G_DEV_EMIF_PUB_CTL_CLK		3
+#define K2G_DEV_EMIF_PHY_CTL_CLK		4
+#define K2G_DEV_EMIF_VBUSP_CLK			5
+
+#define K2G_DEV_MMCHS_VBUS_CLK			0
+#define K2G_DEV_MMCHS_CLK_ADPI			1
+#define K2G_DEV_MMCHS_CLK32K			2
+
+#define K2G_DEV_GPMC_GPMC_FCLK			0
+
+#define K2G_DEV_ELM_CLK				0
+
+#define K2G_DEV_SPI_VBUSP_CLK			0
+
+#define K2G_DEV_ICSS_VCLK_CLK			0
+#define K2G_DEV_ICSS_CORE_CLK			1
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_ICSS_PLL	2
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_NSS_PLL	3
+#define K2G_DEV_ICSS_UCLK_CLK			4
+#define K2G_DEV_ICSS_IEPCLK_CLK			5
+
+#define K2G_DEV_USB_BUS_CLK			0
+#define K2G_DEV_USB_PHYMMR_CLK			1
+#define K2G_DEV_USB_SUSP_CLK			2
+#define K2G_DEV_USB_REF_CLK			3
+#define K2G_DEV_USB_DFT_ULPI_CLK		4
+#define K2G_DEV_USB_DFT_UTMI_CLK		5
+#define K2G_DEV_USB_CLKCORE			6
+
+#define K2G_DEV_NSS_VCLK			0
+#define K2G_DEV_NSS_SA_UL_CLK			1
+#define K2G_DEV_NSS_SA_UL_X1_CLK		2
+#define K2G_DEV_NSS_ESW_CLK			3
+/*
+ * Mux register is internal to the CPTS, so we must allow NSS to control it.
+ * CPTS_REFCLK_P/N is a direct input to this mux, so ignore it is ignored
+ * in the SoC clock tree.
+ */
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_2		4
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_3		5
+#define K2G_DEV_NSS_CPTS_TIMI0			6
+#define K2G_DEV_NSS_CPTS_TIMI1			7
+#define K2G_DEV_NSS_CPTS_NSS_PLL		8
+#define K2G_DEV_NSS_GMII_RFTCLK			9
+#define K2G_DEV_NSS_RGMII_MHZ_5_CLK		10
+#define K2G_DEV_NSS_RGMII_MHZ_50_CLK		11
+#define K2G_DEV_NSS_RGMII_MHZ_250_CLK		12
+#define K2G_DEV_NSS_RMII_MHZ_50_CLK		13
+
+#define K2G_DEV_PCIE_VBUS_CLK			0
+
+#define K2G_DEV_OTP_VBUS_CLK			0
+
+#define K2G_DEV_GPIO_VBUS_CLK			0
+
+#define K2G_DEV_TIMER64_VBUS_CLK		0
+#define K2G_DEV_TIMER64_TINL			1
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI0	2
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI1	3
+#define K2G_DEV_TIMER64_TINH			4
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI0	5
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI1	6
+#define K2G_DEV_TIMER64_TOUTL			7
+#define K2G_DEV_TIMER64_TOUTH			8
+
+#define K2G_DEV_SEC_MGR_SEC_CLK_PI		0
+
+#define K2G_DEV_MSGMGR_VBUS_CLK			0
+
+#define K2G_DEV_BOOTCFG_VBUS_CLK		0
+
+#define K2G_DEV_ARM_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DSP_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DEBUGSS_VBUSP_CTTBRCLK_CLK	0
+#define K2G_DEV_DEBUGSS_VBUSP_STMD0_CLK		1
+#define K2G_DEV_DEBUGSS_VBUSP_SLAVE_CLK		2
+#define K2G_DEV_DEBUGSS_VBUSP_MASTER_CLK	3
+#define K2G_DEV_DEBUGSS_TCK			4
+#define K2G_DEV_DEBUGSS_CS_TRCEXPT_CLK		5
+#define K2G_DEV_DEBUGSS_DSP_TRACECLK		6
+#define K2G_DEV_DEBUGSS_STMXPT_CLK		7
+
+#define K2G_DEV_UART_CBA_CLK_PI			0
+
+#define K2G_DEV_EHRPWM_VBUS_CLK			0
+
+#define K2G_DEV_EQEP_VBUS_CLK			0
+
+#define K2G_DEV_ECAP_VBUS_CLK			0
+
+#define K2G_DEV_I2C_VBUS_CLK			0
+
+#define K2G_DEV_CP_TRACER_CP_TRACER_CLK		0
+
+#define K2G_DEV_EDMA_TPTC_CLK			0
+#define K2G_DEV_EDMA_TPCC_CLK			1
+
+#define K2G_DEV_SEMAPHORE_VBUS_CLK		0
+
+#define K2G_DEV_INTC_VBUS_CLK			0
+
+#define K2G_DEV_GIC_VBUS_CLK			0
+
+#define K2G_DEV_QSPI_QSPI_CLK			0
+#define K2G_DEV_QSPI_DATA_BUS_CLK		1
+#define K2G_DEV_QSPI_CFG_BUS_CLK		2
+#define K2G_DEV_QSPI_QSPI_CLK_O			3
+#define K2G_DEV_QSPI_QSPI_CLK_I			4
+
+#define K2G_DEV_ARM_64B_COUNTER_CLK_INPUT	0
+#define K2G_DEV_ARM_64B_COUNTER_VBUSP_CLK	1
+
+#define K2G_DEV_TETRIS_CORE_CLK			0
+#define K2G_DEV_TETRIS_SUBSYS_CLK		1
+
+#define K2G_DEV_CGEM_CORE_CLK			0
+#define K2G_DEV_CGEM_TRACE_CLK			1
+
+#define K2G_DEV_MSMC_VBUS_CLK			0
+
+#define K2G_DEV_DFT_SS_VBUS_CLK			0
+#define K2G_DEV_DFT_SS_TCK			1
+
+#define K2G_DEV_CBASS_VBUS_CLK			0
+
+#define K2G_DEV_SMARTREFLEX_SCLK_CLK		0
+#define K2G_DEV_SMARTREFLEX_REFCLK1_CLK		1
+#define K2G_DEV_SMARTREFLEX_TEMPMCLK_CLK	2
+
+#define K2G_DEV_EFUSE_VBUS_CLK			0
+
+/* Outputs from board (inputs to SoC) */
+#define K2G_DEV_BOARD_SYS_OSCIN			0
+#define K2G_DEV_BOARD_SYS_CLK			1
+#define K2G_DEV_BOARD_AUDIO_OSCIN		2
+#define K2G_DEV_BOARD_DDR			3
+#define K2G_DEV_BOARD_MLBCLK			4
+#define K2G_DEV_BOARD_MLBPCLK			5
+#define K2G_DEV_BOARD_XREFCLK			6
+#define K2G_DEV_BOARD_TIMI0			7
+#define K2G_DEV_BOARD_TIMI1			8
+
+/* Inputs to board (outputs from SoC) */
+#define K2G_DEV_BOARD_SYSCLKOUT			10
+#define K2G_DEV_BOARD_OBSCLK			11
+#define K2G_DEV_BOARD_OBSCLK_PARENT_MAIN_PLL	12
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DSS_PLL	13
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ARM_PLL	14
+#define K2G_DEV_BOARD_OBSCLK_PARENT_UART_PLL	15
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ICSS_PLL	16
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DDR_PLL	17
+#define K2G_DEV_BOARD_OBSCLK_PARENT_PLL_CTRL	18
+#define K2G_DEV_BOARD_OBSCLK_PARENT_NSS_PLL	19
+#define K2G_DEV_BOARD_OBSCLK_PARENT_SYSOSC	20
+#define K2G_DEV_BOARD_MII_CLKOUT		21
+#define K2G_DEV_BOARD_TIMO0			22
+#define K2G_DEV_BOARD_TIMO1			23
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0L	24
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0H	25
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1L	26
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1H	27
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2L	28
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2H	29
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3L	30
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3H	31
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4L	32
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4H	33
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5L	34
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5H	35
+
+#endif
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/3] Documentation: dt: Add TI SCI clock driver
From: Tero Kristo @ 2016-10-21 12:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477053961-27128-1-git-send-email-t-kristo@ti.com>

Add a clock implementation, TI SCI clock, that will hook to the common
clock framework, and allow each clock to be controlled via TI SCI
protocol.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 .../devicetree/bindings/clock/ti,sci-clk.txt       | 37 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
new file mode 100644
index 0000000..bfc3ca4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
@@ -0,0 +1,37 @@
+Texas Instruments TI-SCI Clocks
+===============================
+
+All clocks on Texas Instruments' SoCs that contain a System Controller,
+are only controlled by this entity. Communication between a host processor
+running an OS and the System Controller happens through a protocol known
+as TI-SCI[1]. This clock implementation plugs into the common clock
+framework and makes use of the TI-SCI protocol on clock API requests.
+
+[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+Required properties:
+-------------------
+- compatible: Must be "ti,k2g-sci-clk"
+- #clock-cells: Shall be 2.
+  In clock consumers, this cell represents the device ID and clock ID
+  exposed by the PM firmware. The assignments can be found in the header
+  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
+  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
+  is the SoC involved, for example 'k2g'.
+
+Examples:
+--------
+
+pmmc: pmmc {
+	compatible = "ti,k2g-sci";
+
+	k2g_clks: k2g_clks {
+		compatible = "ti,k2g-sci-clk";
+		#clock-cells = <2>;
+	};
+};
+
+uart0: serial at 2530c00 {
+	compatible = "ns16550a";
+	clocks = <&k2g_clks K2G_DEV_UART0 0>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 3eaac5ed..3ee7c7a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11895,6 +11895,7 @@ F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
 F:	include/dt-bindings/genpd/k2g.h
 F:	drivers/soc/ti/ti_sci_pm_domains.c
+F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
-- 
1.9.1

^ permalink raw reply related


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