Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4] ARM: davinci: da8xx: Fix sleeping function called from invalid context
From: Sekhar Nori @ 2016-12-05  6:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <907a3c22-534f-80ce-daff-be84dd5e5cf8@lechnology.com>

Hi David,

On Monday 05 December 2016 09:14 AM, David Lechner wrote:
> I have just tried this patch with a bunch of kernel hacking options
> enabled. I am getting the message show at the end of this email. We
> still have the problem of nested spin locks due to nested calls to
> clk_enable(). So, really, we need to use __clk_enable() and
> __clk_disable() from arch/arm/mach-davinci/clock.c in
> usb20_phy_clk_enable() above.

Good catch. I noticed  that common clock framework uses a more elaborate
mechanism to allow nested clock API calls (see clk_prepare_lock()), but
we don't (yet) have that issue in mach-davinci since the recursive calls
are still in mach-davinci and dont need the exported API to be
recursively callable.

> Applying the following patch on top of your patch fixed the recursive
> lock message.

The patch looks okay to me, except couple of minor adjustments.

> 
> ---
> 
> diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
> index df42c93..4fba579 100644
> --- a/arch/arm/mach-davinci/clock.c
> +++ b/arch/arm/mach-davinci/clock.c
> @@ -31,7 +31,7 @@ static LIST_HEAD(clocks);
>  static DEFINE_MUTEX(clocks_mutex);
>  static DEFINE_SPINLOCK(clockfw_lock);
> 
> -static void __clk_enable(struct clk *clk)
> +void __clk_enable(struct clk *clk)

Now that this function is going to be used outside of this file, lets
drop the __ naming convention and call this davinci_clk_enable() in line
with how other davinci-local clock APIs are named. Same thing for the
disable counterpart.

Also, the making these function non-static should be a patch of its own.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH v3] mach-omap2: fixing wrong strcat for Non-NULL terminated string
From: Maninder Singh @ 2016-12-05  5:27 UTC (permalink / raw)
  To: linux-arm-kernel

Issue caught with static analysis tool:
"Dangerous usage of 'name' (strncpy doesn't always 0-terminate it)"

Use strlcpy _includes_ the NUL terminator, and  strlcat() which ensures 
that it won't overflow the buffer.

Reported-by: Maninder Singh <maninder1.s@samsung.com>
Signed-off-by: Vaneet Narang <v.narang@samsung.com>
Signed-off-by: Russell King <linux@armlinux.org.uk>
---
v1 -> v2: changed strncpy to strlcpy
v2 -> v3: use of strlcat as suggested by Russell to
	  make change clearer and simpler.

 arch/arm/mach-omap2/omap_hwmod.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 759e1d4..e8b9887 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -741,14 +741,14 @@ static int _init_main_clk(struct omap_hwmod *oh)
 	int ret = 0;
 	char name[MOD_CLK_MAX_NAME_LEN];
 	struct clk *clk;
+	static const char modck[] = "_mod_ck";
 
-	/* +7 magic comes from '_mod_ck' suffix */
-	if (strlen(oh->name) + 7 > MOD_CLK_MAX_NAME_LEN)
+	if (strlen(oh->name) >= MOD_CLK_MAX_NAME_LEN - strlen(modck))
 		pr_warn("%s: warning: cropping name for %s\n", __func__,
 			oh->name);
 
-	strncpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - 7);
-	strcat(name, "_mod_ck");
+	strlcpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - strlen(modck));
+	strlcat(name, modck, MOD_CLK_MAX_NAME_LEN);
 
 	clk = clk_get(NULL, name);
 	if (!IS_ERR(clk)) {
-- 
1.9.1

^ permalink raw reply related

* [PATCH 3/3] ASoC: simple-card-utils: enable clocks/clock-names/clock-ranges
From: Kuninori Morimoto @ 2016-12-05  5:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874m2jvtmw.wl%kuninori.morimoto.gx@renesas.com>

From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Current simple-card is supporting this style for clocks

	sound {
		...
		simple-audio-card,cpu {
			sound-dai = <&xxx>;
			clocks = <&cpu_clock>;
		};
		simple-audio-card,codec {
			sound-dai = <&xxx>;
			clocks = <&codec_clock>;
		};
	};

Now, it can support this style too, because we can use
devm_get_clk_from_child() now.

	sound {
		...
		clocks = <&cpu_clock>, <&codec_clock>;
		clock-names = "cpu", "codec";
		clock-ranges;
		...
		simple-audio-card,cpu {
			sound-dai = <&xxx>;
		};
		simple-audio-card,codec {
			sound-dai = <&xxx>;
		};
	};

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 .../devicetree/bindings/sound/simple-card.txt      | 32 ++++++++++++++++++
 sound/soc/generic/simple-card-utils.c              | 39 +++++++++++++++++++++-
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt
index c7a9393..43a710b 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.txt
+++ b/Documentation/devicetree/bindings/sound/simple-card.txt
@@ -86,6 +86,7 @@ Optional CPU/CODEC subnodes properties:
 					  in dai startup() and disabled with
 					  clk_disable_unprepare() in dai
 					  shutdown().
+					  see Clock Example.
 
 Example 1 - single DAI link:
 
@@ -199,3 +200,34 @@ sound {
 		clocks = ...
 	};
 };
+
+
+Clock Example 1 - clock settings on each subnode
+
+sound {
+	...
+	simple-audio-card,cpu {
+		sound-dai = <&xxx>;
+		clocks = <&cpu_clock>;
+	};
+	simple-audio-card,codec {
+		sound-dai = <&xxx>;
+		clocks = <&codec_clock>;
+	};
+};
+
+Clock Example 2 - clock settings by clocks
+
+sound {
+	...
+	clocks = <&cpu_clock>, <&codec_clock>;
+	clock-names = "cpu", "codec";
+	clock-ranges;
+	...
+	simple-audio-card,cpu {
+		sound-dai = <&xxx>;
+	};
+	simple-audio-card,codec {
+		sound-dai = <&xxx>;
+	};
+};
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 4924575..c3031a5 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -104,15 +104,52 @@ int asoc_simple_card_parse_clk(struct device *dev,
 			       struct asoc_simple_dai *simple_dai)
 {
 	struct clk *clk;
+	const char *con_id = NULL;
+	const char *port_name[] = {
+		"cpu", "codec"
+	};
 	u32 val;
 
 	/*
+	 * We can use this style if "con_id" is not NULL
+	 *
+	 * sound {
+	 *	...
+	 *	clocks = <&xxx>, <&xxx>;
+	 *	clock-names = "cpu", "codec";
+	 *	clock-ranges;
+	 *
+	 *	simple-audio-card,cpu {
+	 *		sound-dai = <&xxx>;
+	 *	};
+	 *	simple-audio-card,codec {
+	 *		sound-dai = <&xxx>;
+	 *	};
+	 * };
+	 */
+	if (of_find_property(dev->of_node, "clock-names", NULL)) {
+		int i;
+		int port_len, node_len;
+
+		for (i = 0; i < ARRAY_SIZE(port_name); i++) {
+			node_len = strlen(node->name);
+			port_len = strlen(port_name[i]);
+
+			if (0 == strncmp(node->name + node_len - port_len,
+					 port_name[i], port_len)) {
+				con_id = port_name[i];
+				break;
+			}
+		}
+	}
+
+	/*
 	 * Parse dai->sysclk come from "clocks = <&xxx>"
 	 * (if system has common clock)
 	 *  or "system-clock-frequency = <xxx>"
 	 *  or device's module clock.
 	 */
-	clk = devm_get_clk_from_child(dev, node, NULL);
+	clk = devm_get_clk_from_child(dev, node, con_id);
 	if (!IS_ERR(clk)) {
 		simple_dai->sysclk = clk_get_rate(clk);
 	} else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/3] ASoC: simple-card: use devm_get_clk_from_child()
From: Kuninori Morimoto @ 2016-12-05  5:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874m2jvtmw.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Current simple-card-utils is getting clk by of_clk_get(), but didn't call
clk_free(). Now we can use devm_get_clk_from_child() for this purpose.
Let's use it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/simple_card_utils.h     | 11 ++++++-----
 sound/soc/generic/simple-card-utils.c |  8 ++++----
 sound/soc/generic/simple-card.c       |  4 ++--
 sound/soc/generic/simple-scu-card.c   |  4 ++--
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index 64e90ca..af58d23 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -34,11 +34,12 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
 int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
 				     char *prefix);
 
-#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai)		\
-	asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai)
-#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai)		\
-	asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai)
-int asoc_simple_card_parse_clk(struct device_node *node,
+#define asoc_simple_card_parse_clk_cpu(dev, node, dai_link, simple_dai)		\
+	asoc_simple_card_parse_clk(dev, node, dai_link->cpu_of_node, simple_dai)
+#define asoc_simple_card_parse_clk_codec(dev, node, dai_link, simple_dai)	\
+	asoc_simple_card_parse_clk(dev, node, dai_link->codec_of_node, simple_dai)
+int asoc_simple_card_parse_clk(struct device *dev,
+			       struct device_node *node,
 			       struct device_node *dai_of_node,
 			       struct asoc_simple_dai *simple_dai);
 
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index cf02625..4924575 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -98,7 +98,8 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
 }
 EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
 
