Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: davinci: da850: add interrupt-parent property in soc node
From: Prabhakar Lad @ 2013-01-28 16:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <51069A3A.8090404@ti.com>

Sekhar,

On Mon, Jan 28, 2013 at 9:03 PM, Sekhar Nori <nsekhar@ti.com> wrote:
> On 1/25/2013 4:48 PM, Prabhakar Lad wrote:
>> From: Lad, Prabhakar <prabhakar.lad@ti.com>
>>
>> This patch adds 'interrupt-parent' property in soc node, so that
>> the child inherits this property, this avoids adding 'interrupt-parent'
>> to each node.
>>
>> Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: davinci-linux-open-source at linux.davincidsp.com
>> Cc: devicetree-discuss at lists.ozlabs.org
>> Cc: Sekhar Nori <nsekhar@ti.com>
>> Cc: Heiko Schocher <hs@denx.de>
>> ---
>
> Looks good to me. Queuing for v3.9. BTW, we are moving the interrupt
> parent property to soc node rather than adding it. So, I think a better
> headline is "move interrupt-parent property to soc node". I change the
> headline while committing.
>
Thanks for fixing it.

Regards,
--Prabhakar

> Thanks,
> Sekhar

^ permalink raw reply

* [PATCH 0/4 v12] cpufreq: add support for Calxeda ECX-1000 (highbank)
From: Mark Langsdorf @ 2013-01-28 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351631056-25938-1-git-send-email-mark.langsdorf@calxeda.com>

This patch series adds cpufreq support for the Calxeda
ECX-1000 (highbank) SoCs. The EnergyCore Management Engine (ECME) on
the ECX-1000 manages the voltage for the part and communications with
Linux through a pl320 mailbox. clk notifications are used to control
when to send messages to the ECME.

Previous versions of this patch set include two other patches. One has
been dropped as unworkable and the other turned out to be unnecessary.

--Mark Langsdorf
Calxeda, Inc.

^ permalink raw reply

* [PATCH 1/4 v12] arm: use device tree to get smp_twd clock
From: Mark Langsdorf @ 2013-01-28 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359389595-26580-1-git-send-email-mark.langsdorf@calxeda.com>

From: Rob Herring <rob.herring@calxeda.com>

Move clk setup to twd_local_timer_common_register and rely on
twd_timer_rate being 0 to force calibration if there is no clock.
Remove common_setup_called as it is no longer needed.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
Changes from v11
	Added Russell King's acked-by.
Changes from v10
        Reworked to simplify the logic as suggested by Russell King.
Changes from v9
        Updated to work with 3.8 kernel.
Changes from v4, v5, v6, v7, v8
        None.
Changes from v3
        No longer setting *clk to NULL in twd_get_clock().
Changes from v2
        Turned the check for the node pointer into an if-then-else statement.
        Removed the second, redundant clk_get_rate.
Changes from v1
        None.

 arch/arm/kernel/smp_twd.c | 53 +++++++++++++++++------------------------------
 1 file changed, 19 insertions(+), 34 deletions(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 49f335d..ae0c7bb 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -31,7 +31,6 @@ static void __iomem *twd_base;
 
 static struct clk *twd_clk;
 static unsigned long twd_timer_rate;
-static bool common_setup_called;
 static DEFINE_PER_CPU(bool, percpu_setup_called);
 
 static struct clock_event_device __percpu **twd_evt;
@@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
 	return IRQ_NONE;
 }
 
