Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Boris BREZILLON @ 2014-02-05  8:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391554766-11285-1-git-send-email-gregory.clement@free-electrons.com>

Hi Greg,

On 04/02/2014 23:59, Gregory CLEMENT wrote:
> Until now the clock providers were initialized in the order found in
> the device tree. This led to have the dependencies between the clocks
> not respected: children clocks could be initialized before their
> parent clocks.
>
> Instead of forcing each platform to manage its own initialization order,
> this patch adds this work inside the framework itself.
>
> Using the data of the device tree the of_clk_init function now delayed
> the initialization of a clock provider if its parent provider was not
> ready yet.
>

Great! I remember having some trouble with this "parent is not 
registered yet" issue (but I don't recall how I solved it, maybe in 
reordering clk nodes).
Anyway, this will help other platforms too (at least the at91 one).

> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> Mike,
>
> this patch could solve the issues we get on severals mvebu platform
> since 3.14-rc1. This is an alternate solution of the patch set sent by
> Sebastian. However as it modifies the clock framework itself, it is
> more sensible.
>
> I find this solution more elegant than changing the order of the
> initialization of the clock at the platform level. However as it
> should be tested on more platforms that only the mvebu ones, it would
> take some time, and I don't want to still have "broken" platform
> during more release candidate. So at the end this patch should be part
> of the 3.15 kernel.
>
> Thanks,
>
> Gregory
>
>   drivers/clk/clk.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
>   1 file changed, 91 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 5517944495d8..beb0f8b0c2a0 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2526,24 +2526,112 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
>   }
>   EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
>
> +struct clock_provider {
> +	of_clk_init_cb_t clk_init_cb;
> +	struct device_node *np;
> +	struct list_head node;
> +};
> +
> +static LIST_HEAD(clk_provider_list);
> +
> +/*
> + * This function looks for a parent clock. If there is one, then it
> + * checks that the provider for this parent clock was initialized, in
> + * this case the parent clock will be ready.
> + */
> +static int parent_ready(struct device_node *np)
> +{
> +	struct of_phandle_args clkspec;
> +	struct of_clk_provider *provider;
> +
> +	/*
> +	 * If there is no clock parent, no need to wait for them, then
> +	 * we can consider their absence as being ready
> +	 */
> +	if (of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
> +					&clkspec))
> +		return 1;
> +
> +	/* Check if we have such a provider in our array */
> +	list_for_each_entry(provider, &of_clk_providers, link) {
> +		if (provider->node == clkspec.np)
> +			return 1;
> +	}

Shouldn't we wait for all parents to be ready (If I'm right, you're only 
waiting for the first parent...) ?
And if you only request for one clk to be ready, why the first one (you 
could loop over parent clks and stop when one of its parent is ready) ?

Best Regards,

Boris

> +
> +	return 0;
> +}
> +
>   /**
>    * of_clk_init() - Scan and init clock providers from the DT
>    * @matches: array of compatible values and init functions for providers.
>    *
> - * This function scans the device tree for matching clock providers and
> - * calls their initialization functions
> + * This function scans the device tree for matching clock providers
> + * and calls their initialization functions. It also do it by trying
> + * to follow the dependencies.
>    */
>   void __init of_clk_init(const struct of_device_id *matches)
>   {
>   	const struct of_device_id *match;
>   	struct device_node *np;
> +	struct clock_provider *clk_provider, *next;
> +	bool is_init_done;
>
>   	if (!matches)
>   		matches = &__clk_of_table;
>
>   	for_each_matching_node_and_match(np, matches, &match) {
>   		of_clk_init_cb_t clk_init_cb = match->data;
> -		clk_init_cb(np);
> +
> +
> +		if (parent_ready(np)) {
> +			/*
> +			 * The parent clock is ready or there is no
> +			 * clock parent at all, in this case the
> +			 * provider can be initialize immediately.
> +			 */
> +			clk_init_cb(np);
> +		} else {
> +			/*
> +			 * The parent clock is not ready, this
> +			 * provider is moved to a list to be
> +			 * initialized later
> +			 */
> +			struct clock_provider *parent = kzalloc(sizeof(struct clock_provider),
> +							GFP_KERNEL);
> +
> +			parent->clk_init_cb = match->data;
> +			parent->np = np;
> +			list_add(&parent->node, &clk_provider_list);
> +		}
> +	}
> +
> +	while (!list_empty(&clk_provider_list)) {
> +		is_init_done = false;
> +		list_for_each_entry_safe(clk_provider, next,
> +					&clk_provider_list, node) {
> +			if (parent_ready(clk_provider->np)) {
> +				clk_provider->clk_init_cb(clk_provider->np);
> +				list_del(&clk_provider->node);
> +				kfree(clk_provider);
> +				is_init_done = true;
> +			}
> +		}
> +
> +		if (!is_init_done) {
> +			/*
> +			 * We didn't managed to initialize any of the
> +			 * remaining providers during the last loop,
> +			 * so now we initialize all the remaining ones
> +			 * unconditionally in case the clock parent
> +			 * was not mandatory
> +			 */
> +			list_for_each_entry_safe(clk_provider, next,
> +						&clk_provider_list, node) {
> +				clk_provider->clk_init_cb(clk_provider->np);
> +				list_del(&clk_provider->node);
> +				kfree(clk_provider);
> +			}
> +		}
>   	}
>   }
>   #endif
>

^ permalink raw reply

* [PATCH v2 4/4] clk: at91: optimization of the determine_rate callback
From: Jean-Jacques Hiblot @ 2014-02-05  8:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---
 drivers/clk/at91/clk-programmable.c | 38 ++++++++-----------------------------
 1 file changed, 8 insertions(+), 30 deletions(-)

diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 7bcc725..62e2509 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -139,43 +139,21 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct clk_programmable *prog = to_clk_programmable(hw);
 	struct at91_pmc *pmc = prog->pmc;
 	const struct clk_programmable_layout *layout = prog->layout;
-	unsigned long best_rate = parent_rate;
-	unsigned long best_diff;
-	unsigned long new_diff;
-	unsigned long cur_rate;
+	unsigned long div = parent_rate / rate;
 	int shift = 0;
 	u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
 		  ~(PROG_PRES_MASK << layout->pres_shift);
 
-	if (rate > parent_rate)
-		return parent_rate;
-	else
-		best_diff = parent_rate - rate;
+	if (!div)
+		return -EINVAL;
 
-	if (!best_diff) {
-		pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | shift);
-		return 0;
-	}
-
-	for (shift = 1; shift < PROG_PRES_MASK; shift++) {
-		cur_rate = parent_rate >> shift;
-
-		if (cur_rate > rate)
-			new_diff = cur_rate - rate;
-		else
-			new_diff = rate - cur_rate;
-
-		if (!new_diff)
-			break;
+	shift = fls(div) - 1;
 
-		if (new_diff < best_diff) {
-			best_diff = new_diff;
-			best_rate = cur_rate;
-		}
+	if (div != (1<<shift))
+		return -EINVAL;
 
-		if (rate > cur_rate)
-			break;
-	}
+	if (shift >= PROG_PRES_MASK)
+		return -EINVAL;
 
 	pmc_write(pmc, AT91_PMC_PCKR(prog->id),
 		  tmp | (shift << layout->pres_shift));
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v2 3/4] clk: at91: fix programmable clk irq handling
From: Jean-Jacques Hiblot @ 2014-02-05  8:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>

The PCKRDY bit is not set until the system clock is enabled.
This patch moves the management of the ready status in the system clock
driver.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---
 drivers/clk/at91/clk-programmable.c | 108 +++++++++---------------------------
 drivers/clk/at91/clk-system.c       |  74 ++++++++++++++++++++----
 2 files changed, 89 insertions(+), 93 deletions(-)

diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index eff7016..7bcc725 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -13,12 +13,9 @@
 #include <linux/clk/at91_pmc.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_irq.h>
 #include <linux/io.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
 
 #include "pmc.h"
 
@@ -38,68 +35,23 @@ struct clk_programmable_layout {
 struct clk_programmable {
 	struct clk_hw hw;
 	struct at91_pmc *pmc;
-	unsigned int irq;
-	wait_queue_head_t wait;
 	u8 id;
-	u8 css;
-	u8 pres;
-	u8 slckmck;
 	const struct clk_programmable_layout *layout;
 };
 
 #define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw)
 
-
-static irqreturn_t clk_programmable_irq_handler(int irq, void *dev_id)
-{
-	struct clk_programmable *prog = (struct clk_programmable *)dev_id;
-
-	wake_up(&prog->wait);
-
-	return IRQ_HANDLED;
-}
-
-static int clk_programmable_prepare(struct clk_hw *hw)
-{
-	u32 tmp;
-	struct clk_programmable *prog = to_clk_programmable(hw);
-	struct at91_pmc *pmc = prog->pmc;
-	const struct clk_programmable_layout *layout = prog->layout;
-	u8 id = prog->id;
-	u32 mask = PROG_STATUS_MASK(id);
-
-	tmp = prog->css | (prog->pres << layout->pres_shift);
-	if (layout->have_slck_mck && prog->slckmck)
-		tmp |= AT91_PMC_CSSMCK_MCK;
-
-	pmc_write(pmc, AT91_PMC_PCKR(id), tmp);
-
-	while (!(pmc_read(pmc, AT91_PMC_SR) & mask))
-		wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask);
-
-	return 0;
-}
-
-static int clk_programmable_is_ready(struct clk_hw *hw)
-{
-	struct clk_programmable *prog = to_clk_programmable(hw);
-	struct at91_pmc *pmc = prog->pmc;
-
-	return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id));
-}
-
 static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
 						  unsigned long parent_rate)
 {
-	u32 tmp;
+	u32 pres;
 	struct clk_programmable *prog = to_clk_programmable(hw);
 	struct at91_pmc *pmc = prog->pmc;
 	const struct clk_programmable_layout *layout = prog->layout;
 
-	tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
-	prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK;
-
-	return parent_rate >> prog->pres;
+	pres = (pmc_read(pmc, AT91_PMC_PCKR(prog->id)) >> layout->pres_shift) &
+	       PROG_PRES_MASK;
+	return parent_rate >> pres;
 }
 
 static long clk_programmable_determine_rate(struct clk_hw *hw,
@@ -146,17 +98,22 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_programmable *prog = to_clk_programmable(hw);
 	const struct clk_programmable_layout *layout = prog->layout;
+	struct at91_pmc *pmc = prog->pmc;
+	u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & ~layout->css_mask;
+
+	if (layout->have_slck_mck)
+		tmp &= AT91_PMC_CSSMCK_MCK;
+
 	if (index > layout->css_mask) {
 		if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) {
-			prog->css = 0;
-			prog->slckmck = 1;
+			tmp |= AT91_PMC_CSSMCK_MCK;
 			return 0;
 		} else {
 			return -EINVAL;
 		}
 	}
 
-	prog->css = index;
+	pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | index);
 	return 0;
 }
 
@@ -169,13 +126,9 @@ static u8 clk_programmable_get_parent(struct clk_hw *hw)
 	const struct clk_programmable_layout *layout = prog->layout;
 
 	tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
-	prog->css = tmp & layout->css_mask;
-	ret = prog->css;
-	if (layout->have_slck_mck) {
-		prog->slckmck = !!(tmp & AT91_PMC_CSSMCK_MCK);
-		if (prog->slckmck && !ret)
-			ret = PROG_MAX_RM9200_CSS + 1;
-	}
+	ret = tmp & layout->css_mask;
+	if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !ret)
+		ret = PROG_MAX_RM9200_CSS + 1;
 
 	return ret;
 }
@@ -184,11 +137,15 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
 				     unsigned long parent_rate)
 {
 	struct clk_programmable *prog = to_clk_programmable(hw);
+	struct at91_pmc *pmc = prog->pmc;
+	const struct clk_programmable_layout *layout = prog->layout;
 	unsigned long best_rate = parent_rate;
 	unsigned long best_diff;
 	unsigned long new_diff;
 	unsigned long cur_rate;
 	int shift = 0;
+	u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
+		  ~(PROG_PRES_MASK << layout->pres_shift);
 
 	if (rate > parent_rate)
 		return parent_rate;
@@ -196,7 +153,7 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
 		best_diff = parent_rate - rate;
 
 	if (!best_diff) {
-		prog->pres = shift;
+		pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | shift);
 		return 0;
 	}
 
@@ -220,13 +177,13 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
 			break;
 	}
 