-int asoc_simple_card_parse_clk(struct device_node *node,
+int asoc_simple_card_parse_clk(struct device *dev,
+			       struct device_node *node,
 			       struct device_node *dai_of_node,
 			       struct asoc_simple_dai *simple_dai)
 {
@@ -111,14 +112,13 @@ int asoc_simple_card_parse_clk(struct device_node *node,
 	 *  or "system-clock-frequency = <xxx>"
 	 *  or device's module clock.
 	 */
-	clk = of_clk_get(node, 0);
+	clk = devm_get_clk_from_child(dev, node, NULL);
 	if (!IS_ERR(clk)) {
 		simple_dai->sysclk = clk_get_rate(clk);
-		simple_dai->clk = clk;
 	} else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
 		simple_dai->sysclk = val;
 	} else {
-		clk = of_clk_get(dai_of_node, 0);
+		clk = devm_get_clk_from_child(dev, dai_of_node, NULL);
 		if (!IS_ERR(clk))
 			simple_dai->sysclk = clk_get_rate(clk);
 	}
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index a385ff6..85b4f18 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -278,11 +278,11 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
 	if (ret < 0)
 		goto dai_link_of_err;
 
-	ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai);
+	ret = asoc_simple_card_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);
 	if (ret < 0)
 		goto dai_link_of_err;
 
-	ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai);
+	ret = asoc_simple_card_parse_clk_codec(dev, codec, dai_link, codec_dai);
 	if (ret < 0)
 		goto dai_link_of_err;
 
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index bb86ee0..308ff4c 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -128,7 +128,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
 		if (ret)
 			return ret;
 
-		ret = asoc_simple_card_parse_clk_cpu(np, dai_link, dai_props);
+		ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, dai_props);
 		if (ret < 0)
 			return ret;
 
@@ -153,7 +153,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
 		if (ret < 0)
 			return ret;
 
-		ret = asoc_simple_card_parse_clk_codec(np, dai_link, dai_props);
+		ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, dai_props);
 		if (ret < 0)
 			return ret;
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/3] clkdev: add devm_get_clk_from_child()
From: Kuninori Morimoto @ 2016-12-05  5:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <874m2jvtmw.wl%kuninori.morimoto.gx@renesas.com>


From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

Some driver is using this type of DT bindings for clock (more detail,
see ${LINUX}/Documentation/devicetree/bindings/sound/simple-card.txt).

	sound_soc {
		...
		cpu {
			clocks = <&xxx>;
			...
		};
		codec {
			clocks = <&xxx>;
			...
		};
	};

Current driver in this case uses of_clk_get() for each node, but there
is no devm_of_clk_get() today.
OTOH, the problem of having devm_of_clk_get() is that it encourages the
use of of_clk_get() when clk_get() is more desirable.

Thus, this patch adds new devm_get_clk_from_chile() which explicitly
reads as get a clock from a child node of this device.
By this function, we can also use this type of DT bindings

	sound_soc {
		clocks = <&xxx>, <&xxx>;
		clock-names = "cpu", "codec";
		...
		cpu {
			...
		};
		codec {
			...
		};
	};

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/clk/clk-devres.c | 21 +++++++++++++++++++++
 include/linux/clk.h      | 29 +++++++++++++++++++++++++----
 2 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
index 8f57154..3a218c3 100644
--- a/drivers/clk/clk-devres.c
+++ b/drivers/clk/clk-devres.c
@@ -53,3 +53,24 @@ void devm_clk_put(struct device *dev, struct clk *clk)
 	WARN_ON(ret);
 }
 EXPORT_SYMBOL(devm_clk_put);