-static struct clk *twd_get_clock(void)
+static void twd_get_clock(struct device_node *np)
 {
-	struct clk *clk;
 	int err;
 
-	clk = clk_get_sys("smp_twd", NULL);
-	if (IS_ERR(clk)) {
-		pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
-		return clk;
+	if (np)
+		twd_clk = of_clk_get(np, 0);
+	else
+		twd_clk = clk_get_sys("smp_twd", NULL);
+
+	if (IS_ERR(twd_clk)) {
+		pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
+		return;
 	}
 
-	err = clk_prepare_enable(clk);
+	err = clk_prepare_enable(twd_clk);
 	if (err) {
 		pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
-		clk_put(clk);
-		return ERR_PTR(err);
+		clk_put(twd_clk);
+		return;
 	}
 
-	return clk;
+	twd_timer_rate = clk_get_rate(twd_clk);
 }
 
 /*
@@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
 	}
 	per_cpu(percpu_setup_called, cpu) = true;
 
-	/*
-	 * This stuff only need to be done once for the entire TWD cluster
-	 * during the runtime of the system.
-	 */
-	if (!common_setup_called) {
-		twd_clk = twd_get_clock();
-
-		/*
-		 * We use IS_ERR_OR_NULL() here, because if the clock stubs
-		 * are active we will get a valid clk reference which is
-		 * however NULL and will return the rate 0. In that case we
-		 * need to calibrate the rate instead.
-		 */
-		if (!IS_ERR_OR_NULL(twd_clk))
-			twd_timer_rate = clk_get_rate(twd_clk);
-		else
-			twd_calibrate_rate();
-
-		common_setup_called = true;
-	}
+	twd_calibrate_rate();
 
 	/*
 	 * The following is done once per CPU the first time .setup() is
@@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
 	.stop	= twd_timer_stop,
 };
 
-static int __init twd_local_timer_common_register(void)
+static int __init twd_local_timer_common_register(struct device_node *np)
 {
 	int err;
 
@@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void)
 	if (err)
 		goto out_irq;
 
+	twd_get_clock(np);
+
 	return 0;
 
 out_irq:
@@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
 	if (!twd_base)
 		return -ENOMEM;
 
-	return twd_local_timer_common_register();
+	return twd_local_timer_common_register(NULL);
 }
 
 #ifdef CONFIG_OF
@@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void)
 		goto out;
 	}
 
-	err = twd_local_timer_common_register();
+	err = twd_local_timer_common_register(np);
 
 out:
 	WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH 2/4 v12] clk, highbank: Prevent glitches in non-bypass reset mode
From: Mark Langsdorf @ 2013-01-28 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359389595-26580-1-git-send-email-mark.langsdorf@calxeda.com>

The highbank clock will glitch with the current code if the
clock rate is reset without relocking the PLL. Program the PLL
correctly to prevent glitches.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Mike Turquette <mturquette@linaro.org>
---
Changes from v6, v7, v8, v9, v10, v11
        None.
Changes from v5
        Added Mike Turquette's ack.
Changes from v4
        None.
Changes from v3
        Changelog text and patch name now correspond to the actual patch.
        was clk, highbank: remove non-bypass reset mode.
Changes from v2
        None.
Changes from v1
        Removed erroneous reformating.

 drivers/clk/clk-highbank.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c
index 52fecad..3a0b723 100644
--- a/drivers/clk/clk-highbank.c
+++ b/drivers/clk/clk-highbank.c
@@ -182,8 +182,10 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate,
 		reg |= HB_PLL_EXT_ENA;
 		reg &= ~HB_PLL_EXT_BYPASS;
 	} else {
+		writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
 		reg &= ~HB_PLL_DIVQ_MASK;
 		reg |= divq << HB_PLL_DIVQ_SHIFT;
+		writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
 	}
 	writel(reg, hbclk->reg);
 
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH 3/4 v12] arm highbank: add support for pl320 IPC
From: Mark Langsdorf @ 2013-01-28 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359389595-26580-1-git-send-email-mark.langsdorf@calxeda.com>

From: Rob Herring <rob.herring@calxeda.com>

The pl320 IPC allows for interprocessor communication between the 
highbank A9 and the EnergyCore Management Engine. The pl320 implements 
a straightforward mailbox protocol.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Omar Ramirez Luna <omar.luna@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
Changes from v11
	EXPORT_SYMBOL_GPL used instead of EXPORT_SYMBOL.
	Added driver/Kconfig and driver/Makefile changes.
Changes from v10
        Removed deependency on Omar Ramirez Luna's mailbox code. Now the
        patch creates the directory itself.
Changes from v9
        Used to be the 4th patch in the series.
Changes from v6, v7, v8
        None.
Changes from v5
        Renamed ipc_transmit() to pl320_ipc_transmit().
        Properly exported pl320_ipc_{un}register_notifier().
Changes from v4
        Moved pl320-ipc.c from arch/arm/mach-highbank to drivers/mailbox.
        Moved header information to include/linux/mailbox.h.
        Added Kconfig options to reflect the new code location.
        Change drivers/mailbox/Makefile to build the omap mailboxes only 
        when they are configured.
        Removed ipc_call_fast and renamed ipc_call_slow ipc_transmit.
Changes from v3, v2
        None.
Changes from v1
        Removed erroneous changes for cpufreq Kconfig.

 arch/arm/mach-highbank/Kconfig |   2 +
 drivers/Kconfig                |   2 +
 drivers/Makefile               |   1 +
 drivers/mailbox/Kconfig        |  18 ++++
 drivers/mailbox/Makefile       |   1 +
 drivers/mailbox/pl320-ipc.c    | 199 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mailbox.h        |  18 ++++
 7 files changed, 241 insertions(+)
 create mode 100644 drivers/mailbox/Kconfig
 create mode 100644 drivers/mailbox/Makefile
 create mode 100644 drivers/mailbox/pl320-ipc.c
 create mode 100644 include/linux/mailbox.h

diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index 551c97e..2388085 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -11,5 +11,7 @@ config ARCH_HIGHBANK
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU
 	select HAVE_SMP
+	select MAILBOX
+	select PL320_MBOX
 	select SPARSE_IRQ
 	select USE_OF
diff --git a/drivers/Kconfig b/drivers/Kconfig
index f5fb072..2b4e89b 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -134,6 +134,8 @@ source "drivers/hwspinlock/Kconfig"
 
 source "drivers/clocksource/Kconfig"
 
+source "drivers/mailbox/Kconfig"
+
 source "drivers/iommu/Kconfig"
 
 source "drivers/remoteproc/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 7863b9f..a8d32f1 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -130,6 +130,7 @@ obj-y				+= platform/
 #common clk code
 obj-y				+= clk/
 
+obj-$(CONFIG_MAILBOX)		+= mailbox/
 obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/
 obj-$(CONFIG_NFC)		+= nfc/
 obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
new file mode 100644
index 0000000..9489554
--- /dev/null
+++ b/drivers/mailbox/Kconfig
@@ -0,0 +1,18 @@
+menuconfig MAILBOX
+	bool "Mailbox Hardware Support"
+	help
+	  Mailbox is a framework to control hardware communication between
+	  on-chip processors through queued messages and interrupt driven
+	  signals. Say Y if your platform supports hardware mailboxes.
+
+if MAILBOX
+config PL320_MBOX
+	bool "ARM PL320 Mailbox"
+	help
+	  An implementation of the ARM PL320 Interprocessor Communication
+	  Mailbox (IPCM), tailored for the Calxeda Highbank. It is used to
+	  send short messages between Highbank's A9 cores and the EnergyCore
+	  Management Engine, primarily for cpufreq. Say Y here if you want
+	  to use the PL320 IPCM support.
+
+endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
new file mode 100644
index 0000000..543ad6a
--- /dev/null
+++ b/drivers/mailbox/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320-ipc.c
new file mode 100644
index 0000000..ba8293f
--- /dev/null
+++ b/drivers/mailbox/pl320-ipc.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/notifier.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+
+#include <linux/mailbox.h>
+
+#define IPCMxSOURCE(m)		((m) * 0x40)
+#define IPCMxDSET(m)		(((m) * 0x40) + 0x004)
+#define IPCMxDCLEAR(m)		(((m) * 0x40) + 0x008)
+#define IPCMxDSTATUS(m)		(((m) * 0x40) + 0x00C)
+#define IPCMxMODE(m)		(((m) * 0x40) + 0x010)
+#define IPCMxMSET(m)		(((m) * 0x40) + 0x014)
+#define IPCMxMCLEAR(m)		(((m) * 0x40) + 0x018)
+#define IPCMxMSTATUS(m)		(((m) * 0x40) + 0x01C)
+#define IPCMxSEND(m)		(((m) * 0x40) + 0x020)
+#define IPCMxDR(m, dr)		(((m) * 0x40) + ((dr) * 4) + 0x024)
+
+#define IPCMMIS(irq)		(((irq) * 8) + 0x800)
+#define IPCMRIS(irq)		(((irq) * 8) + 0x804)
+
+#define MBOX_MASK(n)		(1 << (n))
+#define IPC_TX_MBOX		1
+#define IPC_RX_MBOX		2
+
+#define CHAN_MASK(n)		(1 << (n))
+#define A9_SOURCE		1
+#define M3_SOURCE		0
+
+static void __iomem *ipc_base;
+static int ipc_irq;
+static DEFINE_MUTEX(ipc_m1_lock);
+static DECLARE_COMPLETION(ipc_completion);
+static ATOMIC_NOTIFIER_HEAD(ipc_notifier);
+
+static inline void set_destination(int source, int mbox)
+{
+	__raw_writel(CHAN_MASK(source), ipc_base + IPCMxDSET(mbox));
+	__raw_writel(CHAN_MASK(source), ipc_base + IPCMxMSET(mbox));
+}
+
+static inline void clear_destination(int source, int mbox)
+{
+	__raw_writel(CHAN_MASK(source), ipc_base + IPCMxDCLEAR(mbox));
+	__raw_writel(CHAN_MASK(source), ipc_base + IPCMxMCLEAR(mbox));
+}
+
+static void __ipc_send(int mbox, u32 *data)
+{
+	int i;
+	for (i = 0; i < 7; i++)
+		__raw_writel(data[i], ipc_base + IPCMxDR(mbox, i));
+	__raw_writel(0x1, ipc_base + IPCMxSEND(mbox));
+}
+
+static u32 __ipc_rcv(int mbox, u32 *data)
+{
+	int i;
+	for (i = 0; i < 7; i++)
+		data[i] = __raw_readl(ipc_base + IPCMxDR(mbox, i));
+	return data[1];
+}
+
+/* blocking implmentation from the A9 side, not usuable in interrupts! */
+int pl320_ipc_transmit(u32 *data)
+{
+	int ret;
+
+	mutex_lock(&ipc_m1_lock);
+
+	init_completion(&ipc_completion);
+	__ipc_send(IPC_TX_MBOX, data);
+	ret = wait_for_completion_timeout(&ipc_completion,
+					  msecs_to_jiffies(1000));
+	if (ret == 0) {
+		ret = -ETIMEDOUT;
+		goto out;
+	}
+
+	ret = __ipc_rcv(IPC_TX_MBOX, data);
+out:
+	mutex_unlock(&ipc_m1_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pl320_ipc_transmit);
+
+irqreturn_t ipc_handler(int irq, void *dev)
+{
+	u32 irq_stat;
+	u32 data[7];
+
+	irq_stat = __raw_readl(ipc_base + IPCMMIS(1));
+	if (irq_stat & MBOX_MASK(IPC_TX_MBOX)) {
+		__raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+		complete(&ipc_completion);
+	}
+	if (irq_stat & MBOX_MASK(IPC_RX_MBOX)) {
+		__ipc_rcv(IPC_RX_MBOX, data);
+		atomic_notifier_call_chain(&ipc_notifier, data[0], data + 1);
+		__raw_writel(2, ipc_base + IPCMxSEND(IPC_RX_MBOX));
+	}
+
+	return IRQ_HANDLED;
+}
+
+int pl320_ipc_register_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&ipc_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(pl320_ipc_register_notifier);
+
+int pl320_ipc_unregister_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_unregister(&ipc_notifier, nb);
+}
+EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier);
+
+static int __init pl320_probe(struct amba_device *adev,
+				const struct amba_id *id)
+{
+	int ret;
+
+	ipc_base = ioremap(adev->res.start, resource_size(&adev->res));
+	if (ipc_base == NULL)
+		return -ENOMEM;
+
+	__raw_writel(0, ipc_base + IPCMxSEND(IPC_TX_MBOX));
+
+	ipc_irq = adev->irq[0];
+	ret = request_irq(ipc_irq, ipc_handler, 0, dev_name(&adev->dev), NULL);
+	if (ret < 0)
+		goto err;
+
+	/* Init slow mailbox */
+	__raw_writel(CHAN_MASK(A9_SOURCE),
+			ipc_base + IPCMxSOURCE(IPC_TX_MBOX));
+	__raw_writel(CHAN_MASK(M3_SOURCE),
+			ipc_base + IPCMxDSET(IPC_TX_MBOX));
+	__raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE),
+		     ipc_base + IPCMxMSET(IPC_TX_MBOX));
+
+	/* Init receive mailbox */
+	__raw_writel(CHAN_MASK(M3_SOURCE),
+			ipc_base + IPCMxSOURCE(IPC_RX_MBOX));
+	__raw_writel(CHAN_MASK(A9_SOURCE),
+			ipc_base + IPCMxDSET(IPC_RX_MBOX));
+	__raw_writel(CHAN_MASK(M3_SOURCE) | CHAN_MASK(A9_SOURCE),
+		     ipc_base + IPCMxMSET(IPC_RX_MBOX));
+
+	return 0;
+err:
+	iounmap(ipc_base);
+	return ret;
+}
+
+static struct amba_id pl320_ids[] = {
+	{
+		.id	= 0x00041320,
+		.mask	= 0x000fffff,
+	},
+	{ 0, 0 },
+};
+
+static struct amba_driver pl320_driver = {
+	.drv = {
+		.name	= "pl320",
+	},
+	.id_table	= pl320_ids,
+	.probe		= pl320_probe,
+};
+
+static int __init ipc_init(void)
+{
+	return amba_driver_register(&pl320_driver);
+}
+module_init(ipc_init);
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
new file mode 100644
index 0000000..911cb28
--- /dev/null
+++ b/include/linux/mailbox.h
@@ -0,0 +1,18 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+int pl320_ipc_transmit(u32 *data);
+int pl320_ipc_register_notifier(struct notifier_block *nb);
+int pl320_ipc_unregister_notifier(struct notifier_block *nb);
+
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH 4/4 v12] cpufreq, highbank: add support for highbank cpufreq
From: Mark Langsdorf @ 2013-01-28 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359389595-26580-1-git-send-email-mark.langsdorf@calxeda.com>