-	prog->pres = shift;
+	pmc_write(pmc, AT91_PMC_PCKR(prog->id),
+		  tmp | (shift << layout->pres_shift));
+
 	return 0;
 }
 
 static const struct clk_ops programmable_ops = {
-	.prepare = clk_programmable_prepare,
-	.is_prepared = clk_programmable_is_ready,
 	.recalc_rate = clk_programmable_recalc_rate,
 	.determine_rate = clk_programmable_determine_rate,
 	.get_parent = clk_programmable_get_parent,
@@ -235,16 +192,14 @@ static const struct clk_ops programmable_ops = {
 };
 
 static struct clk * __init
-at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
+at91_clk_register_programmable(struct at91_pmc *pmc,
 			       const char *name, const char **parent_names,
 			       u8 num_parents, u8 id,
 			       const struct clk_programmable_layout *layout)
 {
-	int ret;
 	struct clk_programmable *prog;
 	struct clk *clk = NULL;
 	struct clk_init_data init;
-	char irq_name[11];
 
 	if (id > PROG_ID_MAX)
 		return ERR_PTR(-EINVAL);
@@ -263,14 +218,6 @@ at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
 	prog->layout = layout;
 	prog->hw.init = &init;
 	prog->pmc = pmc;
-	prog->irq = irq;
-	init_waitqueue_head(&prog->wait);
-	irq_set_status_flags(prog->irq, IRQ_NOAUTOEN);
-	snprintf(irq_name, sizeof(irq_name), "clk-prog%d", id);
-	ret = request_irq(prog->irq, clk_programmable_irq_handler,
-			  IRQF_TRIGGER_HIGH, irq_name, prog);
-	if (ret)
-		return ERR_PTR(ret);
 
 	clk = clk_register(NULL, &prog->hw);
 	if (IS_ERR(clk))
@@ -304,7 +251,6 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
 	int num;
 	u32 id;
 	int i;
-	unsigned int irq;
 	struct clk *clk;
 	int num_parents;
 	const char *parent_names[PROG_SOURCE_MAX];
@@ -332,11 +278,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
 		if (of_property_read_string(np, "clock-output-names", &name))
 			name = progclknp->name;
 
-		irq = irq_of_parse_and_map(progclknp, 0);
-		if (!irq)
-			continue;
-
-		clk = at91_clk_register_programmable(pmc, irq, name,
+		clk = at91_clk_register_programmable(pmc, name,
 						     parent_names, num_parents,
 						     id, layout);
 		if (IS_ERR(clk))
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index a98557b..82c5f44 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -14,6 +14,11 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 
 #include "pmc.h"
 
@@ -25,19 +30,48 @@
 struct clk_system {
 	struct clk_hw hw;
 	struct at91_pmc *pmc;
+	unsigned int irq;
+	wait_queue_head_t wait;
 	u8 id;
 };
 
-static int clk_system_enable(struct clk_hw *hw)
+static inline int is_pck(int id)
+{
+	return (id >= 8) && (id <= 15);
+}
+static irqreturn_t clk_system_irq_handler(int irq, void *dev_id)
+{
+	struct clk_system *sys = (struct clk_system *)dev_id;
+
+	wake_up(&sys->wait);
+	disable_irq_nosync(sys->irq);
+
+	return IRQ_HANDLED;
+}
+
+static int clk_system_prepare(struct clk_hw *hw)
 {
 	struct clk_system *sys = to_clk_system(hw);
 	struct at91_pmc *pmc = sys->pmc;
+	u32 mask = 1 << sys->id;
 
-	pmc_write(pmc, AT91_PMC_SCER, 1 << sys->id);
+	pmc_write(pmc, AT91_PMC_SCER, mask);
+
+	if (!is_pck(sys->id))
+		return 0;
+
+	while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
+		if (sys->irq) {
+			enable_irq(sys->irq);
+			wait_event(sys->wait,
+				   pmc_read(pmc, AT91_PMC_SR) & mask);
+		} else
+			cpu_relax();
+	}
 	return 0;
 }
 
-static void clk_system_disable(struct clk_hw *hw)
+static void clk_system_unprepare(struct clk_hw *hw)
 {
 	struct clk_system *sys = to_clk_system(hw);
 	struct at91_pmc *pmc = sys->pmc;
@@ -45,27 +79,34 @@ static void clk_system_disable(struct clk_hw *hw)
 	pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
 }
 
-static int clk_system_is_enabled(struct clk_hw *hw)
+static int clk_system_is_prepared(struct clk_hw *hw)
 {
 	struct clk_system *sys = to_clk_system(hw);
 	struct at91_pmc *pmc = sys->pmc;
 
-	return !!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id));
+	if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)))
+		return 0;
+
+	if (!is_pck(sys->id))
+		return 1;
+
+	return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id));
 }
 
 static const struct clk_ops system_ops = {
-	.enable = clk_system_enable,
-	.disable = clk_system_disable,
-	.is_enabled = clk_system_is_enabled,
+	.prepare = clk_system_prepare,
+	.unprepare = clk_system_unprepare,
+	.is_prepared = clk_system_is_prepared,
 };
 
 static struct clk * __init
 at91_clk_register_system(struct at91_pmc *pmc, const char *name,
-			 const char *parent_name, u8 id)
+			 const char *parent_name, u8 id, int irq)
 {
 	struct clk_system *sys;
 	struct clk *clk = NULL;
 	struct clk_init_data init;
+	int ret;
 
 	if (!parent_name || id > SYSTEM_MAX_ID)
 		return ERR_PTR(-EINVAL);
@@ -90,6 +131,15 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
 	sys->id = id;
 	sys->hw.init = &init;
 	sys->pmc = pmc;
+	sys->irq = irq;
+	if (irq) {
+		init_waitqueue_head(&sys->wait);
+		irq_set_status_flags(sys->irq, IRQ_NOAUTOEN);
+		ret = request_irq(sys->irq, clk_system_irq_handler,
+				IRQF_TRIGGER_HIGH, name, sys);
+		if (ret)
+			return ERR_PTR(ret);
+	}
 
 	clk = clk_register(NULL, &sys->hw);
 	if (IS_ERR(clk))
@@ -102,6 +152,7 @@ static void __init
 of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
 {
 	int num;
+	int irq = 0;
 	u32 id;
 	struct clk *clk;
 	const char *name;
@@ -119,9 +170,12 @@ of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
 		if (of_property_read_string(np, "clock-output-names", &name))
 			name = sysclknp->name;
 
+		if (is_pck(id))
+			irq = irq_of_parse_and_map(sysclknp, 0);
+
 		parent_name = of_clk_get_parent_name(sysclknp, 0);
 
-		clk = at91_clk_register_system(pmc, name, parent_name, id);
+		clk = at91_clk_register_system(pmc, name, parent_name, id, irq);
 		if (IS_ERR(clk))
 			continue;
 
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v2 2/4] clk: at91: propagate rate change on system clks
From: Jean-Jacques Hiblot @ 2014-02-05  8:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>

From: Boris BREZILLON <b.brezillon@overkiz.com>

System clks are just gates, and thus do not provide any rate operations.
Authorize clk rate change to be propagated to system clk parents.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/clk/at91/clk-system.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 8f7c043..a98557b 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -84,7 +84,8 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
 	 * (see drivers/memory) which would request and enable the ddrck clock.
 	 * When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
 	 */
-	init.flags = CLK_IGNORE_UNUSED;
+	init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT |
+		     CLK_IGNORE_UNUSED;
 
 	sys->id = id;
 	sys->hw.init = &init;
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v2 1/4] clk: at91: replace prog clk round_rate with determine_rate
From: Jean-Jacques Hiblot @ 2014-02-05  8:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>

From: Boris BREZILLON <b.brezillon@overkiz.com>

Implement the determine_rate callback to choose the best parent clk that
fulfills the requested rate.

Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
 drivers/clk/at91/clk-programmable.c | 56 ++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index fd792b2..eff7016 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -102,40 +102,40 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
 	return parent_rate >> prog->pres;
 }
 