+
+struct clk *devm_get_clk_from_child(struct device *dev,
+				    struct device_node *np, const char *con_id)
+{
+	struct clk **ptr, *clk;
+
+	ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	clk = of_clk_get_by_name(np, con_id);
+	if (!IS_ERR(clk)) {
+		*ptr = clk;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return clk;
+}
+EXPORT_SYMBOL(devm_get_clk_from_child);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 123c027..e9d36b3 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -17,8 +17,9 @@
 #include <linux/notifier.h>
 
 struct device;
-
 struct clk;
+struct device_node;
+struct of_phandle_args;
 
 /**
  * DOC: clk notifier callback types
@@ -249,6 +250,23 @@ static inline void clk_unprepare(struct clk *clk)
 struct clk *devm_clk_get(struct device *dev, const char *id);
 
 /**
+ * devm_get_clk_from_child - lookup and obtain a managed reference to a
+ *			     clock producer from child node.
+ * @dev: device for clock "consumer"
+ * @np: pointer to clock consumer node
+ * @con_id: clock consumer ID
+ *
+ * This function parses the clocks, and uses them to look up the
+ * struct clk from the registered list of clock providers by using
+ * @np and @con_id
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_get_clk_from_child(struct device *dev,
+				    struct device_node *np, const char *con_id);
+
+/**
  * clk_enable - inform the system when the clock source should be running.
  * @clk: clock source
  *
@@ -432,6 +450,12 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id)
 	return NULL;
 }
 
+static inline struct clk *devm_get_clk_from_child(struct device *dev,
+				struct device_node *np, const char *con_id)
+{
+	return NULL;
+}
+
 static inline void clk_put(struct clk *clk) {}
 
 static inline void devm_clk_put(struct device *dev, struct clk *clk) {}
@@ -501,9 +525,6 @@ static inline void clk_disable_unprepare(struct clk *clk)
 	clk_unprepare(clk);
 }
 
-struct device_node;
-struct of_phandle_args;
-
 #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
 struct clk *of_clk_get(struct device_node *np, int index);
 struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/3] clkdev: add devm_get_clk_from_child()
From: Kuninori Morimoto @ 2016-12-05  5:22 UTC (permalink / raw)
  To: linux-arm-kernel


Hi Stephen

This is v5 of "clkdev: add devm_of_clk_get()", but new series.
I hope my understanding was correct with your idea.

Kuninori Morimoto (3):
  1) clkdev: add devm_get_clk_from_child()
  2) ASoC: simple-card: use devm_get_clk_from_child()
  3) ASoC: simple-card-utils: enable clocks/clock-names/clock-ranges

 .../devicetree/bindings/sound/simple-card.txt      | 32 +++++++++++++++
 drivers/clk/clk-devres.c                           | 21 ++++++++++
 include/linux/clk.h                                | 29 ++++++++++++--
 include/sound/simple_card_utils.h                  | 11 +++---
 sound/soc/generic/simple-card-utils.c              | 45 ++++++++++++++++++++--
 sound/soc/generic/simple-card.c                    |  4 +-
 sound/soc/generic/simple-scu-card.c                |  4 +-
 7 files changed, 129 insertions(+), 17 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [PATCH 2/2] ARM: omap: timers: reduce rating of gp_timer clocksource
From: Keerthy @ 2016-12-05  4:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202183139.GF4705@atomide.com>



On Saturday 03 December 2016 12:01 AM, Tony Lindgren wrote:
> * Grygorii Strashko <grygorii.strashko@ti.com> [161202 10:02]:
>>
>>
>> On 12/02/2016 10:47 AM, Tony Lindgren wrote:
>>> * Grygorii Strashko <grygorii.strashko@ti.com> [161129 08:43]:
>>>>
>>>>
>>>> On 11/24/2016 12:19 AM, Keerthy wrote:
>>>>> From: Grygorii Strashko <grygorii.strashko@ti.com>
>>>>>
>>>>> Now ARM Global timer (rating 300) will not be selected as clocksource,
>>>>> because it's initialized after OMAP GP Timer (rating 300) and
>>>>> Timekeeping core will not allow to replace clocksource with new one if
>>>>> both of them have the same rating.
>>>>>
>>>>> Reduce rating of OMAP GP Timer (300->290) when it's used as
>>>>> clocksource device - this will allow to select ARM Global timer (300)
>>>>> as clocksource when enabled.
>>>>>
>>>>> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
>>>>> Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
>>>>> Signed-off-by: Keerthy <j-keerthy@ti.com>
>>>>
>>>> Unfortunately, this patch has dependency [1] and can't be used alone as
>>>> it will cause ARM Global timer to be selected as clocksource
>>>> always on am437x and this will kill cpuidle, because ARM Global timer
>>>> is not in always_on domain.
>>>>
>>>> The intention of enabling ARM Global timer is only for non-pm aware use
>>>> cases for RT-kernel latency improvement - where deep cpuidle states are not
>>>> enabled.
>>>
>>> Yeah we need to fix up things to be able to change the clocksource
>>> in addition to clockevent. However, currently only cpuidle_coupled
>>> knows when the whole system is idle, so quite a bit of work is
>>> needed to do that in a sane way.
>>
>> Also sched_clock and timer_delay ;)
>
> Yeah sched_clock would need something to save and restore it..
> Not nice :)
>
>>> What about the first patch in this series?
>>>
>>
>> Fist one is ok. It was originally posted long time ago.
>
> OK so can you please resend that one more time with proper
> Fixes tag on it?

Tony,

I have posted a v2 with the proper Fixes tag.

- Keerthy
>
> Regards,
>
> Tony
>

^ permalink raw reply

* [PATCH v2] ARM: omap2: am437x: rollback to use omap3_gptimer_timer_init()
From: Keerthy @ 2016-12-05  3:57 UTC (permalink / raw)
  To: linux-arm-kernel

From: Grygorii Strashko <grygorii.strashko@ti.com>

The commit 55ee7017ee31 ("arm: omap2: board-generic: use
omap4_local_timer_init for AM437x") unintentionally changes the
clocksource devices for AM437x from OMAP GP Timer to SyncTimer32K.

Unfortunately, the SyncTimer32K is starving from frequency deviation
as mentioned in commit 5b5c01359152 ("ARM: OMAP2+: AM43x: Use gptimer
as clocksource") and, as reported by Franklin [1], even its monotonic
nature is under question (most probably there is a HW issue, but it's
still under investigation).

Taking into account above facts It's reasonable to rollback to the use
of omap3_gptimer_timer_init().

[1] http://www.spinics.net/lists/linux-omap/msg127425.html

Fixes: 55ee7017ee31 ("arm: omap2: board-generic: use
omap4_local_timer_init for AM437x")
Reported-by: Cooper Jr., Franklin <fcooper@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Keerthy <j-keerthy@ti.com>
---

Changes in v2:

  * Added a proper Fixes tag with the commit ID.

 arch/arm/mach-omap2/board-generic.c | 2 +-
 arch/arm/mach-omap2/timer.c         | 9 +++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 36d9943..dc9e34e 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -304,7 +304,7 @@ static void __init rx51_reserve(void)
 	.init_late	= am43xx_init_late,
 	.init_irq	= omap_gic_of_init,
 	.init_machine	= omap_generic_init,
-	.init_time	= omap4_local_timer_init,
+	.init_time	= omap3_gptimer_timer_init,
 	.dt_compat	= am43_boards_compat,
 	.restart	= omap44xx_restart,
 MACHINE_END
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 5e2e221..b2f2448 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -510,18 +510,19 @@ void __init omap3_secure_sync32k_timer_init(void)
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
+	defined(CONFIG_SOC_AM43XX)
 void __init omap3_gptimer_timer_init(void)
 {
 	__omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
 			1, "timer_sys_ck", "ti,timer-alwon", true);
-
-	clocksource_probe();
+	if (of_have_populated_dt())
+		clocksource_probe();
 }
 #endif
 
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) ||		\
-	defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
+	defined(CONFIG_SOC_DRA7XX)
 static void __init omap4_sync32k_timer_init(void)
 {
 	__omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
-- 
1.9.1

^ permalink raw reply related

* [PATCH v4] ARM: davinci: da8xx: Fix sleeping function called from invalid context
From: David Lechner @ 2016-12-05  3:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480690380-13216-1-git-send-email-abailon@baylibre.com>

On 12/02/2016 08:53 AM, Alexandre Bailon wrote:
> Everytime the usb20 phy is enabled, there is a
> "sleeping function called from invalid context" BUG.
>
> clk_enable() from arch/arm/mach-davinci/clock.c uses spin_lock_irqsave()
> before to invoke the callback usb20_phy_clk_enable().
> usb20_phy_clk_enable() uses clk_get() and clk_enable_prepapre()
> which may sleep.
> Move clk_get() to da8xx_register_usb20_phy_clk() and
> replace clk_prepare_enable() by clk_enable().
>
> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
> ---
>  arch/arm/mach-davinci/usb-da8xx.c | 28 +++++++++++++++-------------
>  1 file changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
> index b010e5f..704f506 100644
> --- a/arch/arm/mach-davinci/usb-da8xx.c
> +++ b/arch/arm/mach-davinci/usb-da8xx.c
> @@ -22,6 +22,8 @@
>  #define DA8XX_USB0_BASE		0x01e00000
>  #define DA8XX_USB1_BASE		0x01e25000
>
> +static struct clk *usb20_clk;
> +
>  static struct platform_device da8xx_usb_phy = {
>  	.name		= "da8xx-usb-phy",
>  	.id		= -1,
> @@ -158,21 +160,14 @@ int __init da8xx_register_usb_refclkin(int rate)
>
>  static void usb20_phy_clk_enable(struct clk *clk)
>  {
> -	struct clk *usb20_clk;
>  	int err;
>  	u32 val;
>  	u32 timeout = 500000; /* 500 msec */
>
>  	val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
>
> -	usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
> -	if (IS_ERR(usb20_clk)) {
> -		pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
> -		return;
> -	}
> -
>  	/* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
> -	err = clk_prepare_enable(usb20_clk);
> +	err = clk_enable(usb20_clk);
>  	if (err) {
>  		pr_err("failed to enable usb20 clk: %d\n", err);
>  		clk_put(usb20_clk);

Need to remove clk_put() here.

> @@ -197,8 +192,7 @@ static void usb20_phy_clk_enable(struct clk *clk)
>
>  	pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
>  done:
> -	clk_disable_unprepare(usb20_clk);
> -	clk_put(usb20_clk);
> +	clk_disable(usb20_clk);
>  }
>
>  static void usb20_phy_clk_disable(struct clk *clk)
> @@ -285,11 +279,19 @@ static struct clk_lookup usb20_phy_clk_lookup =
>  int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
>  {
>  	struct clk *parent;
> -	int ret = 0;
> +	int ret;
> +
> +	usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
> +	ret = PTR_ERR_OR_ZERO(usb20_clk);
> +	if (ret)
> +		return ret;
>
>  	parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
> -	if (IS_ERR(parent))
> -		return PTR_ERR(parent);
> +	ret = PTR_ERR_OR_ZERO(parent);
> +	if (ret) {
> +		clk_put(usb20_clk);
> +		return ret;
> +	}
>
>  	usb20_phy_clk.parent = parent;
>  	ret = clk_register(&usb20_phy_clk);
>


I have just tried this patch with a bunch of kernel hacking options 
enabled. I am getting the message show at the end of this email. We 
still have the problem of nested spin locks due to nested calls to 
clk_enable(). So, really, we need to use __clk_enable() and 
__clk_disable() from arch/arm/mach-davinci/clock.c in 
usb20_phy_clk_enable() above.

Applying the following patch on top of your patch fixed the recursive 
lock message.

---

diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index df42c93..4fba579 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -31,7 +31,7 @@ static LIST_HEAD(clocks);
  static DEFINE_MUTEX(clocks_mutex);
  static DEFINE_SPINLOCK(clockfw_lock);

-static void __clk_enable(struct clk *clk)
+void __clk_enable(struct clk *clk)
  {
         if (clk->parent)
                 __clk_enable(clk->parent);
@@ -44,7 +44,7 @@ static void __clk_enable(struct clk *clk)
         }
  }

-static void __clk_disable(struct clk *clk)
+void __clk_disable(struct clk *clk)
  {
         if (WARN_ON(clk->usecount == 0))
                 return;
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index e2a5437..8493242 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -136,6 +136,9 @@ int davinci_clk_reset(struct clk *clk, bool reset);
  extern struct platform_device davinci_wdt_device;
  extern void davinci_watchdog_reset(struct platform_device *);

+void __clk_enable(struct clk *clk);
+void __clk_disable(struct clk *clk);
+
  #endif

  #endif
diff --git a/arch/arm/mach-davinci/usb-da8xx.c 
b/arch/arm/mach-davinci/usb-da8xx
.c
index 896d014..80ba0df 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -160,19 +160,13 @@ int __init da8xx_register_usb_refclkin(int rate)

  static void usb20_phy_clk_enable(struct clk *clk)
  {
-       int err;
         u32 val;
         u32 timeout = 500000; /* 500 msec */

         val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));

         /* The USB 2.O PLL requires that the USB 2.O PSC is enabled as 
well. */
-       err = clk_enable(usb20_clk);
-       if (err) {
-               pr_err("failed to enable usb20 clk: %d\n", err);
-               clk_put(usb20_clk);
-               return;
-       }
+       __clk_enable(usb20_clk);

         /*
          * Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The 
USB 1.1
@@ -192,7 +186,7 @@ static void usb20_phy_clk_enable(struct clk *clk)

         pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
  done:
-       clk_disable(usb20_clk);
+       __clk_disable(usb20_clk);
  }

  static void usb20_phy_clk_disable(struct clk *clk)



---


=============================================
[ INFO: possible recursive locking detected ]
4.9.0-rc8-dlech-ev3-lms2012+ #22 Not tainted
---------------------------------------------
swapper/1 is trying to acquire lock:
  (
clockfw_lock
){......}
, at:
[<c0014884>] clk_enable+0x24/0x50
k:
  (
clockfw_lock
){......}
, at:
[<c0014884>] clk_enable+0x24/0x50
ebug this:
  Possible unsafe locking scenario:
        CPU0
        ----
   lock(
clockfw_lock
);
   lock(
clockfw_lock
);
  May be due to missing lock nesting notation
4 locks held by swapper/1:
  #0:
  (
&dev->mutex
){......}
, at:
[<c02bd60c>] __driver_attach+0x68/0xb4
  #1:
  (
&dev->mutex
){......}
, at:
[<c02bd61c>] __driver_attach+0x78/0xb4
  #2:
  (
&phy->mutex
){+.+...}
, at:
[<c025ee18>] phy_power_on+0x5c/0xe4
  #3:
  (
clockfw_lock
){......}
, at:
[<c0014884>] clk_enable+0x24/0x50
CPU: 0 PID: 1 Comm: swapper Not tainted 4.9.0-rc8-dlech-ev3-lms2012+ #22
Hardware name: Generic DA850/OMAP-L138/AM18x
Backtrace:
[<c000d824>] (dump_backtrace) from [<c000dac4>] (show_stack+0x18/0x1c)
  r7:c0e998a4 r6:c0820750 r5:c0820750 r4:c3838000
[<c000daac>] (show_stack) from [<c02393dc>] (dump_stack+0x20/0x28)
[<c02393bc>] (dump_stack) from [<c004bd7c>] (__lock_acquire+0x10f4/0x167c)
[<c004ac88>] (__lock_acquire) from [<c004c6ac>] (lock_acquire+0x78/0x98)
  r10:00000000 r9:c06a5ed4 r8:00000000 r7:00000001 r6:60000093 r5:00000000
  r4:ffffe000
[<c004c634>] (lock_acquire) from [<c04d8fac>] 
(_raw_spin_lock_irqsave+0x60/0x74)
  r7:0000003b r6:c0014884 r5:80000093 r4:c06b09a0
[<c04d8f4c>] (_raw_spin_lock_irqsave) from [<c0014884>] 
(clk_enable+0x24/0x50)
  r6:c06f69f4 r5:0001ef02 r4:c06b3398
[<c0014860>] (clk_enable) from [<c0015c74>] (usb20_phy_clk_enable+0x24/0xb8)
  r5:0001ef02 r4:c06f69f0
[<c0015c50>] (usb20_phy_clk_enable) from [<c0014858>] 
(__clk_enable+0x74/0x7c)
  r9:c06a5ed4 r8:00000000 r7:0000003b r6:c3a6ca00 r5:80000013 r4:c06b7ee8
[<c00147e4>] (__clk_enable) from [<c0014808>] (__clk_enable+0x24/0x7c)
  r4:c06b8648
[<c00147e4>] (__clk_enable) from [<c0014890>] (clk_enable+0x30/0x50)
  r4:c06b8648
[<c0014860>] (clk_enable) from [<c025f43c>] 
(da8xx_usb11_phy_power_on+0x30/0x80)
  r5:c3a54050 r4:c06b8648
[<c025f40c>] (da8xx_usb11_phy_power_on) from [<c025ee3c>] 
(phy_power_on+0x80/0xe4)
  r5:c3a6c800 r4:fffffdf4
[<c025edbc>] (phy_power_on) from [<c032243c>] (ohci_da8xx_enable+0x4c/0x80)
  r7:0000003b r6:c3af6000 r5:c3af6000 r4:00000000
[<c03223f0>] (ohci_da8xx_enable) from [<c03224f0>] 
(ohci_da8xx_reset+0x1c/0xd8)
  r5:00000000 r4:c3af6000
[<c03224d4>] (ohci_da8xx_reset) from [<c0309118>] (usb_add_hcd+0x314/0x834)
  r7:0000003b r6:ffffffed r5:00000000 r4:c3af6000
[<c0308e04>] (usb_add_hcd) from [<c032200c>] (ohci_da8xx_probe+0x14c/0x21c)
  r9:c06a5ed4 r8:00000000 r7:c38bd010 r6:c38bd000 r5:c3af6000 r4:c38af900
[<c0321ec0>] (ohci_da8xx_probe) from [<c02bec44>] 
(platform_drv_probe+0x40/0x8c)
  r7:c06e610c r6:c06e610c r5:c38bd010 r4:c0321ec0
[<c02bec04>] (platform_drv_probe) from [<c02bd438>] 
(driver_probe_device+0x138/0x2a4)
  r7:c06e610c r6:c0e9db10 r5:00000000 r4:c38bd010
[<c02bd300>] (driver_probe_device) from [<c02bd634>] 
(__driver_attach+0x90/0xb4)
  r9:c06a5ed4 r8:c06f66e0 r7:c06e1250 r6:c06e610c r5:c38bd044 r4:c38bd010
[<c02bd5a4>] (__driver_attach) from [<c02bba5c>] 
(bus_for_each_dev+0x74/0x98)
  r7:c06e1250 r6:c02bd5a4 r5:c06e610c r4:00000000
[<c02bb9e8>] (bus_for_each_dev) from [<c02bcf2c>] (driver_attach+0x20/0x28)
  r6:c39a2300 r5:00000000 r4:c06e610c
[<c02bcf0c>] (driver_attach) from [<c02bca80>] (bus_add_driver+0xd4/0x1f0)
[<c02bc9ac>] (bus_add_driver) from [<c02bdcec>] (driver_register+0xa4/0xe8)
  r7:c0698850 r6:00000000 r5:00000000 r4:c06e610c
[<c02bdc48>] (driver_register) from [<c02bebac>] 
(__platform_driver_register+0x38/0x4c)
  r5:00000000 r4:c06acce4
[<c02beb74>] (__platform_driver_register) from [<c068da20>] 
(ohci_da8xx_init+0x64/0x90)
[<c068d9bc>] (ohci_da8xx_init) from [<c00096c0>] 
(do_one_initcall+0xb0/0x168)
  r5:c068d9bc r4:ffffe000
[<c0009610>] (do_one_initcall) from [<c0676e14>] 
(kernel_init_freeable+0x110/0x1cc)
  r9:c06a5ed4 r8:c06f66e0 r7:c0698850 r6:000000c1 r5:c06f66e0 r4:00000007
[<c0676d04>] (kernel_init_freeable) from [<c04d37e4>] 
(kernel_init+0x10/0xf8)
  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c04d37d4 r4:00000000
[<c04d37d4>] (kernel_init) from [<c000a2ac>] (ret_from_fork+0x14/0x28)
  r5:c04d37d4 r4:00000000
BUG: spinlock lockup suspected on CPU#0, swapper/1
  lock: clockfw_lock+0x0/0x20, .magic: dead4ead, .owner: swapper/1, 
.owner_cpu: 0
CPU: 0 PID: 1 Comm: swapper Not tainted 4.9.0-rc8-dlech-ev3-lms2012+ #22
Hardware name: Generic DA850/OMAP-L138/AM18x
Backtrace:
[<c000d824>] (dump_backtrace) from [<c000dac4>] (show_stack+0x18/0x1c)
  r7:00000000 r6:04605000 r5:c06b09a0 r4:c3838000
[<c000daac>] (show_stack) from [<c02393dc>] (dump_stack+0x20/0x28)
[<c02393bc>] (dump_stack) from [<c004f140>] (spin_dump+0x80/0x94)
[<c004f0c0>] (spin_dump) from [<c004f2c4>] (do_raw_spin_lock+0xdc/0x11c)
  r5:00000000 r4:c06b09a0
[<c004f1e8>] (do_raw_spin_lock) from [<c04d8fb4>] 
(_raw_spin_lock_irqsave+0x68/0x74)
  r10:00000000 r9:c06a5ed4 r8:00000000 r7:0000003b r6:c0014884 r5:80000093
  r4:c06b09a0 r3:c3838000
[<c04d8f4c>] (_raw_spin_lock_irqsave) from [<c0014884>] 
(clk_enable+0x24/0x50)
  r6:c06f69f4 r5:0001ef02 r4:c06b3398
[<c0014860>] (clk_enable) from [<c0015c74>] (usb20_phy_clk_enable+0x24/0xb8)
  r5:0001ef02 r4:c06f69f0
[<c0015c50>] (usb20_phy_clk_enable) from [<c0014858>] 
(__clk_enable+0x74/0x7c)
  r9:c06a5ed4 r8:00000000 r7:0000003b r6:c3a6ca00 r5:80000013 r4:c06b7ee8
[<c00147e4>] (__clk_enable) from [<c0014808>] (__clk_enable+0x24/0x7c)
  r4:c06b8648
[<c00147e4>] (__clk_enable) from [<c0014890>] (clk_enable+0x30/0x50)
  r4:c06b8648
[<c0014860>] (clk_enable) from [<c025f43c>] 
(da8xx_usb11_phy_power_on+0x30/0x80)
  r5:c3a54050 r4:c06b8648
[<c025f40c>] (da8xx_usb11_phy_power_on) from [<c025ee3c>] 
(phy_power_on+0x80/0xe4)
  r5:c3a6c800 r4:fffffdf4
[<c025edbc>] (phy_power_on) from [<c032243c>] (ohci_da8xx_enable+0x4c/0x80)
  r7:0000003b r6:c3af6000 r5:c3af6000 r4:00000000
[<c03223f0>] (ohci_da8xx_enable) from [<c03224f0>] 
(ohci_da8xx_reset+0x1c/0xd8)
  r5:00000000 r4:c3af6000
[<c03224d4>] (ohci_da8xx_reset) from [<c0309118>] (usb_add_hcd+0x314/0x834)
  r7:0000003b r6:ffffffed r5:00000000 r4:c3af6000
[<c0308e04>] (usb_add_hcd) from [<c032200c>] (ohci_da8xx_probe+0x14c/0x21c)
  r9:c06a5ed4 r8:00000000 r7:c38bd010 r6:c38bd000 r5:c3af6000 r4:c38af900
[<c0321ec0>] (ohci_da8xx_probe) from [<c02bec44>] 
(platform_drv_probe+0x40/0x8c)
  r7:c06e610c r6:c06e610c r5:c38bd010 r4:c0321ec0
[<c02bec04>] (platform_drv_probe) from [<c02bd438>] 
(driver_probe_device+0x138/0x2a4)
  r7:c06e610c r6:c0e9db10 r5:00000000 r4:c38bd010
[<c02bd300>] (driver_probe_device) from [<c02bd634>] 
(__driver_attach+0x90/0xb4)
  r9:c06a5ed4 r8:c06f66e0 r7:c06e1250 r6:c06e610c r5:c38bd044 r4:c38bd010
[<c02bd5a4>] (__driver_attach) from [<c02bba5c>] 
(bus_for_each_dev+0x74/0x98)
  r7:c06e1250 r6:c02bd5a4 r5:c06e610c r4:00000000
[<c02bb9e8>] (bus_for_each_dev) from [<c02bcf2c>] (driver_attach+0x20/0x28)
  r6:c39a2300 r5:00000000 r4:c06e610c
[<c02bcf0c>] (driver_attach) from [<c02bca80>] (bus_add_driver+0xd4/0x1f0)
[<c02bc9ac>] (bus_add_driver) from [<c02bdcec>] (driver_register+0xa4/0xe8)
  r7:c0698850 r6:00000000 r5:00000000 r4:c06e610c
[<c02bdc48>] (driver_register) from [<c02bebac>] 
(__platform_driver_register+0x38/0x4c)
  r5:00000000 r4:c06acce4
[<c02beb74>] (__platform_driver_register) from [<c068da20>] 
(ohci_da8xx_init+0x64/0x90)
[<c068d9bc>] (ohci_da8xx_init) from [<c00096c0>] 
(do_one_initcall+0xb0/0x168)
  r5:c068d9bc r4:ffffe000
[<c0009610>] (do_one_initcall) from [<c0676e14>] 
(kernel_init_freeable+0x110/0x1cc)
  r9:c06a5ed4 r8:c06f66e0 r7:c0698850 r6:000000c1 r5:c06f66e0 r4:00000007
[<c0676d04>] (kernel_init_freeable) from [<c04d37e4>] 
(kernel_init+0x10/0xf8)
  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c04d37d4 r4:00000000
[<c04d37d4>] (kernel_init) from [<c000a2ac>] (ret_from_fork+0x14/0x28)
  r5:c04d37d4 r4:00000000

^ permalink raw reply related

* [PATCH v2 3/3] ARM: da850: fix da850_set_pll0rate()
From: Viresh Kumar @ 2016-12-05  3:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480693134-31324-4-git-send-email-bgolaszewski@baylibre.com>

Good to see you again Bartosz :)

On 02-12-16, 16:38, Bartosz Golaszewski wrote:
> This function is broken - its second argument is an index to the freq
> table, not the requested clock rate in Hz. It leads to an oops when
> called from clk_set_rate() since this argument isn't bounds checked
> either.
> 
> Fix it by iterating over the array of supported frequencies and
> selecting a one that matches or returning -EINVAL for unsupported
> rates.
> 
> Also: update the davinci cpufreq driver. It's the only user of this
> clock and currently it passes the cpufreq table index to
> clk_set_rate(), which is confusing. Make it pass the requested clock
> rate in Hz.
> 
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
>  arch/arm/mach-davinci/da850.c     | 22 ++++++++++++++++++----
>  drivers/cpufreq/davinci-cpufreq.c |  2 +-
>  2 files changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
> index a55101c..92e3303 100644
> --- a/arch/arm/mach-davinci/da850.c
> +++ b/arch/arm/mach-davinci/da850.c
> @@ -1179,14 +1179,28 @@ static int da850_set_armrate(struct clk *clk, unsigned long index)
>  	return clk_set_rate(pllclk, index);
>  }
>  
> -static int da850_set_pll0rate(struct clk *clk, unsigned long index)
> +static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
>  {
> -	unsigned int prediv, mult, postdiv;
> -	struct da850_opp *opp;
>  	struct pll_data *pll = clk->pll_data;
> +	struct cpufreq_frequency_table *freq;
> +	unsigned int prediv, mult, postdiv;
> +	struct da850_opp *opp = NULL;
>  	int ret;
>  
> -	opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data;
> +	for (freq = da850_freq_table;
> +	     freq->frequency != CPUFREQ_TABLE_END; freq++) {
> +		/* requested_rate is in Hz, freq->frequency is in KHz */
> +		unsigned long freq_rate = freq->frequency * 1000;
> +
> +		if (freq_rate == rate) {
> +			opp = (struct da850_opp *)freq->driver_data;
> +			break;
> +		}
> +	}
> +
> +	if (opp == NULL)
> +		return -EINVAL;
> +
>  	prediv = opp->prediv;
>  	mult = opp->mult;
>  	postdiv = opp->postdiv;
> diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c
> index b95a872..d54a27c 100644
> --- a/drivers/cpufreq/davinci-cpufreq.c
> +++ b/drivers/cpufreq/davinci-cpufreq.c
> @@ -55,7 +55,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
>  			return ret;
>  	}
>  
> -	ret = clk_set_rate(armclk, idx);
> +	ret = clk_set_rate(armclk, new_freq * 1000);
>  	if (ret)
>  		return ret;