Highbank processors depend on the external ECME to perform voltage
management based on a requested frequency. Communication between the
A9 cores and the ECME happens over the pl320 IPC channel.

Signed-off-by: Mark Langsdorf <mark.langsdorf@calxeda.com>
Reviewed-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Mike Turquette <mturquette@linaro.org>
---
Changes from v11
	Added a compatible check against calxeda,highbank.
Changes from v10
        Now finds a cpu node by searching under /cpus and looking for something
        with an operating-points descriptor. This applies to both 
        highbank-cpufreq and cpufreq-cpu0.
Changes from v9
        Added Mike Turquette's reviewed by.
        Used to be the 6th patch in the series.
Changes from v8
        Added Shawn Guo's reviewed by.
        Removed some magic numbers.
        Changed failure returns in clk_notify from NOTIFY_STOP to NOTIFY_BAD.
Changes from v7
        Removed old attribution to cpufreq-cpu0.
        Added some description in the documentation.
        Made cpu_dev, cpu_clk into local variables.
        Removed __devinit.
        Removed some unneeded includes.
        Added a brace to clarify some nested if logic.
Changes from v6
        Removed devicetree bindings documentation.
        Restructured driver to use clk notifications.
        Core driver logic is now cpufreq-clk0.
Changes from v5
        Changed ipc_transmit() to pl320_ipc_transmit().
Changes from v4
        Removed erroneous changes to arch/arm/Kconfig.
        Removed unnecessary changes to drivers/cpufreq/Kconfig.arm
        Alphabetized additions to arch/arm/mach-highbank/Kconfig
        Changed ipc call and header to match new ipc location in 
        drivers/mailbox.
Changes from v3
        None.
Changes from v2
        Changed transition latency binding in code to match documentation.
Changes from v1
        Added highbank specific Kconfig changes.

 arch/arm/boot/dts/highbank.dts     |  10 ++++
 arch/arm/mach-highbank/Kconfig     |   2 +
 drivers/cpufreq/Kconfig.arm        |  15 +++++
 drivers/cpufreq/Makefile           |   3 +-
 drivers/cpufreq/cpufreq-cpu0.c     |   6 +-
 drivers/cpufreq/highbank-cpufreq.c | 115 +++++++++++++++++++++++++++++++++++++
 6 files changed, 149 insertions(+), 2 deletions(-)
 create mode 100644 drivers/cpufreq/highbank-cpufreq.c

diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 5927a8d..6aad34a 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -37,6 +37,16 @@
 			next-level-cache = <&L2>;
 			clocks = <&a9pll>;
 			clock-names = "cpu";