-static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate,
-					unsigned long *parent_rate)
+static long clk_programmable_determine_rate(struct clk_hw *hw,
+					    unsigned long rate,
+					    unsigned long *best_parent_rate,
+					    struct clk **best_parent_clk)
 {
-	unsigned long best_rate = *parent_rate;
-	unsigned long best_diff;
-	unsigned long new_diff;
-	unsigned long cur_rate;
-	int shift = shift;
-
-	if (rate > *parent_rate)
-		return *parent_rate;
-	else
-		best_diff = *parent_rate - rate;
-
-	if (!best_diff)
-		return best_rate;
+	struct clk *parent = NULL;
+	long best_rate = -EINVAL;
+	unsigned long parent_rate;
+	unsigned long tmp_rate;
+	int shift;
+	int i;
 
-	for (shift = 1; shift < PROG_PRES_MASK; shift++) {
-		cur_rate = *parent_rate >> shift;
+	for (i = 0; i < __clk_get_num_parents(hw->clk); i++) {
+		parent = clk_get_parent_by_index(hw->clk, i);
+		if (!parent)
+			continue;
 
-		if (cur_rate > rate)
-			new_diff = cur_rate - rate;
-		else
-			new_diff = rate - cur_rate;
+		parent_rate = __clk_get_rate(parent);
+		for (shift = 0; shift < PROG_PRES_MASK; shift++) {
+			tmp_rate = parent_rate >> shift;
+			if (tmp_rate <= rate)
+				break;
+		}
 
-		if (!new_diff)
-			return cur_rate;
+		if (tmp_rate > rate)
+			continue;
 
-		if (new_diff < best_diff) {
-			best_diff = new_diff;
-			best_rate = cur_rate;
+		if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) {
+			best_rate = tmp_rate;
+			*best_parent_rate = parent_rate;
+			*best_parent_clk = parent;
 		}
 
-		if (rate > cur_rate)
+		if (!best_rate)
 			break;
 	}
 
@@ -228,7 +228,7 @@ static const struct clk_ops programmable_ops = {
 	.prepare = clk_programmable_prepare,
 	.is_prepared = clk_programmable_is_ready,
 	.recalc_rate = clk_programmable_recalc_rate,
-	.round_rate = clk_programmable_round_rate,
+	.determine_rate = clk_programmable_determine_rate,
 	.get_parent = clk_programmable_get_parent,
 	.set_parent = clk_programmable_set_parent,
 	.set_rate = clk_programmable_set_rate,
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH v2 0/4] clk: at91: better support for the PCKs
From: Jean-Jacques Hiblot @ 2014-02-05  8:37 UTC (permalink / raw)
  To: linux-arm-kernel

This serie implements a better support for the Programmable Clocks.
The first two patch are related to changing the rate of the PCKs.
The 3rd patch is a fix to handle properly the PCKRDY interrupt.
The last patch is a small optimzation/simplification of the determine_rate
algorithm for the PCK.

This has been tested on a 9261ek

Boris BREZILLON (2):
  clk: at91: replace prog clk round_rate with determine_rate
  clk: at91: propagate rate change on system clks

Jean-Jacques Hiblot (2):
  clk: at91: fix programmable clk irq handling
  clk: at91: optimization of the determine_rate callback

 drivers/clk/at91/clk-programmable.c | 202 +++++++++++-------------------------
 drivers/clk/at91/clk-system.c       |  77 ++++++++++++--
 2 files changed, 127 insertions(+), 152 deletions(-)

-- 
1.8.5.2

^ permalink raw reply

* [PATCH v2] ARM: at91: add Atmel's SAMA5D3 Xplained board
From: Nicolas Ferre @ 2014-02-05  8:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140204203054.GA21958@ldesroches-Latitude-E6320>

Add DT file for new SAMA5D3 Xpained board.
This board is based on Atmel's SAMA5D36 Cortex-A5 SoC.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/boot/dts/Makefile                  |   1 +
 arch/arm/boot/dts/at91-sama5d3_xplained.dts | 233 ++++++++++++++++++++++++++++
 2 files changed, 234 insertions(+)
 create mode 100644 arch/arm/boot/dts/at91-sama5d3_xplained.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b9d6a8b485e0..6d1e43d46187 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
 dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
 dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
 # sama5d3
+dtb-$(CONFIG_ARCH_AT91)	+= at91-sama5d3_xplained.dtb
 dtb-$(CONFIG_ARCH_AT91)	+= sama5d31ek.dtb
 dtb-$(CONFIG_ARCH_AT91)	+= sama5d33ek.dtb
 dtb-$(CONFIG_ARCH_AT91)	+= sama5d34ek.dtb
diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
new file mode 100644
index 000000000000..fb1349ca60a4
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
@@ -0,0 +1,233 @@
+/*
+ * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
+ *
+ *  Copyright (C) 2014 Atmel,
+ *		  2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+
+/ {
+	model = "SAMA5D3 Xplained";
+	compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	memory {
+		reg = <0x20000000 0x10000000>;
+	};
+
+	ahb {
+		apb {
+			mmc0: mmc at f0000000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
+				status = "okay";
+				slot at 0 {
+					reg = <0>;
+					bus-width = <8>;
+					cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
+				};
+			};
+
+			spi0: spi at f0004000 {
+				cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+				status = "okay";
+			};
+
+			can0: can at f000c000 {
+				status = "okay";
+			};
+
+			i2c0: i2c at f0014000 {
+				status = "okay";
+			};
+
+			i2c1: i2c at f0018000 {
+				status = "okay";
+			};
+
+			macb0: ethernet at f0028000 {
+				phy-mode = "rgmii";
+				status = "okay";
+			};
+
+			usart0: serial at f001c000 {
+				status = "okay";
+			};
+
+			usart1: serial at f0020000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+				status = "okay";
+			};
+
+			uart0: serial at f0024000 {
+				status = "okay";
+			};
+
+			mmc1: mmc at f8000000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+				status = "okay";
+				slot at 0 {
+					reg = <0>;
+					bus-width = <4>;
+					cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
+				};
+			};
+
+			spi1: spi at f8008000 {
+				cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
+				status = "okay";
+			};
+
+			adc0: adc at f8018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <
+					&pinctrl_adc0_adtrg
+					&pinctrl_adc0_ad0
+					&pinctrl_adc0_ad1
+					&pinctrl_adc0_ad2
+					&pinctrl_adc0_ad3
+					&pinctrl_adc0_ad4
+					&pinctrl_adc0_ad5
+					&pinctrl_adc0_ad6
+					&pinctrl_adc0_ad7
+					&pinctrl_adc0_ad8
+					&pinctrl_adc0_ad9
+					>;
+				status = "okay";
+			};
+
+			i2c2: i2c at f801c000 {
+				dmas = <0>, <0>;	/* Do not use DMA for i2c2 */
+				status = "okay";
+			};
+
+			macb1: ethernet at f802c000 {
+				phy-mode = "rmii";
+				status = "okay";
+			};
+
+			dbgu: serial at ffffee00 {
+				status = "okay";
+			};
+
+			pinctrl at fffff200 {
+				board {
+					pinctrl_mmc0_cd: mmc0_cd {
+						atmel,pins =
+							<AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+					};
+
+					pinctrl_mmc1_cd: mmc1_cd {
+						atmel,pins =
+							<AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+					};
+
+					pinctrl_usba_vbus: usba_vbus {
+						atmel,pins =
+							<AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;	/* PE9, conflicts with A9 */
+					};
+				};
+			};
+
+			pmc: pmc at fffffc00 {
+				main: mainck {
+					clock-frequency = <12000000>;
+				};
+			};
+		};
+
+		nand0: nand at 60000000 {
+			nand-bus-width = <8>;
+			nand-ecc-mode = "hw";
+			atmel,has-pmecc;
+			atmel,pmecc-cap = <4>;
+			atmel,pmecc-sector-size = <512>;
+			nand-on-flash-bbt;
+			status = "okay";
+
+			at91bootstrap at 0 {
+				label = "at91bootstrap";
+				reg = <0x0 0x40000>;
+			};
+
+			bootloader at 40000 {
+				label = "bootloader";
+				reg = <0x40000 0x80000>;
+			};
+
+			bootloaderenv at c0000 {
+				label = "bootloader env";
+				reg = <0xc0000 0xc0000>;
+			};
+
+			dtb at 180000 {
+				label = "device tree";
+				reg = <0x180000 0x80000>;
+			};
+
+			kernel at 200000 {
+				label = "kernel";
+				reg = <0x200000 0x600000>;
+			};
+
+			rootfs at 800000 {
+				label = "rootfs";
+				reg = <0x800000 0x0f800000>;
+			};
+		};
+
+		usb0: gadget at 00500000 {
+			atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>;	/* PE9, conflicts with A9 */
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usba_vbus>;
+			status = "okay";
+		};
+
+		usb1: ohci at 00600000 {
+			num-ports = <3>;
+			atmel,vbus-gpio = <0
+					   &pioE 3 GPIO_ACTIVE_LOW
+					   &pioE 4 GPIO_ACTIVE_LOW
+					  >;
+			status = "okay";
+		};
+
+		usb2: ehci at 00700000 {
+			status = "okay";
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+
+		bp3 {
+			label = "PB_USER";
+			gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
+			linux,code = <0x104>;
+			gpio-key,wakeup;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		d2 {
+			label = "d2";
+			gpios = <&pioE 23 GPIO_ACTIVE_LOW>;	/* PE23, conflicts with A23, CTS2 */
+			linux,default-trigger = "heartbeat";
+		};
+
+		d3 {
+			label = "d3";
+			gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH 1/3] ARM: dts: imx27-phytec-phycard-s-som: Sort entries
From: Sascha Hauer @ 2014-02-05  8:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391525972-15810-1-git-send-email-shc_work@mail.ru>

On Tue, Feb 04, 2014 at 06:59:30PM +0400, Alexander Shiyan wrote:
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>

This series:

Acked-by: Sascha Hauer <s.hauer@pengutronix.de>

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH 0/2] Add Ether's PHY IRQ support for Lager/Koelsh boards
From: Magnus Damm @ 2014-02-05  7:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201402041851.47198.sergei.shtylyov@cogentembedded.com>

Hi Sergei,

On Wed, Feb 5, 2014 at 12:51 AM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Hello.
>
>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
> 'renesas-devel-v3.14-rc1-20130204' tag. Here we add support for the Ether's PHY
> IRQ to the R8A7790/Lager and R8A7791/Koelsch boards.
>
> [1/2] ARM: shmobile: Lager: pass Ether PHY IRQ
> [1/2] ARM: shmobile: Koelsch: pass Ether PHY IRQ

Thanks, looking good!

/ magnus

^ permalink raw reply

* [GIT PULL] tree-wide: clean up no longer required #include <linux/init.h>
From: Ingo Molnar @ 2014-02-05  6:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140205172723.3fa841793b3fa3f3f534937f@canb.auug.org.au>


* Stephen Rothwell <sfr@canb.auug.org.au> wrote:

> Hi Ingo,
> 
> On Wed, 5 Feb 2014 07:06:33 +0100 Ingo Molnar <mingo@kernel.org> wrote:
> > 
> > So, if you meant Linus to pull it, you probably want to cite a real 
> > Git URI along the lines of:
> > 
> >    git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git
> 
> Paul provided the proper git url further down in the mail along with the
> usual pull request message (I guess he should have put that bit at the
> top).

Yeah, indeed, and it even comes with a signed tag, which is an extra 
nice touch:

  git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux.git tags/init-cleanup

(I guess the https was mentioned first to lower expectations.)

Thanks,

	Ingo

^ permalink raw reply

* [GIT PULL] tree-wide: clean up no longer required #include <linux/init.h>
From: Stephen Rothwell @ 2014-02-05  6:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140205060633.GE30094@gmail.com>

Hi Ingo,

On Wed, 5 Feb 2014 07:06:33 +0100 Ingo Molnar <mingo@kernel.org> wrote:
> 
> So, if you meant Linus to pull it, you probably want to cite a real 
> Git URI along the lines of:
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git

Paul provided the proper git url further down in the mail along with the
usual pull request message (I guess he should have put that bit at the
top).

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140205/99085ec1/attachment.sig>

^ permalink raw reply

* [RFC/PATCH] ARM: dove: Remove UBI support from defconfig
From: Jason Cooper @ 2014-02-05  6:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390829189-25073-1-git-send-email-ezequiel.garcia@free-electrons.com>

On Mon, Jan 27, 2014 at 10:26:29AM -0300, Ezequiel Garcia wrote:
> As NAND support is not enabled by default, it's hard to see
> why we'd want to have UBI support. Let's remove it.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> ---
>  arch/arm/configs/dove_defconfig | 1 -
>  1 file changed, 1 deletion(-)

Added to mvebu/defconfig

thx,

Jason.

^ permalink raw reply

* [PATCH] ARCH: mvebu: Makefile clean-up
From: Jason Cooper @ 2014-02-05  6:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1388763487-28436-1-git-send-email-gregory.clement@free-electrons.com>

On Fri, Jan 03, 2014 at 04:38:07PM +0100, Gregory CLEMENT wrote:
> Some objects depend on CONFIG_ARCH_MVEBU whereas this whole Makefile
> depends on the same symbol. Moreover CONFIG_ARCH_MVEBU can't be
> selected as a module. So we can simplify this Makefile by moving all
> the object from obj-$(CONFIG_ARCH_MVEBU) to obj-y.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> Jason,
> 
> This patch is just a cosmetic one and it will conflict with the patch
> fix I have just sent, but the conflict is trivial and I can resubmit
> it as soon as the fix will be part of the 3.13-rc. If it is too late
> for 3.14, just postpone it for 3.15.
> 
> Thanks,
> 
> Gregory
> 
>  arch/arm/mach-mvebu/Makefile | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Applied to mvebu/soc with s/ARCH/ARM/ and minor conflict resolution for
mvebu-soc-id.o.

thx,

Jason.

^ permalink raw reply

* [PATCH 0/9] Samsung clock PM consolidation part 1
From: Tomasz Figa @ 2014-02-05  6:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPdUM4OHCEgy4Y8An9j8t3sQ6RjzMdSEdOnqrZNuAwrWGZN7Nw@mail.gmail.com>

Hi Rahul,

On 05.02.2014 05:45, Rahul Sharma wrote:
> Hi Tomasz,
>
> Are you planning to respin this series? It is not applying on mike's for-next.

Yes, I have already rebased it and was planning to resend it later today 
or tomorrow after checking one more thing.

Best regards,
Tomasz

^ permalink raw reply

* [GIT PULL] tree-wide: clean up no longer required #include <linux/init.h>
From: Ingo Molnar @ 2014-02-05  6:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAP=VYLp+zus5591g-1YQBCJifbk+UY59yJ7rV06ZN3QhhdnK7w@mail.gmail.com>


* Paul Gortmaker <paul.gortmaker@windriver.com> wrote:

> On Feb 4, 2014 3:52 PM, "Paul Gortmaker" <paul.gortmaker@windriver.com>
> wrote:
> >
> > We've had this in linux-next for 2+ weeks (thanks Stephen!) as a
> > linux-stable like queue of patches, and as can be seen here:
> >
> >   https://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git
> 
> Argh, above link is meant for cloning, not viewing.
> 
> This should be better...
> 
> https://git.kernel.org/cgit/linux/kernel/git/paulg/init.git/

So, if you meant Linus to pull it, you probably want to cite a real 
Git URI along the lines of:

   git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git

( Otherwise your pull request might be ignored or worse, you might get
  an honest reply, due to the https transport being considered evil
  that no free man outside of corporate firewalls should ever consider
  and all that. )

Nice cleanups btw.

Thanks,

	Ingo

^ permalink raw reply

* [PATCH v2 1/2] arm64: vdso: fix coarse clock handling
From: Nathan Lynch @ 2014-02-05  5:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391456932-17815-2-git-send-email-nathan_lynch@mentor.com>

When __kernel_clock_gettime is called with a CLOCK_MONOTONIC_COARSE or
CLOCK_REALTIME_COARSE clock id, it returns incorrectly to whatever the
caller has placed in x2 ("ret x2" to return from the fast path).  Fix
this by saving x30/LR to x2 only in code that will call
__do_get_tspec, restoring x30 afterward, and using a plain "ret" to
return from the routine.

Also: while the resulting tv_nsec value for CLOCK_REALTIME and
CLOCK_MONOTONIC must be computed using intermediate values that are
left-shifted by cs_shift (x12, set by __do_get_tspec), the results for
coarse clocks should be calculated using unshifted values
(xtime_coarse_nsec is in units of actual nanoseconds).  The current
code shifts intermediate values by x12 unconditionally, but x12 is
uninitialized when servicing a coarse clock.  Fix this by setting x12
to 0 once we know we are dealing with a coarse clock id.

Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
---

Changes from v1:
- Save x30/lr only when branching to __do_get_tspec, and restore it
  afterward.  Use plain "ret" to return instead of "ret x2".
- Better explanation for setting x12 (shift) to zero.

 arch/arm64/kernel/vdso/gettimeofday.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index f0a6d10b5211..fe652ffd34c2 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -103,6 +103,8 @@ ENTRY(__kernel_clock_gettime)
 	bl	__do_get_tspec
 	seqcnt_check w9, 1b
 
+	mov	x30, x2
+
 	cmp	w0, #CLOCK_MONOTONIC
 	b.ne	6f
 
@@ -118,6 +120,9 @@ ENTRY(__kernel_clock_gettime)
 	ccmp	w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
 	b.ne	8f
 
+	/* xtime_coarse_nsec is already right-shifted */
+	mov	x12, #0
+
 	/* Get coarse timespec. */
 	adr	vdso_data, _vdso_data
 3:	seqcnt_acquire
@@ -156,7 +161,7 @@ ENTRY(__kernel_clock_gettime)
 	lsr	x11, x11, x12
 	stp	x10, x11, [x1, #TSPEC_TV_SEC]
 	mov	x0, xzr
-	ret	x2
+	ret
 7:
 	mov	x30, x2
 8:	/* Syscall fallback. */
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH 1/2] arm64: vdso: fix coarse clock handling
From: Nathan Lynch @ 2014-02-05  5:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140204182631.GI664@mudshark.cambridge.arm.com>

Hi Will,

On 02/04/2014 12:26 PM, Will Deacon wrote:
> 
> On Mon, Feb 03, 2014 at 07:48:51PM +0000, Nathan Lynch wrote:
>> When __kernel_clock_gettime is called with a CLOCK_MONOTONIC_COARSE or
>> CLOCK_REALTIME_COARSE clock id, it returns incorrectly to whatever the
>> caller has placed in x2.  Fix this by saving x30/LR to x2
>> unconditionally.
>>
>> Also: the tv_nsec field in the result is shifted by the value in x12.
>> In the high-precision case x12 is cs_shift from the data page, but
>> for coarse clocks x12 is uninitialized.  Fix this by setting x12 to 0
>> once we know we are dealing with a coarse clock.
> 
> How are you managing to see these failures? It's clear that our LTP testing
> isn't hitting this path...

I'm using a custom test program that I wrote to check the vdso
implementation I've been working on for 32-bit ARM.  Briefly looking
through LTP sources it's not apparent to me that it tests
clock_gettime() with the coarse ids.


> 
>> Signed-off-by: Nathan Lynch <nathan_lynch@mentor.com>
>> ---
>>  arch/arm64/kernel/vdso/gettimeofday.S | 9 ++++++---
>>  1 file changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
>> index f0a6d10b5211..6c37ae4a70c0 100644
>> --- a/arch/arm64/kernel/vdso/gettimeofday.S
>> +++ b/arch/arm64/kernel/vdso/gettimeofday.S
>> @@ -88,13 +88,13 @@ ENDPROC(__kernel_gettimeofday)
>>  /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
>>  ENTRY(__kernel_clock_gettime)
>>  	.cfi_startproc
>> +	mov	x2, x30
>> +	.cfi_register x30, x2
>> +
>>  	cmp	w0, #CLOCK_REALTIME
>>  	ccmp	w0, #CLOCK_MONOTONIC, #0x4, ne
>>  	b.ne	2f
>>  
>> -	mov	x2, x30
>> -	.cfi_register x30, x2
>> -
> 
> Could we avoid the redundant moves by instead doing this around the bl
> __do_get_tspec?

In v2 I've restored x30 upon returning from __do_get_tspec and adjusted
the return from __kernel_clock_gettime accordingly.  Let me know if you
were suggesting something different here.


> 
>>  	/* Get kernel timespec. */
>>  	adr	vdso_data, _vdso_data
>>  1:	seqcnt_acquire
>> @@ -118,6 +118,9 @@ ENTRY(__kernel_clock_gettime)
>>  	ccmp	w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne
>>  	b.ne	8f
>>  
>> +	/* Set shift to 0 for coarse clocks */
>> +	mov	x12, #0
> 
> Worth mentioning that xtime_coarse_nsec is pre-shifted for us, rather than
> shifting not actually being required.

Agreed.


> Also, rather than shift by #0, can we move the lsl instruction immediately
> before the b 4f earlier on?

There are two more shift operations later in the routine which would
also need accounting for, so it's not quite that simple.  Okay to leave
this alone for the purpose of this patch?

^ permalink raw reply

* [PATCH] ARM: shmobile: Use 64-bit dma_addr_t on r8a7790/r8a7791
From: Magnus Damm @ 2014-02-05  5:36 UTC (permalink / raw)
  To: linux-arm-kernel

From: Magnus Damm <damm@opensource.se>

Some on-chip devices on r8a7790 and r8a7791 can do
bus mastering and access more than 32-bits of address
space. Select ARCH_DMA_ADDR_T_64BIT when LPAE is set
in case of multiplatform and legacy SoC support.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/Kconfig |    3 +++
 1 file changed, 3 insertions(+)

--- 0001/arch/arm/mach-shmobile/Kconfig
+++ work/arch/arm/mach-shmobile/Kconfig	2014-02-04 17:04:53.000000000 +0900
@@ -13,6 +13,7 @@ config ARCH_SHMOBILE_MULTI
 	select ARM_GIC
 	select MIGHT_HAVE_CACHE_L2X0
 	select MIGHT_HAVE_PCI
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 	select NO_IOPORT
 	select PINCTRL
 	select ARCH_REQUIRE_GPIOLIB
@@ -126,6 +127,7 @@ config ARCH_R8A7790
 	select MIGHT_HAVE_PCI
 	select SH_CLK_CPG
 	select RENESAS_IRQC
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 
 config ARCH_R8A7791
 	bool "R-Car M2 (R8A77910)"
@@ -135,6 +137,7 @@ config ARCH_R8A7791
 	select MIGHT_HAVE_PCI
 	select SH_CLK_CPG
 	select RENESAS_IRQC
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 
 config ARCH_EMEV2
 	bool "Emma Mobile EV2"

^ permalink raw reply

* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Jason Cooper @ 2014-02-05  5:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391554766-11285-1-git-send-email-gregory.clement@free-electrons.com>

Mike,

On Tue, Feb 04, 2014 at 11:59:26PM +0100, Gregory CLEMENT wrote:
> Until now the clock providers were initialized in the order found in
> the device tree. This led to have the dependencies between the clocks
> not respected: children clocks could be initialized before their
> parent clocks.
> 
> Instead of forcing each platform to manage its own initialization order,
> this patch adds this work inside the framework itself.
> 
> Using the data of the device tree the of_clk_init function now delayed
> the initialization of a clock provider if its parent provider was not
> ready yet.
> 
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> Mike,
> 
> this patch could solve the issues we get on severals mvebu platform
> since 3.14-rc1. This is an alternate solution of the patch set sent by
> Sebastian. However as it modifies the clock framework itself, it is
> more sensible.
> 
> I find this solution more elegant than changing the order of the
> initialization of the clock at the platform level. However as it
> should be tested on more platforms that only the mvebu ones, it would
> take some time, and I don't want to still have "broken" platform
> during more release candidate. So at the end this patch should be part
> of the 3.15 kernel.

If we can get a response from Mike, I'd prefer to go with this approach
and let it bake in -next for a while.  Hopefully, we could get it in
before -rc4...

thx,

Jason.

>  drivers/clk/clk.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 91 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 5517944495d8..beb0f8b0c2a0 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2526,24 +2526,112 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
>  }
>  EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
>  
> +struct clock_provider {
> +	of_clk_init_cb_t clk_init_cb;
> +	struct device_node *np;
> +	struct list_head node;
> +};
> +
> +static LIST_HEAD(clk_provider_list);
> +
> +/*
> + * This function looks for a parent clock. If there is one, then it
> + * checks that the provider for this parent clock was initialized, in
> + * this case the parent clock will be ready.
> + */
> +static int parent_ready(struct device_node *np)
> +{
> +	struct of_phandle_args clkspec;
> +	struct of_clk_provider *provider;
> +
> +	/*
> +	 * If there is no clock parent, no need to wait for them, then
> +	 * we can consider their absence as being ready
> +	 */
> +	if (of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
> +					&clkspec))
> +		return 1;
> +
> +	/* Check if we have such a provider in our array */
> +	list_for_each_entry(provider, &of_clk_providers, link) {
> +		if (provider->node == clkspec.np)
> +			return 1;
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * of_clk_init() - Scan and init clock providers from the DT
>   * @matches: array of compatible values and init functions for providers.
>   *
> - * This function scans the device tree for matching clock providers and
> - * calls their initialization functions
> + * This function scans the device tree for matching clock providers
> + * and calls their initialization functions. It also do it by trying
> + * to follow the dependencies.
>   */
>  void __init of_clk_init(const struct of_device_id *matches)
>  {
>  	const struct of_device_id *match;
>  	struct device_node *np;
> +	struct clock_provider *clk_provider, *next;
> +	bool is_init_done;
>  
>  	if (!matches)
>  		matches = &__clk_of_table;
>  
>  	for_each_matching_node_and_match(np, matches, &match) {
>  		of_clk_init_cb_t clk_init_cb = match->data;
> -		clk_init_cb(np);
> +
> +
> +		if (parent_ready(np)) {
> +			/*
> +			 * The parent clock is ready or there is no
> +			 * clock parent at all, in this case the
> +			 * provider can be initialize immediately.
> +			 */
> +			clk_init_cb(np);
> +		} else {
> +			/*
> +			 * The parent clock is not ready, this
> +			 * provider is moved to a list to be
> +			 * initialized later
> +			 */
> +			struct clock_provider *parent = kzalloc(sizeof(struct clock_provider),
> +							GFP_KERNEL);
> +
> +			parent->clk_init_cb = match->data;
> +			parent->np = np;
> +			list_add(&parent->node, &clk_provider_list);
> +		}
> +	}
> +
> +	while (!list_empty(&clk_provider_list)) {
> +		is_init_done = false;
> +		list_for_each_entry_safe(clk_provider, next,
> +					&clk_provider_list, node) {
> +			if (parent_ready(clk_provider->np)) {
> +				clk_provider->clk_init_cb(clk_provider->np);
> +				list_del(&clk_provider->node);
> +				kfree(clk_provider);
> +				is_init_done = true;
> +			}
> +		}
> +
> +		if (!is_init_done) {
> +			/*
> +			 * We didn't managed to initialize any of the
> +			 * remaining providers during the last loop,
> +			 * so now we initialize all the remaining ones
> +			 * unconditionally in case the clock parent
> +			 * was not mandatory
> +			 */
> +			list_for_each_entry_safe(clk_provider, next,
> +						&clk_provider_list, node) {
> +				clk_provider->clk_init_cb(clk_provider->np);
> +				list_del(&clk_provider->node);
> +				kfree(clk_provider);
> +			}
> +		}
>  	}
>  }
>  #endif
> -- 
> 1.8.1.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] backlight: add PWM dependencies
From: Jingoo Han @ 2014-02-05  5:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391518634-6472-1-git-send-email-linus.walleij@linaro.org>