I haven't checked the internal of davinci or the way rate is changed now, but
from cpufreq's perspective, fee free to add my:

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply

* [PATCH 2/2] soc: zte: pm_domains: Add support for zx296718 driver
From: Jun Nie @ 2016-12-05  3:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480774291-6211-2-git-send-email-baoyou.xie@linaro.org>

2016-12-03 22:11 GMT+08:00 Baoyou Xie <baoyou.xie@linaro.org>:
> This patch introduces the power domain driver of zx296718
> which belongs to zte's 2967 family.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
>  drivers/soc/zte/Makefile              |   3 +
>  drivers/soc/zte/zx296718_pm_domains.c | 162 ++++++++++++++++++++++++++++++++++
>  2 files changed, 165 insertions(+)
>  create mode 100644 drivers/soc/zte/zx296718_pm_domains.c
>
> diff --git a/drivers/soc/zte/Makefile b/drivers/soc/zte/Makefile
> index 97ac8ea..a6e7bfe 100644
> --- a/drivers/soc/zte/Makefile
> +++ b/drivers/soc/zte/Makefile
> @@ -2,3 +2,6 @@
>  # zx SOC drivers
>  #
>  obj-$(CONFIG_ZX_PM_DOMAINS) += pm_domains.o
> +ifeq ($(CONFIG_ZX_PM_DOMAINS), y)
> +       obj-y += zx296718_pm_domains.o
> +endif