+			operating-points = <
+				/* kHz    ignored */
+				 1300000  1000000
+				 1200000  1000000
+				 1100000  1000000
+				  800000  1000000
+				  400000  1000000
+				  200000  1000000
+			>;
+			clock-latency = <100000>;
 		};
 
 		cpu at 901 {
diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index 2388085..44b12f9 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -1,5 +1,7 @@
 config ARCH_HIGHBANK
 	bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_AMBA
 	select ARM_GIC
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index a0b3661..ffe55b8 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -83,3 +83,18 @@ config ARM_SPEAR_CPUFREQ
 	default y
 	help
 	  This adds the CPUFreq driver support for SPEAr SOCs.
+
+config ARM_HIGHBANK_CPUFREQ
+	tristate "Calxeda Highbank-based"
+	depends on ARCH_HIGHBANK
+	select CPU_FREQ_TABLE
+	select GENERIC_CPUFREQ_CPU0
+	select PM_OPP
+	select REGULATOR
+
+	default m
+	help
+	  This adds the CPUFreq driver for Calxeda Highbank SoC
+	  based boards.
+
+	  If in doubt, say N.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index fadc4d4..31e6f19 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -50,8 +50,9 @@ obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)	+= exynos-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ)	+= exynos4210-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ)	+= exynos4x12-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ)	+= exynos5250-cpufreq.o
-obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)     += omap-cpufreq.o
+obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)		+= spear-cpufreq.o
+obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)	+= highbank-cpufreq.o
 
 ##################################################################################
 # PowerPC platform drivers
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index 52bf36d..90e9d73 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -179,7 +179,11 @@ static int cpu0_cpufreq_driver_init(void)
 	struct device_node *np;
 	int ret;
 