On Tuesday, February 04, 2014 9:57 PM, Linus Walleij wrote:
> 
> In some compilations the LM3630A and LP855X backlight drivers
> fail like this:
> 
> drivers/built-in.o: In function `lm3630a_pwm_ctrl':
> drivers/video/backlight/lm3630a_bl.c:168: undefined reference to `pwm_config'
> drivers/video/backlight/lm3630a_bl.c:172: undefined reference to `pwm_disable'
> drivers/video/backlight/lm3630a_bl.c:170: undefined reference to `pwm_enable'
> drivers/built-in.o: In function `lp855x_pwm_ctrl':
> drivers/video/backlight/lp855x_bl.c:249: undefined reference to `pwm_config'
> drivers/video/backlight/lp855x_bl.c:253: undefined reference to `pwm_disable'
> drivers/video/backlight/lp855x_bl.c:251: undefined reference to `pwm_enable'
> 
> This is because both drivers depend on the PWM framework, so
> add this dependency to their Kconfig entries.

However, even though, when CONFIG_PWM is not enabled, the problem
should not happen. pwm_config(),pwm_disable(), and pwm_enable()
are already defined for CONFIG_PWM=n case as below.

./include/linux/pwm.h
#if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
	.....
#else
static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
{
        return ERR_PTR(-ENODEV);
}