Follow unified style for Makefile:
obj-$(CONFIG_ZX_PM_DOMAINS) += zx296718_pm_domains.o

> diff --git a/drivers/soc/zte/zx296718_pm_domains.c b/drivers/soc/zte/zx296718_pm_domains.c
> new file mode 100644
> index 0000000..fc16dfd
> --- /dev/null
> +++ b/drivers/soc/zte/zx296718_pm_domains.c
> @@ -0,0 +1,162 @@
> +/*
> + * Copyright (C) 2015 ZTE Ltd.
> + *
> + * Author: Baoyou Xie <baoyou.xie@linaro.org>
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +#include "pm_domains.h"
> +
> +enum {
> +       PCU_DM_VOU = 0,
> +       PCU_DM_SAPPU,
> +       PCU_DM_VDE,
> +       PCU_DM_VCE,
> +       PCU_DM_HDE,
> +       PCU_DM_VIU,
> +       PCU_DM_USB20,
> +       PCU_DM_USB21,
> +       PCU_DM_USB30,
> +       PCU_DM_HSIC,
> +       PCU_DM_GMAC,
> +       PCU_DM_TS,
> +};
> +
> +static struct zx_pm_domain vou_domain = {
> +       .dm = {
> +               .name           = "vou_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_VOU,
> +};
> +static struct zx_pm_domain sappu_domain = {
> +       .dm = {
> +               .name           = "sappu_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_SAPPU,
> +};
> +static struct zx_pm_domain vde_domain = {
> +       .dm = {
> +               .name           = "vde_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_VDE,
> +};
> +static struct zx_pm_domain vce_domain = {
> +       .dm = {
> +               .name           = "vce_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_VCE,
> +};
> +static struct zx_pm_domain hde_domain = {
> +       .dm = {
> +               .name           = "hde_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_HDE,
> +};
> +
> +static struct zx_pm_domain viu_domain = {
> +       .dm = {
> +               .name           = "viu_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_VIU,
> +};
> +static struct zx_pm_domain usb20_domain = {
> +       .dm = {
> +               .name           = "usb20_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_USB20,
> +};
> +static struct zx_pm_domain usb21_domain = {
> +       .dm = {
> +               .name           = "usb21_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_USB21,
> +};
> +static struct zx_pm_domain usb30_domain = {
> +       .dm = {
> +               .name           = "usb30_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_USB30,
> +};
> +static struct zx_pm_domain hsic_domain = {
> +       .dm = {
> +               .name           = "hsic_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_HSIC,
> +};
> +static struct zx_pm_domain gmac_domain = {
> +       .dm = {
> +               .name           = "gmac_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_GMAC,
> +};
> +static struct zx_pm_domain ts_domain = {
> +       .dm = {
> +               .name           = "ts_domain",
> +               .power_off      = zx_normal_power_off,
> +               .power_on       = zx_normal_power_on,
> +       },
> +       .bit = PCU_DM_TS,
> +};
> +struct generic_pm_domain *zx296718_pm_domains[] = {
> +       //&vou_domain.dm,
Remove this line.

> +       &sappu_domain.dm,

If you can add an index and add the index definition in devicetree
header file, it will be more convenient when binding power domain to
device in DT file. such as
         [ZX296718_PM_VDE] = &vde_domain.dm,

> +       &vde_domain.dm,
> +       &vce_domain.dm,
> +       &hde_domain.dm,
> +       &viu_domain.dm,
> +       &usb20_domain.dm,
> +       &usb21_domain.dm,
> +       &usb30_domain.dm,
> +       &hsic_domain.dm,
> +       &gmac_domain.dm,
> +       &ts_domain.dm,
> +       &vou_domain.dm,
> +};
> +
> +static int zx296718_pd_probe(struct platform_device *pdev)
> +{
> +       return zx_pd_probe(pdev,
> +                         zx296718_pm_domains,
> +                         ARRAY_SIZE(zx296718_pm_domains));
> +}
> +
> +static const struct of_device_id zx296718_pm_domain_matches[] = {
> +       { .compatible = "zte,zx296718-pcu", },

Suggest to rename probe function and of_device_id to a generic zx
name, then add compatible data so that probe function can be shared.
Probe function can find SoC specific data via comparing compatible
string and initialize device accordingly.

> +       { },
> +};
> +
> +static struct platform_driver zx296718_pd_driver = {
> +       .driver = {
> +               .name = "zx-powerdomain",
> +               .owner = THIS_MODULE,
> +               .of_match_table = zx296718_pm_domain_matches,
> +       },
> +       .probe = zx296718_pd_probe,
> +};
> +
> +static int __init zx296718_pd_init(void)
> +{
> +       return platform_driver_register(&zx296718_pd_driver);
> +}
> +subsys_initcall(zx296718_pd_init);
> --
> 2.7.4
>

^ permalink raw reply

* [PATCH] arm64: dts: zx: add pcu_domain node for zx296718
From: Shawn Guo @ 2016-12-05  3:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480766354-25168-1-git-send-email-baoyou.xie@linaro.org>

On Sat, Dec 03, 2016 at 07:59:14PM +0800, Baoyou Xie wrote:
> This patch adds the pcu_domain node, so it can be used
> by zte-soc's power domain driver.
> 
> Furthermore, it adds the document of the node.
> 
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
>  Documentation/devicetree/bindings/arm/zte.txt | 11 +++++++++++

DT bindings doc should be a separate patch, and goes together with
driver changes using the bindings through subsystem maintainers, rather
than dts patches.

>  arch/arm64/boot/dts/zte/zx296718.dtsi         |  7 +++++++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/zte.txt b/Documentation/devicetree/bindings/arm/zte.txt
> index 83369785..19a7e1b 100644
> --- a/Documentation/devicetree/bindings/arm/zte.txt
> +++ b/Documentation/devicetree/bindings/arm/zte.txt
> @@ -27,6 +27,9 @@ System management required properties:
>        - compatible = "zte,zx296718-aon-sysctrl"
>        - compatible = "zte,zx296718-sysctrl"
>  
> +Low power management required properties:
> +      - compatible = "zte,zx296718-pcu"
> +
>  Example:
>  aon_sysctrl: aon-sysctrl at 116000 {
>  	compatible = "zte,zx296718-aon-sysctrl", "syscon";
> @@ -37,3 +40,11 @@ sysctrl: sysctrl at 1463000 {
>  	compatible = "zte,zx296718-sysctrl", "syscon";
>  	reg = <0x1463000 0x1000>;
>  };
> +
> +pcu_domain: pcu at 0x00117000 {
> +        compatible = "zte,zx296718-pcu";
> +        reg = <0x00117000 0x1000>;
> +        #power-domain-cells = <1>;
> +        status = "ok";
> +};
> +

I think we should have a separate bindings doc for PCU power domain
block in Documentation/devicetree/bindings/soc/zte.

> diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi
> index b44d1d1..39e70c7 100644
> --- a/arch/arm64/boot/dts/zte/zx296718.dtsi
> +++ b/arch/arm64/boot/dts/zte/zx296718.dtsi
> @@ -351,5 +351,12 @@
>  			reg = <0x01480000 0x1000>;
>  			#clock-cells = <1>;
>  		};
> +
> +		pcu_domain: pcu at 0x00117000 {

Please drop the 0x and leading zeros in unit-address after node name.
That said, the node name should be written like below:

	pcu at 117000 {

Also, please sort the node with unit-address in order of the address.
That means that pcu node should be put after aon-sysctrl at 116000.

> +			compatible = "zte,zx296718-pcu";
> +			reg = <0x00117000 0x1000>;
> +			#power-domain-cells = <1>;
> +			status = "ok";

The property 'status' is generally used to enable devices that have
board-level pin-out or configuration in board dts.  It's not really
necessary for pcu here.

Shawn

> +		};
>  	};
>  };
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 1/2] soc: zte: pm_domains: Prepare for supporting ARMv8 2967 family
From: Jun Nie @ 2016-12-05  3:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480774291-6211-1-git-send-email-baoyou.xie@linaro.org>

2016-12-03 22:11 GMT+08:00 Baoyou Xie <baoyou.xie@linaro.org>:
> The ARMv8 2967 family (296718, 296716 etc) uses different value
> for controlling the power domain on/off registers, Choose the
> value depending on the compatible.
>
> Multiple domains are prepared for the family, it's privated by
> the drivers of boards.
>
> This patch prepares the common functions.
>
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
> ---
>  MAINTAINERS                  |   1 +
>  drivers/soc/Kconfig          |   1 +
>  drivers/soc/Makefile         |   1 +
>  drivers/soc/zte/Kconfig      |  13 ++++
>  drivers/soc/zte/Makefile     |   4 ++
>  drivers/soc/zte/pm_domains.c | 138 +++++++++++++++++++++++++++++++++++++++++++
>  drivers/soc/zte/pm_domains.h |  29 +++++++++
>  7 files changed, 187 insertions(+)
>  create mode 100644 drivers/soc/zte/Kconfig
>  create mode 100644 drivers/soc/zte/Makefile
>  create mode 100644 drivers/soc/zte/pm_domains.c
>  create mode 100644 drivers/soc/zte/pm_domains.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ad199da..8198389 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1979,6 +1979,7 @@ L:        linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:     Maintained
>  F:     arch/arm/mach-zx/
>  F:     drivers/clk/zte/
> +F:     drivers/soc/zte/
>  F:     Documentation/devicetree/bindings/arm/zte.txt
>  F:     Documentation/devicetree/bindings/clock/zx296702-clk.txt
>
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index f31bceb..f09023f 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -11,5 +11,6 @@ source "drivers/soc/tegra/Kconfig"
>  source "drivers/soc/ti/Kconfig"
>  source "drivers/soc/ux500/Kconfig"
>  source "drivers/soc/versatile/Kconfig"
> +source "drivers/soc/zte/Kconfig"
>
>  endmenu
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 50c23d0..05eae52 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -16,3 +16,4 @@ obj-$(CONFIG_ARCH_TEGRA)      += tegra/
>  obj-$(CONFIG_SOC_TI)           += ti/
>  obj-$(CONFIG_ARCH_U8500)       += ux500/
>  obj-$(CONFIG_PLAT_VERSATILE)   += versatile/
> +obj-$(CONFIG_ARCH_ZX)          += zte/
> diff --git a/drivers/soc/zte/Kconfig b/drivers/soc/zte/Kconfig
> new file mode 100644
> index 0000000..4953c3fa
> --- /dev/null
> +++ b/drivers/soc/zte/Kconfig
> @@ -0,0 +1,13 @@
> +#
> +# zx SoC drivers
> +#
> +menuconfig SOC_ZX
> +        bool "zx SoC driver support"

Why not reuse ARCH_ZX ?

> +
> +if SOC_ZX
> +
> +config ZX_PM_DOMAINS
> +        bool "zx PM domains"
> +        depends on PM_GENERIC_DOMAINS
> +
> +endif
> diff --git a/drivers/soc/zte/Makefile b/drivers/soc/zte/Makefile
> new file mode 100644
> index 0000000..97ac8ea
> --- /dev/null
> +++ b/drivers/soc/zte/Makefile
> @@ -0,0 +1,4 @@
> +#
> +# zx SOC drivers
> +#
> +obj-$(CONFIG_ZX_PM_DOMAINS) += pm_domains.o
> diff --git a/drivers/soc/zte/pm_domains.c b/drivers/soc/zte/pm_domains.c
> new file mode 100644
> index 0000000..5792f21
> --- /dev/null
> +++ b/drivers/soc/zte/pm_domains.c
> @@ -0,0 +1,138 @@
> +/*
> + * Copyright (C) 2015 ZTE Ltd.
> + *
> + * Author: Baoyou Xie <baoyou.xie@linaro.org>
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include "pm_domains.h"
> +
> +#define PCU_DM_CLKEN        0x18
> +#define PCU_DM_RSTEN        0x20
> +#define PCU_DM_ISOEN        0x1c

List registers with ascending sequence.

I find these registers offset is different with existing 296702
register offset. So I suggest to use offset table to resolve the
conflict so that this driver is extendable for more SoC with different
register offset if you want. You can reference
drivers/tty/serial/amba-pl011.c for register offset handling.

> +#define PCU_DM_PWREN        0x24
> +#define PCU_DM_ACK_SYNC     0x28
> +
> +static void __iomem *pcubase;
> +
> +int zx_normal_power_on(struct generic_pm_domain *domain)
> +{
> +       struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain;
> +       unsigned long loop = 20000;
> +       u32 val;
> +
> +       loop = 1000;
> +       do {
> +               val = readl_relaxed(pcubase + PCU_DM_PWREN);
> +               val |= BIT(zpd->bit);

bit polarity can also be configurable if you want support more SoCs
with different polarity setting.

> +               writel_relaxed(val, pcubase + PCU_DM_PWREN);
> +
> +               udelay(1);
> +               val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit);
> +       } while (--loop && !val);
> +
> +       if (!loop) {
> +               pr_err("Error: %s %s fail\n", __func__, domain->name);
> +               return -EIO;
> +       }
> +
> +       val = readl_relaxed(pcubase + PCU_DM_RSTEN);
> +       val &= ~BIT(zpd->bit);
> +       writel_relaxed(val | BIT(zpd->bit), pcubase + PCU_DM_RSTEN);
> +       udelay(5);
> +
> +       val = readl_relaxed(pcubase + PCU_DM_ISOEN);
> +       val &= ~BIT(zpd->bit);
> +       writel_relaxed(val, pcubase + PCU_DM_ISOEN);
> +       udelay(5);
> +
> +       val = readl_relaxed(pcubase + PCU_DM_CLKEN);
> +       val &= ~BIT(zpd->bit);
> +       writel_relaxed(val | BIT(zpd->bit), pcubase + PCU_DM_CLKEN);
> +       udelay(5);
> +
> +       pr_info("normal poweron %s\n", domain->name);
> +
> +       return 0;
> +}
> +
> +int zx_normal_power_off(struct generic_pm_domain *domain)
> +{
> +       struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain;
> +       unsigned long loop = 1000;
> +       u32 val;
> +
> +       val = readl_relaxed(pcubase + PCU_DM_CLKEN);
> +       val &= ~BIT(zpd->bit);
> +       writel_relaxed(val, pcubase + PCU_DM_CLKEN);
> +       udelay(5);
> +
> +       val = readl_relaxed(pcubase + PCU_DM_ISOEN);
> +       val &= ~BIT(zpd->bit);
> +       writel_relaxed(val | BIT(zpd->bit), pcubase + PCU_DM_ISOEN);
> +       udelay(5);
> +
> +       val = readl_relaxed(pcubase + PCU_DM_RSTEN);
> +       val &= ~BIT(zpd->bit);
> +       writel_relaxed(val, pcubase + PCU_DM_RSTEN);
> +       udelay(5);
> +
> +       loop = 1000;
> +       do {
> +               val = readl_relaxed(pcubase + PCU_DM_PWREN);
> +               val &= ~BIT(zpd->bit);
> +               writel_relaxed(val, pcubase + PCU_DM_PWREN);
> +
> +               udelay(1);
> +
> +               val = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit);
> +       } while (--loop && val);
> +
> +       if (!loop) {
> +               pr_err("Error: %s %s fail\n", __func__, domain->name);
> +               return -EIO;
> +       }
> +
> +       pr_info("normal poweroff %s\n", domain->name);
> +
> +       return 0;
> +}
> +
> +int
> +zx_pd_probe(struct platform_device *pdev,
> +          struct generic_pm_domain **zx_pm_domains,
> +          int domain_num)
> +{
> +       struct genpd_onecell_data *genpd_data;
> +       struct resource *res;
> +       int i;
> +
> +       genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL);
> +       if (!genpd_data)
> +               return -ENOMEM;
> +
> +       genpd_data->domains = zx_pm_domains;
> +       genpd_data->num_domains = domain_num;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res) {
> +               dev_err(&pdev->dev, "no memory resource defined\n");
> +               return -ENODEV;
> +       }
> +
> +       pcubase = devm_ioremap_resource(&pdev->dev, res);
> +       if (!pcubase) {
> +               dev_err(&pdev->dev, "ioremap fail.\n");
> +               return -EIO;
> +       }
> +
> +       for (i = 0; i < domain_num; ++i)
> +               pm_genpd_init(zx_pm_domains[i], NULL, false);
> +
> +       of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data);
> +       dev_info(&pdev->dev, "powerdomain init ok\n");
> +       return 0;
> +}
> diff --git a/drivers/soc/zte/pm_domains.h b/drivers/soc/zte/pm_domains.h
> new file mode 100644
> index 0000000..613e0be
> --- /dev/null
> +++ b/drivers/soc/zte/pm_domains.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (c) 2015 ZTE Co., Ltd.
> + *           http://www.zte.com.cn
> + *
> + * Header for ZTE's Power Domain Driver support
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __ZTE_PM_DOMAIN_H
> +#define __ZTE_PM_DOMAIN_H
> +
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +
> +struct zx_pm_domain {
> +       struct generic_pm_domain dm;
> +       unsigned int bit;
> +};
> +
> +extern int zx_normal_power_on(struct generic_pm_domain *domain);
> +extern int zx_normal_power_off(struct generic_pm_domain *domain);
> +extern int
> +zx_pd_probe(struct platform_device *pdev,
> +          struct generic_pm_domain **zx_pm_domains,
> +          int domain_num);
> +#endif /* __ZTE_PM_DOMAIN_H */
> --
> 2.7.4
>