-	np = of_find_node_by_path("/cpus/cpu at 0");
+	for_each_child_of_node(of_find_node_by_path("/cpus"), np) {
+		if (of_get_property(np, "operating-points", NULL))
+			break;
+	}
+
 	if (!np) {
 		pr_err("failed to find cpu0 node\n");
 		return -ENOENT;
diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c
new file mode 100644
index 0000000..2ea6276
--- /dev/null
+++ b/drivers/cpufreq/highbank-cpufreq.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2012 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This driver provides the clk notifier callbacks that are used when
+ * the cpufreq-cpu0 driver changes to frequency to alert the highbank
+ * EnergyCore Management Engine (ECME) about the need to change
+ * voltage. The ECME interfaces with the actual voltage regulators.
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/mailbox.h>
+
+#define HB_CPUFREQ_CHANGE_NOTE	0x80000001
+#define HB_CPUFREQ_IPC_LEN	7
+#define HB_CPUFREQ_VOLT_RETRIES	15
+
+static int hb_voltage_change(unsigned int freq)
+{
+	int i;
+	u32 msg[HB_CPUFREQ_IPC_LEN];
+
+	msg[0] = HB_CPUFREQ_CHANGE_NOTE;
+	msg[1] = freq / 1000000;
+	for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++)
+		msg[i] = 0;
+
+	return pl320_ipc_transmit(msg);
+}
+
+static int hb_cpufreq_clk_notify(struct notifier_block *nb, 
+				unsigned long action, void *hclk)
+{
+	struct clk_notifier_data *clk_data = hclk;
+	int i = 0;
+
+	if (action == PRE_RATE_CHANGE) {
+		if (clk_data->new_rate > clk_data->old_rate)
+			while (hb_voltage_change(clk_data->new_rate))
+				if (i++ > HB_CPUFREQ_VOLT_RETRIES)
+					return NOTIFY_BAD;
+	} else if (action == POST_RATE_CHANGE) {
+		if (clk_data->new_rate < clk_data->old_rate)
+			while (hb_voltage_change(clk_data->new_rate))
+				if (i++ > HB_CPUFREQ_VOLT_RETRIES)
+					return NOTIFY_BAD;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block hb_cpufreq_clk_nb = {
+	.notifier_call = hb_cpufreq_clk_notify,
+};
+
+static int hb_cpufreq_driver_init(void)
+{
+	struct device *cpu_dev;
+	struct clk *cpu_clk;
+	struct device_node *np;
+	int ret;
+
+	if (!of_machine_is_compatible("calxeda,highbank"))
+		return -ENODEV;
+
+	for_each_child_of_node(of_find_node_by_path("/cpus"), np)
+		if (of_get_property(np, "operating-points", NULL))
+			break;
+
+	if (!np) {
+		pr_err("failed to find highbank cpufreq node\n");
+		return -ENOENT;
+	}
+
+	cpu_dev = get_cpu_device(0);
+	if (!cpu_dev) {
+		pr_err("failed to get highbank cpufreq device\n");
+		ret = -ENODEV;
+		goto out_put_node;
+	}
+
+	cpu_dev->of_node = np;
+
+	cpu_clk = clk_get(cpu_dev, NULL);
+	if (IS_ERR(cpu_clk)) {
+		ret = PTR_ERR(cpu_clk);
+		pr_err("failed to get cpu0 clock: %d\n", ret);
+		goto out_put_node;
+	}
+
+	ret = clk_notifier_register(cpu_clk, &hb_cpufreq_clk_nb);
+	if (ret) {
+		pr_err("failed to register clk notifier: %d\n", ret);
+		goto out_put_node;
+	}
+
+out_put_node:
+	of_node_put(np);
+	return ret;
+}
+module_init(hb_cpufreq_driver_init);
+
+MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@calxeda.com>");
+MODULE_DESCRIPTION("Calxeda Highbank cpufreq driver");
+MODULE_LICENSE("GPL");
-- 
1.7.11.7

^ permalink raw reply related

* [PATCH 1/4] drm/tilcdc: add TI LCD Controller DRM driver (v3)
From: Rob Clark @ 2013-01-28 16:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <C8443D0743D26F4388EA172BF4E2A7A93EA944D2@DBDE01.ent.ti.com>

On Mon, Jan 28, 2013 at 3:56 AM, Mohammed, Afzal <afzal@ti.com> wrote:
> Hi Rob,
>
> On Fri, Jan 25, 2013 at 20:22:55, Rob Clark wrote:
>> On Fri, Jan 25, 2013 at 8:15 AM, Mohammed, Afzal <afzal@ti.com> wrote:
>
>> > It's not about being simple, but not doing the wrong way, here you are
>> > relying on a platform specific clock in a driver, think about the case
>> > where same IP is used on another platform. Either way it is not a good
>> > thing to handle platform specific details (about disp_clk) in driver.
>
>> Right, but I was trying to understand what was the benefit that the
>> added complexity is.  I didn't realize on davinci that you are limited
>
> Here I am referring to usage of disp_clk,
>
> Driver is not supposed to do platform hacks - here you are trying to
> configure something (PLL) in your driver which is not part of LCDC IP.
> And LCDC IP is not aware of PLL which is a platform specific matter
> (existent only in AM335x), it is only aware of functional clock.
>
> You can set the rate on "fck" (functional clock) in AM335x using my patch,
> "ARM: AM33XX: clock: SET_RATE_PARENT in lcd path", and there
> would not be any need for driver to be aware of platform specific PLL.

right, but I think it would be better to just make another patch that
changes tilcdc to just set rate on fck after that patch is merged.  I
mean, I'd rather have the driver at least usable on AM33xx until then,
rather than broken for everyone.

BR,
-R

>> >> >> +     priv->clk = clk_get(dev->dev, "fck");
>
>> >> >> +     priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck");
>
>> at the moment all this discussion is a bit moot.  I'd propose leaving
>> the driver as it is for now, because that at least makes it useful on
>> am33xx.  And when CCF and davinci have the needed support in place,
>
> Let's forget about leveraging CCF in driver, but sane solution w.r.t PLL
> configuration would be to do as mentioned above.
>
> Regards
> Afzal
>

^ permalink raw reply

* [PATCH 2/2] clk: tegra: adapt tegra periph clk to mux table/mask
From: Stephen Warren @ 2013-01-28 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359388467-32386-3-git-send-email-pdeschrijver@nvidia.com>

On 01/28/2013 08:54 AM, Peter De Schrijver wrote:
> The tegra peripheral clock type uses struct clk_mux directly, so it needs to
> be updated to handle the new mask and table fields. Also the macros need
> to be updated

Just a quick note on patch dependencies here:

Patch 1/2 can presumably be taken through the clk tree whenever Mike is
OK with it.

Patch 2/2 depends on patches in the Tegra tree for 3.9. Since patch 2/2
is useful mostly for the Tegra114 clock driver, and I don't imagine that
will get posted/merged in time for 3.9, it's probably easiest to just
take patch 2/2 for 3.10 along with the Tegra114 clock driver. Also, I
imagine there won't be any more clk/Tegra tree dependencies in 3.10, so
patch 2/2 and the Tegra114 clk driver patches can likely go through the
clk tree itself for 3.10.

^ permalink raw reply

* OMAP baseline test results for v3.8-rc5
From: Felipe Balbi @ 2013-01-28 16:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <331ABD5ECB02734CA317220B2BBEABC13EAF78AE@DBDE01.ent.ti.com>

Hi,

On Mon, Jan 28, 2013 at 03:40:09PM +0100, AnilKumar, Chimata wrote:
> On Mon, Jan 28, 2013 at 17:48:49, Mohammed, Afzal wrote:
> > Hi Felipe,
> > 
> > On Mon, Jan 28, 2013 at 17:46:35, Balbi, Felipe wrote:
> > 
> > > didn't help :-s
> > 
> > Hands up :(
> 
> Hi Felipe,
> 
> Could you please try with any of these options?
> 
> 1. Change/add mem=512M (should be same value as u-boot printed RAM size) in your
> bootargs?
> 
> Or
> 
> 2. set fdt_high 0xffffffff (at u-boot prompt).

that helped, thank you :-)

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130128/4ced70d0/attachment.sig>

^ permalink raw reply

* [PATCH v2 06/16] ARM: bL_head.S: vlock-based first man election
From: Will Deacon @ 2013-01-28 17:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359008879-9015-7-git-send-email-nicolas.pitre@linaro.org>

On Thu, Jan 24, 2013 at 06:27:49AM +0000, Nicolas Pitre wrote:
> From: Dave Martin <dave.martin@linaro.org>
> 
> Instead of requiring the first man to be elected in advance (which
> can be suboptimal in some situations), this patch uses a per-
> cluster mutex to co-ordinate selection of the first man.
> 
> This should also make it more feasible to reuse this code path for
> asynchronous cluster resume (as in CPUidle scenarios).
> 
> We must ensure that the vlock data doesn't share a cacheline with
> anything else, or dirty cache eviction could corrupt it.
> 
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>

[...]

> +
> +	.align	__CACHE_WRITEBACK_ORDER
> +	.type	first_man_locks, #object
> +first_man_locks:
> +	.space	VLOCK_SIZE * BL_MAX_CLUSTERS
> +	.align	__CACHE_WRITEBACK_ORDER
>  
>  	.type	bL_entry_vectors, #object
>  ENTRY(bL_entry_vectors)

I've just been chatting to Dave about this and __CACHE_WRITEBACK_ORDER
isn't really the correct solution here.

To summarise the problem: although vlocks are only accessed by CPUs with
their caches disabled, the lock structures could reside in the same
cacheline (at some level of cache) as cacheable data being written by
another CPU. This comes about because the vlock code has a cacheable alias
via the kernel linear mapping and means that when the cacheable data is
evicted, it clobbers the vlocks with stale values which are part of the
dirty cacheline.

Now, we also have this problem for DMA mappings, as mentioned here:

  http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/124276.html

It seems to me that we actually want a mechanism for allocating/managing
physically contiguous blocks of memory such that the cacheable alias is
removed from the linear mapping (perhaps we could use PAGE_NONE to avoid
confusing the mm code?).

Will

^ permalink raw reply

* [PATCHv1 for soc 4/5] arm: Add v7_invalidate_l1 to cache-v7.S
From: Stephen Warren @ 2013-01-28 17:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130128104552.GB6073@amd.pavel.ucw.cz>

On 01/28/2013 03:45 AM, Pavel Machek wrote:
> On Thu 2013-01-24 20:42:08, Stephen Warren wrote:
>> On 01/24/2013 05:00 PM, dinguyen at altera.com wrote:
>>> From: Dinh Nguyen <dinguyen@altera.com>
>>>
>>> mach-socfpga is another platform that needs to use
>>> v7_invalidate_l1 to bringup additional cores. There was a comment that
>>> the ideal place for v7_invalidate_l1 should be in arm/mm/cache-v7.S
>>
>>> diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
>>
>>> -ENTRY(v7_invalidate_l1)
>>> -        mov     r0, #0
>>
>> Unfortunately, there's a patch in the Tegra tree for 3.9 that moves that
>> function from headsmp.S to reset-handler.S, so this patch will conflict.
>> How do you want to handle that?
> 
> Drop the patch from Tegra tree and merge this one there? Having three
> copies of code is not nice to start with, no matter where it is...

Well, I guess for other reasons rebasing the Tegra tree is useful for a
few dependencies, so I'll drop that part of the patch which moves
v7_invalidate_l1() from one file to another, so there shouldn't be any
conflicts, and you can feel free to take this series through whatever
tree you want.

I haven't tested this patch yet though, to see whether the slight
differences in the code in your patch mentioned in the other sub-thread
affect Tegra at all. Hopefully I can test this later today.

^ permalink raw reply

* [RFC PATCH] ARM: Export the CPU logical map to modules
From: Dave Martin @ 2013-01-28 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

It is reasonable for loadable modules to be CPU topology aware
(particular examples include cpufreq and cpuidle drivers).

This patch exports __cpu_logical_map, so that modules can use the
cpu_logical_map() interface declared in <asm/smp_plat.h>.

Signed-off-by: Dave Martin <dave.martin@linaro.org>
---
If anyone has a strong view on whether this should be
EXPORT_SYMBOL_GPL(), I don't have a problem with changing
that.  I'm not sure of the precise etiquette here.
Certainly this does not feel like a very "public" interface.

Perhaps we should wrap this in a real function for export
to modules, rather than encouraging them to poke the
__cpu_logical_map[] array (albeit via a predefined macro).


 arch/arm/kernel/setup.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 3f6cbb2..1b9e5bf 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -428,6 +428,7 @@ void cpu_init(void)
 }
 
 int __cpu_logical_map[NR_CPUS];
+EXPORT_SYMBOL(__cpu_logical_map);
 
 void __init smp_setup_processor_id(void)
 {
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH v2 11/30] usb: ehci-omap: Remove PHY reset handling code
From: Alan Stern @ 2013-01-28 17:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359372631-8180-12-git-send-email-rogerq@ti.com>

On Mon, 28 Jan 2013, Roger Quadros wrote:

> Reset GPIO handling for the PHY must be done in the PHY
> driver. We use the PHY helpers instead to reset the PHY.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply

* [PATCHv1 for soc 4/5] arm: Add v7_invalidate_l1 to cache-v7.S
From: Dinh Nguyen @ 2013-01-28 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <5106B4FD.4030108@wwwdotorg.org>

Hi Stephen,

On Mon, 2013-01-28 at 10:27 -0700, Stephen Warren wrote:
> On 01/28/2013 03:45 AM, Pavel Machek wrote:
> > On Thu 2013-01-24 20:42:08, Stephen Warren wrote:
> >> On 01/24/2013 05:00 PM, dinguyen at altera.com wrote:
> >>> From: Dinh Nguyen <dinguyen@altera.com>
> >>>
> >>> mach-socfpga is another platform that needs to use
> >>> v7_invalidate_l1 to bringup additional cores. There was a comment that
> >>> the ideal place for v7_invalidate_l1 should be in arm/mm/cache-v7.S
> >>
> >>> diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
> >>
> >>> -ENTRY(v7_invalidate_l1)
> >>> -        mov     r0, #0
> >>
> >> Unfortunately, there's a patch in the Tegra tree for 3.9 that moves that
> >> function from headsmp.S to reset-handler.S, so this patch will conflict.
> >> How do you want to handle that?
> > 
> > Drop the patch from Tegra tree and merge this one there? Having three
> > copies of code is not nice to start with, no matter where it is...
> 
> Well, I guess for other reasons rebasing the Tegra tree is useful for a
> few dependencies, so I'll drop that part of the patch which moves
> v7_invalidate_l1() from one file to another, so there shouldn't be any
> conflicts, and you can feel free to take this series through whatever
> tree you want.
> 
> I haven't tested this patch yet though, to see whether the slight
> differences in the code in your patch mentioned in the other sub-thread
> affect Tegra at all. Hopefully I can test this later today.

Shawn Guo mentioned that the instruction to invalidate I-Cache is
unnecessary becauce of this commit: 612539e (ARM: 7296/1: proc-v7.S:
remove HARVARD_CACHE preprocessor guards)

So I'll send v2 without the extra instruction.

Thanks,
Dinh
> 

^ permalink raw reply

* [PATCH v2 12/30] usb: ehci-omap: Remove PHY regulator handling code
From: Alan Stern @ 2013-01-28 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359372631-8180-13-git-send-email-rogerq@ti.com>

On Mon, 28 Jan 2013, Roger Quadros wrote:

> PHY regulator handling must be done in the PHY driver
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>

Acked-by: Alan Stern <stern@rowland.harvard.edu>

^ permalink raw reply

* i.Mx6Quad - eth0: tx queue full!
From: Vikram Narayanan @ 2013-01-28 17:39 UTC (permalink / raw)
  To: linux-arm-kernel

Running the latest head <linux-2.6.git> on an i.Mx6Quad based platform
gives me the below error when flooded with ping requests.

== Start log ==
[ 2555.004031] ------------[ cut here ]------------
[ 2555.009740] WARNING: at net/sched/sch_generic.c:254 dev_watchdog+0x298/0x2b8()
[ 2555.018721] NETDEV WATCHDOG: eth0 (fec): transmit queue 0 timed out
[ 2555.026733] Modules linked in:
[ 2555.030598] Backtrace:
[ 2555.034252] [<800119c8>] (dump_backtrace+0x0/0x10c) from [<803b8494>] (dump_stack+0x18/0x1c)
[ 2555.044438]  r6:000000fe r5:80302f64 r4:80503dd0 r3:80510e80
[ 2555.052019] [<803b847c>] (dump_stack+0x0/0x1c) from [<8001df08>] (warn_slowpath_common+0x54/0x6c)
[ 2555.062679] [<8001deb4>] (warn_slowpath_common+0x0/0x6c) from [<8001dfc4>] (warn_slowpath_fmt+0x38/0x40)
[ 2555.073936]  r8:8052ebf1 r7:805040c0 r6:00000000 r5:8f9771d4 r4:8f977000
r3:00000009
[ 2555.084816] [<8001df8c>] (warn_slowpath_fmt+0x0/0x40) from [<80302f64>] (dev_watchdog+0x298/0x2b8)
[ 2555.095535]  r3:8f977000 r2:8049f6d4
[ 2555.099868] [<80302ccc>] (dev_watchdog+0x0/0x2b8) from [<8002acf8>] (call_timer_fn.isra.33+0x2c/0x8c)
[ 2555.110794] [<8002accc>] (call_timer_fn.isra.33+0x0/0x8c) from [<8002af48>] (run_timer_softirq+0x1f0/0x204)
[ 2555.122240]  r7:80571114 r6:805040c0 r5:00000000 r4:80570900
[ 2555.129894] [<8002ad58>] (run_timer_softirq+0x0/0x204) from [<80025750>] (__do_softirq+0xc8/0x180)
[ 2555.140599] [<80025688>] (__do_softirq+0x0/0x180) from [<80025b40>] (irq_exit+0x88/0x90)
[ 2555.150492] [<80025ab8>] (irq_exit+0x0/0x90) from [<8000ec58>] (handle_IRQ+0x44/0x98)
[ 2555.160112]  r4:804ffde0 r3:00000220
[ 2555.164848] [<8000ec14>] (handle_IRQ+0x0/0x98) from [<80008540>] (gic_handle_irq+0x30/0x64)
[ 2555.174956]  r6:80503f28 r5:8050a518 r4:f400010c r3:00000000
[ 2555.182694] [<80008510>] (gic_handle_irq+0x0/0x64) from [<8000df80>] (__irq_svc+0x40/0x50)
[ 2555.192737] Exception stack(0x80503f28 to 0x80503f70)
[ 2555.198639] 3f20:                   8052f150 a0000093 00000000 00000000 80502000 8052ed08
[ 2555.208600] 3f40: 8050a4f4 803bfaec 8050df00 412fc09a 80502000 80503f7c 80503f80 80503f70
[ 2555.218584] 3f60: 8000eee4 8000eee8 60000013 ffffffff
[ 2555.224730]  r7:80503f5c r6:ffffffff r5:60000013 r4:8000eee8
[ 2555.232292] [<8000eeb8>] (default_idle+0x0/0x38) from [<8000f0d8>] (cpu_idle+0xcc/0x114)
[ 2555.242204] [<8000f00c>] (cpu_idle+0x0/0x114) from [<803b3718>] (rest_init+0x64/0x7c)
[ 2555.251858] [<803b36b4>] (rest_init+0x0/0x7c) from [<804cc7dc>] (start_kernel+0x258/0x298)
[ 2555.261963] [<804cc584>] (start_kernel+0x0/0x298) from [<10008078>] (0x10008078)
[ 2555.271167] ---[ end trace 3d2ffb53e6fe41f3 ]---
[ 2555.277270] eth0: tx queue full!.
[ 2555.288776] eth0: tx queue full!.
[ 2555.293594] eth0: tx queue full!.
[ 2555.297944] eth0: tx queue full!.
[ 2555.302229] eth0: tx queue full!.

...... continues indefinitely and needs a reboot to recover the system.
== End log ==

i.Mx6Quad's MAC is connected to SMSC LAN88730 PHY via an MII interface.

I found a similar thread [1], but that solution didn't work for me.
Any ideas on why the fec driver is unhappy?

Thanks,
Vikram

[1] https://community.freescale.com/thread/281457

^ permalink raw reply

* [PATCH v3 0/3] introduce static_vm for ARM-specific static mapped area
From: Will Deacon @ 2013-01-28 17:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358990934-4893-1-git-send-email-iamjoonsoo.kim@lge.com>

Hello,

On Thu, Jan 24, 2013 at 01:28:51AM +0000, Joonsoo Kim wrote:
> In current implementation, we used ARM-specific flag, that is,
> VM_ARM_STATIC_MAPPING, for distinguishing ARM specific static mapped area.
> The purpose of static mapped area is to re-use static mapped area when
> entire physical address range of the ioremap request can be covered
> by this area.
> 
> This implementation causes needless overhead for some cases.
> For example, assume that there is only one static mapped area and
> vmlist has 300 areas. Every time we call ioremap, we check 300 areas for
> deciding whether it is matched or not. Moreover, even if there is
> no static mapped area and vmlist has 300 areas, every time we call
> ioremap, we check 300 areas in now.
> 
> If we construct a extra list for static mapped area, we can eliminate
> above mentioned overhead.
> With a extra list, if there is one static mapped area,
> we just check only one area and proceed next operation quickly.
> 
> In fact, it is not a critical problem, because ioremap is not frequently
> used. But reducing overhead is better idea.
> 
> Another reason for doing this work is for removing vm_struct list management,
> entirely. For more information, look at the following link.
> http://lkml.org/lkml/2012/12/6/184

First patch looks good (removing the unused vmregion stuff) but I'm not so
sure about the rest of it. If you really care about ioremap performance,
perhaps it would be better to have a container struct around the vm_struct
for static mappings and then stick them in an augmented rbtree so you can
efficiently find the mapping encompassing a particular physical address?

Will

^ permalink raw reply

* [PATCH 0/2] ARM: dts: OMAP3: Add GPMC controller and NAND memory to Overo
From: Florian Vaussard @ 2013-01-28 17:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This is more an RFC serie, as an issue is still unclear to me.
Building on the work of Daniel Mack for the GPMC controller (staged
in Tony's tree [1]), it was easy to add the GPMC controller to OMAP3.

The issue comes from the Overo on-board NAND, as the amount of flash
depends on the revision. Currently, partitions are handled in the board
file using MTDPART_SIZ_FULL, but looking at the ofpart parser, the size
given to the parser must be fixed.

So how should we handle such case? Having several dtsi depending
on the Overo's revision would be a mess to my sense, considering
the non-conditional include inside the expansion boards' dts.
Or would it make sense to extend the DT binding for partitions?

This serie was tested on an Overo with 512MB of NAND.

Best regards,

Florian

[1] git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git omap-for-v3.9/gpmc

Florian Vaussard (2):
  ARM: dts: OMAP3: Add GPMC controller
  ARM: dts: OMAP3: Add NAND memory for Overo products

 arch/arm/boot/dts/omap3-overo.dtsi |   49 ++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/omap3.dtsi       |   11 ++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

-- 
1.7.5.4

^ permalink raw reply

* [PATCH 1/2] ARM: dts: OMAP3: Add GPMC controller
From: Florian Vaussard @ 2013-01-28 17:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359395648-2137-1-git-send-email-florian.vaussard@epfl.ch>

Add device-tree support for the GPMC controller on the OMAP3.

Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
 arch/arm/boot/dts/omap3.dtsi |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 6c63118..2ddae38 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -403,5 +403,16 @@
 			ti,timer-alwon;
 			ti,timer-secure;
 		};
+
+		gpmc: gpmc at 6e000000 {
+			compatible = "ti,omap3430-gpmc";
+			ti,hwmods = "gpmc";
+			reg = <0x6e000000 0x1000000>;
+			interrupts = <20>;
+			gpmc,num-cs = <8>;
+			gpmc,num-waitpins = <4>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
 	};
 };
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/2] ARM: dts: OMAP3: Add NAND memory for Overo products
From: Florian Vaussard @ 2013-01-28 17:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359395648-2137-1-git-send-email-florian.vaussard@epfl.ch>