static inline void pwm_free(struct pwm_device *pwm)
{
}

static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
{
        return -EINVAL;
}

static inline int pwm_enable(struct pwm_device *pwm)
{
        return -EINVAL;
}

static inline void pwm_disable(struct pwm_device *pwm)
{
}
#endif

Is there 'drivers/pwm/core.o'?
I reproduced this problem by commenting core.o with CONFIG_PWM=y.

.config
CONFIG_PWM=y

./drivers/pwm/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_PWM)              += core.o
+#obj-$(CONFIG_PWM)             += core.o

In this case, the following build errors happen.
Even though, CONFIG_PWM is enabled, the same errors happen.
Would you give me the more detailed information?
Ex. how to reproduce the problem.

drivers/built-in.o: In function `lm3630a_pwm_ctrl':
drivers/video/backlight/lm3630a_bl.c:168: undefined reference to `pwm_config'
drivers/video/backlight/lm3630a_bl.c:172: undefined reference to `pwm_disable'
drivers/video/backlight/lm3630a_bl.c:170: undefined reference to `pwm_enable'
drivers/built-in.o: In function `lm3630a_probe':
drivers/video/backlight/lm3630a_bl.c:422: undefined reference to `devm_pwm_get'
drivers/built-in.o: In function `lp855x_pwm_ctrl':
drivers/video/backlight/lp855x_bl.c:249: undefined reference to `pwm_config'
drivers/video/backlight/lp855x_bl.c:253: undefined reference to `pwm_disable'
drivers/video/backlight/lp855x_bl.c:251: undefined reference to `pwm_enable'
drivers/video/backlight/lp855x_bl.c:242: undefined reference to `devm_pwm_get'

Thank you.

Best regards,
Jingoo Han

> 
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  drivers/video/backlight/Kconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
> index 5a3eb2ecb525..0604c3348761 100644
> --- a/drivers/video/backlight/Kconfig
> +++ b/drivers/video/backlight/Kconfig
> @@ -371,6 +371,7 @@ config BACKLIGHT_AAT2870
>  config BACKLIGHT_LM3630A
>  	tristate "Backlight Driver for LM3630A"
>  	depends on BACKLIGHT_CLASS_DEVICE && I2C
> +	depends on PWM
>  	select REGMAP_I2C
>  	help
>  	  This supports TI LM3630A Backlight Driver
> @@ -387,6 +388,7 @@ config BACKLIGHT_LM3639
>  config BACKLIGHT_LP855X
>  	tristate "Backlight driver for TI LP855X"
>  	depends on BACKLIGHT_CLASS_DEVICE && I2C
> +	depends on PWM
>  	help
>  	  This supports TI LP8550, LP8551, LP8552, LP8553, LP8555, LP8556 and
>  	  LP8557 backlight driver.
> --
> 1.8.5.3

^ permalink raw reply

* [PATCH 0/3] irqchip: orion: bridge irq fixes for v3.14-rc1
From: Jason Cooper @ 2014-02-05  4:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390516686-2224-1-git-send-email-sebastian.hesselbarth@gmail.com>

On Thu, Jan 23, 2014 at 11:38:03PM +0100, Sebastian Hesselbarth wrote:
> This is a small patch set to fix some shortcomings how Orion bridge
> irqs are handled. The patches are based on v3.13-rc8 and should go
> into v3.14. They can possibly also marked for -stable down to v3.10.
> 
> This patches are the result of a discussion about a stale watchdog irq,
> that can accidentially trigger the watchdog's irq handler and cause a
> reset [1].
> 
> The first patch will add a write to clear already pending interrupts
> on init. The second patch replaces handle_level_irq with handle_edge_irq
> which is more appropriate for bridge irqs which are edge-triggered.
> The last patch finally, fixes stale interrupts by installing an
> .irq_enable callback, that will clear a possible pending interrupt
> before unmasking it.
> 
> [1] http://www.spinics.net/lists/arm-kernel/msg302106.html
> 
> Sebastian Hesselbarth (3):
>   irqchip: orion: clear bridge cause register on init
>   irqchip: orion: use handle_edge_irq on bridge irqs
>   irqchip: orion: clear stale interrupts in irq_enable
> 
>  drivers/irqchip/irq-orion.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)

Whole series applied to mvebu-next/irqchip-fixes (v2 for 3/3).  Once I
see that the outstanding pull requests for mvebu/irqchip have been
merged into mainline, I'll be changing the name of this branch to
mvebu/irqchip-fixes.  I just don't want to upset the applecart atm.

Oh yeah, Cc'd for stable back to v3.10.

thx,

Jason.

^ permalink raw reply

* [PATCH 0/9] Samsung clock PM consolidation part 1
From: Rahul Sharma @ 2014-02-05  4:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1381921698-5060-1-git-send-email-t.figa@samsung.com>

Hi Tomasz,

Are you planning to respin this series? It is not applying on mike's for-next.

Regards,
Rahul Sharma.


On 16 October 2013 16:38, Tomasz Figa <t.figa@samsung.com> wrote:
> This series reworks suspend/resume handling of Samsung clock drivers
> to cover more SoC specific aspects that are beyond simple register
> save and restore. The goal is to have all the suspend/resume code
> that touches the clock controller in single place, which is the
> clock driver.
>
> On Exynos4210-based Trats, Exynos4412-based Trats2 and Exynos5250-based
> Arndale boards (except suspend/resume, which is broken because of
> unrelated reasons):
>
> Tested-by: Tomasz Figa <t.figa@samsung.com>
>
> Tomasz Figa (9):
>   clk: exynos4: Remove remnants of non-DT support
>   clk: samsung: Provide common helpers for register save/restore
>   clk: samsung: exynos4: Move suspend/resume handling to SoC driver
>   clk: samsung: exynos5250: Move suspend/resume handling to SoC driver
>   clk: samsung: exynos5420: Move suspend/resume handling to SoC driver
>   clk: samsung: s3c64xx: Move suspend/resume handling to SoC driver
>   clk: samsung: Drop old suspend/resume code
>   clk: samsung: exynos4: Add remaining suspend/resume handling
>   ARM: EXYNOS: pm: Drop legacy Exynos4 clock suspend/resume code
>
>  arch/arm/mach-exynos/pm.c            | 125 +-------------------------
>  drivers/clk/samsung/clk-exynos4.c    | 170 ++++++++++++++++++++++++++++++-----
>  drivers/clk/samsung/clk-exynos5250.c |  49 ++++++++--
>  drivers/clk/samsung/clk-exynos5420.c |  49 ++++++++--
>  drivers/clk/samsung/clk-exynos5440.c |   2 +-
>  drivers/clk/samsung/clk-s3c64xx.c    |  79 +++++++++++++---
>  drivers/clk/samsung/clk.c            |  71 ++++++---------
>  drivers/clk/samsung/clk.h            |  14 ++-
>  8 files changed, 346 insertions(+), 213 deletions(-)
>
> --
> 1.8.3.2
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v3 8/8] ARM: dts: sun7i: Add ethernet alias for GMAC
From: Chen-Yu Tsai @ 2014-02-05  4:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140203193802.GE25625@lukather>

On Tue, Feb 4, 2014 at 3:38 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Mon, Feb 03, 2014 at 11:32:26AM +0800, Chen-Yu Tsai wrote:
>> U-Boot will insert MAC address into the device tree image.
>> It looks up ethernet[0-5] aliases to find the ethernet nodes.
>> Alias GMAC as ethernet0, as it is the only ethernet controller used.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>>  arch/arm/boot/dts/sun7i-a20.dtsi | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
>> index 65fb8d0..c48fb11 100644
>> --- a/arch/arm/boot/dts/sun7i-a20.dtsi
>> +++ b/arch/arm/boot/dts/sun7i-a20.dtsi
>> @@ -17,7 +17,7 @@
>>       interrupt-parent = <&gic>;
>>
>>       aliases {
>> -             ethernet0 = &emac;
>> +             ethernet0 = &gmac;
>>       };
>
> I'm not very fond of this patch.
>
> People might rely on the fact that ethernet0 is actually the emac, and
> are expecting u-boot to fill the ethaddr variable to the emac, and not
> the gmac.
>
> Since u-boot is totally able to deal with several ethernet addresses,
> please add it as ethernet1.

Actually I think we should override this in the board dts.
The boards we currently support can only use emac or gmac,
and in our u-boot tree, they have been converted to using
gmac. If any future boards support both emac and gmac, we
can address the ordering then. And the ordering should
match u-boot.

What do you think?


Cheers
ChenYu

^ permalink raw reply

* [PATCH] mvebu : pcie: dt: potential issue in range parsing
From: Jason Cooper @ 2014-02-05  4:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389349431-7997-1-git-send-email-jjhiblot@traphandler.com>

Jean-Jacques,

On Fri, Jan 10, 2014 at 11:23:51AM +0100, Jean-Jacques Hiblot wrote:
> The second parameter of of_read_number is not the index, but a size.
> As it happens, in this case it may work just fine because of the the conversion
> to u32 and the favorable endianness on this architecture.
> 
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
>  drivers/pci/host/pci-mvebu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Sorry for the unusually long delay.  I was waiting for Thomas to get
back from vacation since he is intimately familiar with this driver.

Thomas?

thx,

Jason.

> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> index c269e43..877e8ce 100644
> --- a/drivers/pci/host/pci-mvebu.c
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -768,7 +768,7 @@ static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
>  
>  	for (i = 0; i < nranges; i++) {
>  		u32 flags = of_read_number(range, 1);
> -		u32 slot = of_read_number(range, 2);
> +		u32 slot = of_read_number(range + 1, 1);
>  		u64 cpuaddr = of_read_number(range + na, pna);
>  		unsigned long rtype;
>  
> -- 
> 1.8.5.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* arm64: kernel panic in paging_init()
From: Mark Salter @ 2014-02-05  2:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <34F26939-E85D-44DF-8E38-7B4AA4BF1A61@arm.com>

On Tue, 2014-02-04 at 22:39 +0000, Catalin Marinas wrote:
> On 4 Feb 2014, at 18:57, Mark Salter <msalter@redhat.com> wrote:
> > On Tue, 2014-02-04 at 12:14 +0000, Catalin Marinas wrote:
> >> On Mon, Feb 03, 2014 at 08:50:49PM +0000, Mark Salter wrote:
> >>> I'm seeing the following panic in paging init. This is on the foundation
> >>> model with a modified dtb memory node which has a non section-aligned
> >>> bank:
> >>> 	memory at 80000000 {
> >>> 		device_type = "memory";
> >>> 		reg = <0x00000000 0x80000000 0 0x20000000>,
> >>> 		      <0x00000000 0xa0300000 0 0x1fd00000>;
> >>> 	};
> >>> 
> >>> I only see this with 64k pagesize configured. What happens is the
> >>> non section-aligned bank causes alloc_init_pte() to allocate a page
> >>> for the new pte from the end of the first bank (the failing address
> >>> 0xfffffe001fff0000 [0x9fff0000 phys]). This should be a valid page
> >>> since it was mapped during the create_mapping() call for the first
> >>> memory bank. A flush_tlb_all() added to the end of create_mapping()
> >>> makes the panic go away so I think the problem is something stale
> >>> cached before the page with the failing address was mapped.
> >> 
> >> I think it goes like this:
> >> 
> >> head.S maps enough memory to get started but using 64K pages rather than
> >> 512M sections with a single pgd entry and several ptes. This never gets
> >> to the end of the first block (just up to KERNEL_END).
> >> 
> >> create_mapping() realises it can do a 512M section mapping, overriding
> >> the original table pgd entry with a block one. The memblock limit is set
> >> correctly PGDIR_SIZE but create_mapping, when it replaces the table pgd
> >> with a block one doesn't do any TLB invalidation.
> >> 
> >> So I wouldn't do a TLB invalidation all the time but only when the old
> >> pmd was set. Please give the patch below a try, I only compiled it (I'll
> >> add some text afterwards):
> > 
> > Yes, that works. Thanks.
> 
> Can I add your tested-by?

Yes, you may.

^ permalink raw reply


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