^ permalink raw reply

* [PATCH V2 fix 5/6] mm: hugetlb: add a new function to allocate a new gigantic page
From: Huang Shijie @ 2016-12-05  3:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202140325.GM6830@dhcp22.suse.cz>

On Fri, Dec 02, 2016 at 03:03:30PM +0100, Michal Hocko wrote:
> On Wed 16-11-16 14:55:04, Huang Shijie wrote:
> > There are three ways we can allocate a new gigantic page:
> > 
> > 1. When the NUMA is not enabled, use alloc_gigantic_page() to get
> >    the gigantic page.
> > 
> > 2. The NUMA is enabled, but the vma is NULL.
> >    There is no memory policy we can refer to.
> >    So create a @nodes_allowed, initialize it with init_nodemask_of_mempolicy()
> >    or init_nodemask_of_node(). Then use alloc_fresh_gigantic_page() to get
> >    the gigantic page.
> > 
> > 3. The NUMA is enabled, and the vma is valid.
> >    We can follow the memory policy of the @vma.
> > 
> >    Get @nodes_allowed by huge_nodemask(), and use alloc_fresh_gigantic_page()
> >    to get the gigantic page.
> 
> Again __hugetlb_alloc_gigantic_page is not used and it is hard to deduce
> its usage from this commit. The above shouldn't be really much different from