Add device-tree support for the on-board NAND memory,
with corresponding partitions.

Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
---
 arch/arm/boot/dts/omap3-overo.dtsi |   49 ++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-overo.dtsi b/arch/arm/boot/dts/omap3-overo.dtsi
index 81341fa..0efd6f3 100644
--- a/arch/arm/boot/dts/omap3-overo.dtsi
+++ b/arch/arm/boot/dts/omap3-overo.dtsi
@@ -33,6 +33,55 @@
 	};
 };
 
+&gpmc {
+	ranges = <0 0 0x30000000 0x00000004>;       /* CS0: NAND */
+
+	nand at 0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "sw";
+
+		gpmc,sync-clk = <0>;
+		gpmc,cs-on = <0>;
+		gpmc,cs-rd-off = <36>;
+		gpmc,cs-wr-off = <36>;
+		gpmc,adv-on = <6>;
+		gpmc,adv-rd-off = <24>;
+		gpmc,adv-wr-off = <36>;
+		gpmc,we-off = <30>;
+		gpmc,oe-off = <48>;
+		gpmc,access = <54>;
+		gpmc,rd-cycle = <72>;
+		gpmc,wr-cycle = <72>;
+		gpmc,wr-access = <30>;
+		gpmc,wr-data-mux-bus = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		xloader at 0 {
+			reg = <0x00000000 0x00080000>;
+		};
+
+		uboot at 80000 {
+			reg = <0x00080000 0x001c0000>;
+		};
+
+		ubootenv at 240000 {
+			reg = <0x00240000 0x00040000>;
+		};
+
+		linux at 280000 {
+			reg = <0x00280000 0x00400000>;
+		};
+
+		rootfs at 680000 {
+			reg = <0x00680000 0x1f980000>; /* 500 MB */
+		};
+	};
+};
+
 &i2c1 {
 	clock-frequency = <2600000>;
 
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH v2 06/16] ARM: bL_head.S: vlock-based first man election
From: Nicolas Pitre @ 2013-01-28 17:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130128171831.GF23470@mudshark.cambridge.arm.com>