Okay, I will merge it into the later patch.

> what we do in alloc_pages_vma so please make sure to check it before
> coming up with something hugetlb specific.
No problem. Thanks for the hint.

Thanks
Huang Shijie

^ permalink raw reply

* [PATCH V2 fix 4/6] mm: mempolicy: intruduce a helper huge_nodemask()
From: Huang Shijie @ 2016-12-05  3:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202135845.GL6830@dhcp22.suse.cz>

On Fri, Dec 02, 2016 at 02:58:46PM +0100, Michal Hocko wrote:
> On Wed 16-11-16 14:53:02, Huang Shijie wrote:
> > This patch intruduces a new helper huge_nodemask(),
> > we can use it to get the node mask.
> > 
> > This idea of the function is from the init_nodemask_of_mempolicy():
> >    Return true if we can succeed in extracting the node_mask
> > for 'bind' or 'interleave' policy or initializing the node_mask
> > to contain the single node for 'preferred' or 'local' policy.
> 
> It is absolutely unclear how this is going to be used from this patch.
> Please make sure to also use a newly added function in the same patch.
> 
Okay, I will merge this patch into the later patch.

Thanks	
Huang Shijie	

^ permalink raw reply

* [PATCH v2 3/6] mm: hugetlb: change the return type for alloc_fresh_gigantic_page
From: Huang Shijie @ 2016-12-05  3:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202135643.GK6830@dhcp22.suse.cz>

On Fri, Dec 02, 2016 at 02:56:43PM +0100, Michal Hocko wrote:
> On Mon 14-11-16 15:07:36, Huang Shijie wrote:
> > This patch changes the return type to "struct page*" for
> > alloc_fresh_gigantic_page().
> 
> OK, this makes somme sense. Other hugetlb allocation function (and page
> allocator in general) return struct page as well. Besides that int would
> make sense if we wanted to convey an error code but 0 vs. 1 just doesn't
> make any sense.
> 
> But if you are changing that then alloc_fresh_huge_page should be
> changed as well.
Okay.

> 
> > This patch makes preparation for later patch.
> > 
> > Signed-off-by: Huang Shijie <shijie.huang@arm.com>
> 
> Acked-by: Michal Hocko <mhocko@suse.com>
Thanks a lot.

Thanks
Huang Shijie

^ permalink raw reply

* [PATCH v2 2/6] mm: hugetlb: add a new parameter for some functions
From: Huang Shijie @ 2016-12-05  3:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202135229.GJ6830@dhcp22.suse.cz>

On Fri, Dec 02, 2016 at 02:52:30PM +0100, Michal Hocko wrote:
> On Mon 14-11-16 15:07:35, Huang Shijie wrote:
> > This patch adds a new parameter, the "no_init", for these functions:
> >    alloc_fresh_gigantic_page_node()
> >    alloc_fresh_gigantic_page()
> > 
> > The prep_new_huge_page() does some initialization for the new page.
> > But sometime, we do not need it to do so, such as in the surplus case
> > in later patch.
> > 
> > With this parameter, the prep_new_huge_page() can be called by needed:
> >    If the "no_init" is false, calls the prep_new_huge_page() in
> >    the alloc_fresh_gigantic_page_node();
> 
> This double negative just makes my head spin. I haven't got to later
> patch to understand the motivation but if anything bool do_prep would
> be much more clear. In general doing these "init if a parameter is
Okay, I will use the "do_prep" for the new parameter.

thanks for the code review.

Huang Shijie

^ permalink raw reply

* [PATCH v2] arm64: dts: zx: support cpu-freq for zx296718
From: Shawn Guo @ 2016-12-05  2:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1480657956-8140-1-git-send-email-baoyou.xie@linaro.org>

On Fri, Dec 02, 2016 at 01:52:36PM +0800, Baoyou Xie wrote:
> This patch adds the CPU clock phandle in CPU's node
> and uses operating-points-v2 to register operating points.
> 
> So it can be used by cpufreq-dt driver.
> 
> Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>

Applied, thanks.

^ permalink raw reply

* [PATCH v2] arm64: dts: zx: support cpu-freq for zx296718
From: Jun Nie @ 2016-12-05  2:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202060000.GE7682@vireshk-i7>

2016-12-02 14:00 GMT+08:00 Viresh Kumar <viresh.kumar@linaro.org>:
> On 02-12-16, 13:58, Baoyou Xie wrote:
>> + Viresh, the author of the bindings.
>>
>> On 2 December 2016 at 13:52, Baoyou Xie <baoyou.xie@linaro.org> wrote:
>>
>> > This patch adds the CPU clock phandle in CPU's node
>> > and uses operating-points-v2 to register operating points.
>> >
>> > So it can be used by cpufreq-dt driver.
>> >
>> > Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
>> > ---
>> >  arch/arm64/boot/dts/zte/zx296718.dtsi | 39 ++++++++++++++++++++++++++++++
>> > +++++
>> >  1 file changed, 39 insertions(+)

Reviewed-by: Jun Nie <jun.nie@linaro.org>

>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
>
> --
> viresh

^ permalink raw reply

* [PATCH v3 -next 1/2] ARM: sunxi: add support for H2+ SoC
From: Alexey Kardashevskiy @ 2016-12-05  2:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161202150513.34691-1-icenowy@aosc.xyz>

On 03/12/16 02:05, Icenowy Zheng wrote:
> Allwinner H2+ is a quad-core Cortex-A7 SoC.
> 
> It is very like H3, that they share the same SoC ID (0x1680), and H3
> memory maps as well as drivers works well on the SoC.


What git tree is this made against of? Thanks.


> 
> Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> ---
> Changes since v2:
> - Changed compatible from allwinner,sun8i-h2plus to allwinner,sun8i-h2-plus.
>  Documentation/arm/sunxi/README                  | 4 ++++
>  Documentation/devicetree/bindings/arm/sunxi.txt | 1 +
>  arch/arm/mach-sunxi/sunxi.c                     | 1 +
>  3 files changed, 6 insertions(+)
> 
> diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README
> index cd02433..1fe4d99c 100644
> --- a/Documentation/arm/sunxi/README
> +++ b/Documentation/arm/sunxi/README
> @@ -63,6 +63,10 @@ SunXi family
>          + User Manual
>            http://dl.linux-sunxi.org/A33/A33%20user%20manual%20release%201.1.pdf
>  
> +      - Allwinner H2+ (sun8i)
> +        + No document available now, but is known to be working properly with
> +          H3 drivers and memory map.
> +
>        - Allwinner H3 (sun8i)
>          + Datasheet
>            http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt
> index 4d6467c..59b143f 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.txt
> +++ b/Documentation/devicetree/bindings/arm/sunxi.txt
> @@ -13,6 +13,7 @@ using one of the following compatible strings:
>    allwinner,sun8i-a33
>    allwinner,sun8i-a83t
>    allwinner,sun8i-h3
> +  allwinner,sun8i-h2-plus
>    allwinner,sun9i-a80
>    allwinner,sun50i-a64
>    nextthing,gr8
> diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
> index 2e2bde2..320d2af 100644
> --- a/arch/arm/mach-sunxi/sunxi.c
> +++ b/arch/arm/mach-sunxi/sunxi.c
> @@ -63,6 +63,7 @@ static const char * const sun8i_board_dt_compat[] = {
>  	"allwinner,sun8i-a23",
>  	"allwinner,sun8i-a33",
>  	"allwinner,sun8i-a83t",
> +	"allwinner,sun8i-h2-plus",
>  	"allwinner,sun8i-h3",
>  	NULL,
>  };
> 


-- 
Alexey

^ permalink raw reply

* [PATCH v2 1/2] arm64: dts: zx: Fix gic GICR property
From: Shawn Guo @ 2016-12-05  2:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3937871.l5gZt4hBke@wuerfel>

Hi Arnd,

On Fri, Dec 02, 2016 at 09:28:58PM +0100, Arnd Bergmann wrote:
> Given that there is any concern about the patch now, and the merge
> window is almost open, I'm moving both patches to the
> next/fixes-non-critical branch and will merge it for v4.10 instead
> of sending it for v4.9.
> 
> If you end up deciding that the patch is wrong, please follow up
> with a fix on top. Once the situation is resolved and the patch
> merged upstream, feel free to ask stable at vger.kernel.org for a
> backport to stable kernels to get it into v4.9.x.

The patch is correct, though it can be cleaned up a bit further per
Marc's suggestion.  Since we now have 4.9-rc8, I'm wondering if we can
still get this into 4.9 to save the stable kernel backport.

I sent you a cleanup patch on top of this one yesterday.  If you like,
I can quickly resend the patch with the cleanup squashed.

Thanks,
Shawn

^ permalink raw reply

* [PATCH 1/3] arm: hisi: add ARCH_MULTI_V5 support
From: Jiancheng Xue @ 2016-12-05  2:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5893354.6MrIxqzRoI@wuerfel>

Hi Arnd,

On 2016/10/17 21:48, Arnd Bergmann wrote:
> On Monday, October 17, 2016 8:07:03 PM CEST Pan Wen wrote:
>> Add support for some HiSilicon SoCs which depend on ARCH_MULTI_V5.
>>
>> Signed-off-by: Pan Wen <wenpan@hisilicon.com>
>>
> 
> Looks ok. I've added Marty Plummer to Cc, he was recently proposing
> patches for Hi3520, which I think is closely related to this one.
> Please try to work together so the patches don't conflict. It should
> be fairly straightforward since you are basically doing the same
> change here.
> 
Marty hasn't give any replies about this thread until now. I reviewed
the patch for Hi3520. And I think this patch won't conflict with Hi3520.
Could you help us to ack this patch?

Thanks,
Jiancheng

^ permalink raw reply

* [PATCH] ARM: dts: imx7d: fix LCDIF clock assignment
From: Shawn Guo @ 2016-12-05  2:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7e4829f484f6c4425fc9d01bea1a094f@agner.ch>

Hi Arnd, Olof,

On Sun, Dec 04, 2016 at 05:26:58PM -0800, Stefan Agner wrote:
> Hi Shawn
> 
> On 2016-11-23 15:02, Fabio Estevam wrote:
> > On Tue, Nov 22, 2016 at 10:42 PM, Stefan Agner <stefan@agner.ch> wrote:
> >> The eLCDIF IP of the i.MX 7 SoC knows multiple clocks and lists them
> >> separately:
> >>
> >> Clock      Clock Root              Description
> >> apb_clk    MAIN_AXI_CLK_ROOT       AXI clock
> >> pix_clk    LCDIF_PIXEL_CLK_ROOT    Pixel clock
> >> ipg_clk_s  MAIN_AXI_CLK_ROOT       Peripheral access clock
> >>
> >> All of them are switched by a single gate, which is part of the
> >> IMX7D_LCDIF_PIXEL_ROOT_CLK clock. Hence using that clock also for
> >> the AXI bus clock (clock-name "axi") makes sure the gate gets
> >> enabled when accessing registers.
> >>
> >> There seem to be no separate AXI display clock, and the clock is
> >> optional. Hence remove the dummy clock.
> >>
> >> This fixes kernel freezes when starting the X-Server (which
> >> disables/re-enables the display controller).
> >>
> >> Signed-off-by: Stefan Agner <stefan@agner.ch>
> > 
> > Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> 
> Since this fixes a kernel freeze, is there a chance to get this still in
> 4.9?

Since we get one more week to the final 4.9, is it possible for you to
send this fix for 4.9 inclusion?  Thanks.

For the patch,

Acked-by: Shawn Guo <shawnguo@kernel.org>

Shawn

^ permalink raw reply

* [PATCH 2/2] ARM: dts: sun8i: Specify memblock for Nano Pi Neo
From: Milo Kim @ 2016-12-05  2:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161205020032.26586-1-woogyom.kim@gmail.com>

The board has DDR3 256MB. This patch helps scanning the memory and
adding memblock through the DT.

Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
---
 arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
index 8d2cc6e..433f55d 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
@@ -45,4 +45,9 @@
 / {
 	model = "FriendlyARM NanoPi NEO";
 	compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3";
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0x40000000 0x10000000>;
+	};
 };
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/2] ARM: dts: sun8i: Specify memblock for Nano Pi M1
From: Milo Kim @ 2016-12-05  2:00 UTC (permalink / raw)
  To: linux-arm-kernel

The board has DDR3 512MB. This patch helps scanning the memory and
adding memblock through the DT.

Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
---
 arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
index ec63d10..be3668f 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-m1.dts
@@ -45,6 +45,11 @@
 / {
 	model = "FriendlyArm NanoPi M1";
 	compatible = "friendlyarm,nanopi-m1", "allwinner,sun8i-h3";
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0x40000000 0x20000000>;
+	};
 };
 
 &ehci1 {
-- 
2.9.3

^ 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