On Mon, 28 Jan 2013, Will Deacon wrote:

> On Thu, Jan 24, 2013 at 06:27:49AM +0000, Nicolas Pitre wrote:
> > From: Dave Martin <dave.martin@linaro.org>
> > 
> > Instead of requiring the first man to be elected in advance (which
> > can be suboptimal in some situations), this patch uses a per-
> > cluster mutex to co-ordinate selection of the first man.
> > 
> > This should also make it more feasible to reuse this code path for
> > asynchronous cluster resume (as in CPUidle scenarios).
> > 
> > We must ensure that the vlock data doesn't share a cacheline with
> > anything else, or dirty cache eviction could corrupt it.
> > 
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
> 
> [...]
> 
> > +
> > +	.align	__CACHE_WRITEBACK_ORDER
> > +	.type	first_man_locks, #object
> > +first_man_locks:
> > +	.space	VLOCK_SIZE * BL_MAX_CLUSTERS
> > +	.align	__CACHE_WRITEBACK_ORDER
> >  
> >  	.type	bL_entry_vectors, #object
> >  ENTRY(bL_entry_vectors)
> 
> I've just been chatting to Dave about this and __CACHE_WRITEBACK_ORDER
> isn't really the correct solution here.
> 
> To summarise the problem: although vlocks are only accessed by CPUs with
> their caches disabled, the lock structures could reside in the same
> cacheline (at some level of cache) as cacheable data being written by
> another CPU. This comes about because the vlock code has a cacheable alias
> via the kernel linear mapping and means that when the cacheable data is
> evicted, it clobbers the vlocks with stale values which are part of the
> dirty cacheline.
> 
> Now, we also have this problem for DMA mappings, as mentioned here:
> 
>   http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/124276.html
> 
> It seems to me that we actually want a mechanism for allocating/managing
> physically contiguous blocks of memory such that the cacheable alias is
> removed from the linear mapping (perhaps we could use PAGE_NONE to avoid
> confusing the mm code?).

Well, I partly disagree.

I don't dispute the need for a mechanism to allocate physically 
contiguous blocks of memory in the DMA case or other similar users of 
largish dynamic allocations.  

But That's not the case here.  In the vlock case, what we actually need 
in practice is equivalent to a _single_ cache line of cache free memory.  
Requiring a dynamic allocation infrastructure tailored for this specific 
case is going to waste much more CPU cycles and memory in the end than 
what this static allocation is currently doing, even if it were 
overallocating.

Your suggestion would be needed when we get to the point where dynamic 
sizing of the number of clusters is required. But, as I said in response 
to your previous comment, let's not fall into the trap of 
overengineering this solution for the time being.  Better approach this 
incrementally if actual usage does indicate that some more 
sophistication is needed.  The whole stack is already complex enough as 
it is and I'd prefer if people could get familiar with the simpler 
version initially.


Nicolas

^ permalink raw reply

* [v3 1/2] ARM: Add API to detect SCU base address from CP15
From: Stephen Warren @ 2013-01-28 18:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358833924-24535-1-git-send-email-hdoyu@nvidia.com>

On 01/21/2013 10:52 PM, Hiroshi Doyu wrote:
> Add API to detect SCU base address from CP15.

I've applied these 2 patches and Santosh's OMAP followup to Tegra's
for-3.9/scu-base-rework branch.

^ permalink raw reply

* [v4 1/6] ARM: tegra: Use DT /cpu node to detect number of CPU core
From: Stephen Warren @ 2013-01-28 18:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1359025829-22306-2-git-send-email-hdoyu@nvidia.com>

On 01/24/2013 04:10 AM, Hiroshi Doyu wrote:
> Tegra SoCs does not use SCU based to detect CPU core numbers but they
> use DT /cpu node. If it's not provided or failed, it continues as a
> single core.

I've applied patch 1 to Tegra's for-3.9/scu-base-rework branch, and
patches 2-6 to Tegra's for-3.9/soc-t114 branch.

^ permalink raw reply

* [PATCH v3 0/3] introduce static_vm for ARM-specific static mapped area
From: Nicolas Pitre @ 2013-01-28 18:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130128175106.GI23470@mudshark.cambridge.arm.com>

On Mon, 28 Jan 2013, Will Deacon wrote:

> Hello,
> 
> On Thu, Jan 24, 2013 at 01:28:51AM +0000, Joonsoo Kim wrote:
> > In current implementation, we used ARM-specific flag, that is,
> > VM_ARM_STATIC_MAPPING, for distinguishing ARM specific static mapped area.
> > The purpose of static mapped area is to re-use static mapped area when
> > entire physical address range of the ioremap request can be covered
> > by this area.
> > 
> > This implementation causes needless overhead for some cases.
> > For example, assume that there is only one static mapped area and
> > vmlist has 300 areas. Every time we call ioremap, we check 300 areas for
> > deciding whether it is matched or not. Moreover, even if there is
> > no static mapped area and vmlist has 300 areas, every time we call
> > ioremap, we check 300 areas in now.
> > 
> > If we construct a extra list for static mapped area, we can eliminate
> > above mentioned overhead.
> > With a extra list, if there is one static mapped area,
> > we just check only one area and proceed next operation quickly.
> > 
> > In fact, it is not a critical problem, because ioremap is not frequently
> > used. But reducing overhead is better idea.
> > 
> > Another reason for doing this work is for removing vm_struct list management,
> > entirely. For more information, look at the following link.
> > http://lkml.org/lkml/2012/12/6/184
> 
> First patch looks good (removing the unused vmregion stuff) but I'm not so
> sure about the rest of it. If you really care about ioremap performance,
> perhaps it would be better to have a container struct around the vm_struct
> for static mappings and then stick them in an augmented rbtree so you can
> efficiently find the mapping encompassing a particular physical address?

How can ioremap performance be a problem is the question I had since the 
beginning.

Firstly, ioremap is _not_ meant to be used in performance critical 
paths.

Secondly, there shouldn't be _that_ many entries on the vmlist such as 
300.  That sounds a bit excessive.

So please, can we discuss the reasons that motivated those patches in 
the first place?  Maybe that's where the actual problem is.


Nicolas

^ permalink raw reply

* [RFC V2 PATCH 0/8] ARM: kirkwood: cleanup DT conversion
From: Jason Gunthorpe @ 2013-01-28 18:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130128104008.GA5170@localhost>

> >         // MBUS Decoder window for NAND
> >         nand at f4000000 {
> >                 #address-cells = <1>;
> >                 #size-cells = <1>;
> >                 compatible = "simple-bus", "marvell,orion-mbus";
> > 		mbus-target = 0xXXXXX;
> >                 ranges = <0 0xf4000000 0x10000>;
> > 
> >                 nand at 0 {
> >                         cle = <0>;
> >                         ale = <1>;
> >                         bank-width = <1>;
> >                         chip-delay = <50>;
> >                         compatible = "marvell,orion-nand";
> >                         reg = <0x0 0x400>;
> >                 };
> >         };
> > 
> 
> This is a nice idea.
> 
> I have a few questions, though.
> 
> 1. Are you sure we should use "ranges" property?
> In this case it's not an address translation but rather
> and address window configuration.

Yes, you'd use ranges with an identity transation. The purpose is so
that child OF blocks are all relative to the start of the decode
region. This way changing the address of the HW block behind the mbus
window is simply done by changing the ranges property.

Note the reg on the nand is starting at offset 0, so ranges will
translate that to 0xf4000000. Similar for the internal regs.

> I would think we could add a new "windows" property to reflect
> address window configuration.

My arrangement above would have each "marvell,orion-mbus" specify the
mbus-target, which I imagined to be all the HW specific bits (target,
attributes, etc). The addr-map driver would select a window for this
bus and then assign those bits to it.

> 2. Also, If we use "ranges" property. How would that work?
> By reading the property in the addr-map driver or
> by somehow improving on of_bus to include this new kind of busses?

The addr-map driver would have to read it, I believe the rules of how
busses work make this fairly simple:

1) very early on the addr-map driver would have to scan the OF tree,
   find the address of the mbus mapping registers, and the internal
   register map.
2) Verify the mbus window for the internal registers matches the DT
   This is just a sanity check, if the correct value doesn't come back
   then the DT doesnt match what the bootloader setup, and some
   jtag accessible diagnostic can be printed...
3) Wipe all the mbus windows
4) Register a "marvell,orion-mbus" bus handler somehow
5) When OF processes the DT it would call the bus handler for each
   "marvell,orion-mbus" which should parse the ranges, allocate
   a free window, program that window then instantiate the child
   devices.

Jason

^ 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