Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL v3] Renesas ARM-based SoC defconfig for v3.9
From: Simon Horman @ 2013-01-16  6:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Olof, Hi Arnd,

please consider the following defconfig enhancements for 3.9.

----------------------------------------------------------------
The following changes since commit a49f0d1ea3ec94fc7cf33a7c36a16343b74bd565:

  Linux 3.8-rc1 (2012-12-21 17:19:00 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git defconfig

for you to fetch changes up to 8098df15c26b2bf16924df5a134d1a649692ab62:

  ARM: mach-shmobile: kzm9d: update defconfig (2013-01-15 08:57:09 +0900)

----------------------------------------------------------------
Simon Horman (5):
      ARM: mach-shmobile: mackerel: update defconfig
      ARM: mach-shmobile: fix memory size for kota2_defconfig
      ARM: mach-shmobile: kzm9g: defconfig update
      ARM: mach-shmobile: armadillo: update defconfig
      ARM: mach-shmobile: kzm9d: update defconfig

 arch/arm/boot/dts/emev2-kzm9d.dts             |    2 +-
 arch/arm/boot/dts/r8a7740-armadillo800eva.dts |    4 ++++
 arch/arm/boot/dts/sh7372-mackerel.dts         |    4 ++++
 arch/arm/boot/dts/sh73a0-kzm9g.dts            |    4 ++++
 arch/arm/configs/armadillo800eva_defconfig    |    5 ++---
 arch/arm/configs/kota2_defconfig              |    2 +-
 arch/arm/configs/kzm9d_defconfig              |    4 +---
 arch/arm/configs/kzm9g_defconfig              |    4 +++-
 arch/arm/configs/mackerel_defconfig           |    2 +-
 9 files changed, 21 insertions(+), 10 deletions(-)

^ permalink raw reply

* [PATCH 1/5] ARM: mach-shmobile: mackerel: update defconfig
From: Simon Horman @ 2013-01-16  6:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358316146-12579-1-git-send-email-horms+renesas@verge.net.au>

* Enable ARM_APPENDED_DTB

  Typically the bootloader of a mackerel board does not support DT
  so this option is useful

* Add "rw" to command line

  This appears to be necessary for a successful NFS-root boot

* Remove memchunk from kernel command line,
  it is not used outside of arch/sh

* Move command line to dts

  This brings us one small step closer to sharing defconfig
  between mackerel and other boards

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/sh7372-mackerel.dts |    4 ++++
 arch/arm/configs/mackerel_defconfig   |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sh7372-mackerel.dts b/arch/arm/boot/dts/sh7372-mackerel.dts
index 286f0ca..2623de8 100644
--- a/arch/arm/boot/dts/sh7372-mackerel.dts
+++ b/arch/arm/boot/dts/sh7372-mackerel.dts
@@ -15,6 +15,10 @@
 	model = "Mackerel (AP4 EVM 2nd)";
 	compatible = "renesas,mackerel";
 
+	chosen {
+		bootargs = "console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp mem=240m rw";
+	};
+
 	memory {
 		device_type = "memory";
 		reg = <0x40000000 0x10000000>;
diff --git a/arch/arm/configs/mackerel_defconfig b/arch/arm/configs/mackerel_defconfig
index 2098ce1..e6881ac 100644
--- a/arch/arm/configs/mackerel_defconfig
+++ b/arch/arm/configs/mackerel_defconfig
@@ -23,7 +23,7 @@ CONFIG_AEABI=y
 CONFIG_FORCE_MAX_ZONEORDER=15
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp memchunk.vpu=64m memchunk.veu0=8m memchunk.spu0=2m mem=240m"
+CONFIG_ARM_APPENDED_DTB=y
 CONFIG_KEXEC=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_PM=y
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 2/5] ARM: mach-shmobile: fix memory size for kota2_defconfig
From: Simon Horman @ 2013-01-16  6:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358316146-12579-1-git-send-email-horms+renesas@verge.net.au>

The CONFIG_MEMORY_SIZE value is interpreted as a 32 bit integer, which
makes sense on a system without PAE. It appears that a trailing 0 was
appended to the value and after some testing it appears that 0x1e000000 is
the correct value.

Without this patch, building kota2_defconfig results in:

/home/arnd/linux-arm/arch/arm/kernel/setup.c:790:2: warning: large integer implicitly truncated to unsigned type [-Woverflow]

Reported-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/configs/kota2_defconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/kota2_defconfig b/arch/arm/configs/kota2_defconfig
index fa83db1..57ad3d4 100644
--- a/arch/arm/configs/kota2_defconfig
+++ b/arch/arm/configs/kota2_defconfig
@@ -21,7 +21,7 @@ CONFIG_ARCH_SHMOBILE=y
 CONFIG_KEYBOARD_GPIO_POLLED=y
 CONFIG_ARCH_SH73A0=y
 CONFIG_MACH_KOTA2=y
-CONFIG_MEMORY_SIZE=0x1e0000000
+CONFIG_MEMORY_SIZE=0x1e000000
 # CONFIG_SH_TIMER_TMU is not set
 # CONFIG_SWP_EMULATE is not set
 CONFIG_CPU_BPREDICT_DISABLE=y
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 3/5] ARM: mach-shmobile: kzm9g: defconfig update
From: Simon Horman @ 2013-01-16  6:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358316146-12579-1-git-send-email-horms+renesas@verge.net.au>

* Enable ARM_APPENDED_DTB

  Typically the bootloader of a kzm9g board does not support DT
  so this option is useful.

* Use voltage regulators by default

* Move command line to dts

  This brings us one small step closer to sharing defconfig
  between kzm9g and other boards

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/sh73a0-kzm9g.dts |    4 ++++
 arch/arm/configs/kzm9g_defconfig   |    4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts
index bcb9119..9a43879 100644
--- a/arch/arm/boot/dts/sh73a0-kzm9g.dts
+++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts
@@ -15,6 +15,10 @@
 	model = "KZM-A9-GT";
 	compatible = "renesas,kzm9g", "renesas,sh73a0";
 
+	chosen {
+		bootargs = "console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=sh-sci.4,115200";
+	};
+
 	memory {
 		device_type = "memory";
 		reg = <0x41000000 0x1e800000>;
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
index afbae28..670c3b6 100644
--- a/arch/arm/configs/kzm9g_defconfig
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -39,7 +39,7 @@ CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=sh-sci.4,115200"
+CONFIG_ARM_APPENDED_DTB=y
 CONFIG_KEXEC=y
 CONFIG_VFP=y
 CONFIG_NEON=y
@@ -85,6 +85,8 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_SH_MOBILE=y
 CONFIG_GPIO_PCF857X=y
 # CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DUMMY=y
 CONFIG_FB=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 4/5] ARM: mach-shmobile: armadillo: update defconfig
From: Simon Horman @ 2013-01-16  6:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358316146-12579-1-git-send-email-horms+renesas@verge.net.au>

* Enable ARM_APPENDED_DTB

  Typically the bootloader of an armadillo board does not support DT
  so this option is useful.

* Do not disable SUSPEND

  Suspend seems to work fine on the armadillo

* Enable PM_RUNTIME

  This also seems to work fine.

* Move command line to dts

  This brings us one small step closer to sharing defconfig
  between armadillo and other boards

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/r8a7740-armadillo800eva.dts |    4 ++++
 arch/arm/configs/armadillo800eva_defconfig    |    5 ++---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
index a7505a9..52cfead 100644
--- a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
@@ -15,6 +15,10 @@
 	model = "armadillo 800 eva";
 	compatible = "renesas,armadillo800eva";
 
+	chosen {
+		bootargs = "console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096 rw";
+	};
+
 	memory {
 		device_type = "memory";
 		reg = <0x40000000 0x20000000>;
diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
index 2e1a825..f9e2701 100644
--- a/arch/arm/configs/armadillo800eva_defconfig
+++ b/arch/arm/configs/armadillo800eva_defconfig
@@ -34,12 +34,11 @@ CONFIG_AEABI=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096 rw"
-CONFIG_CMDLINE_FORCE=y
+CONFIG_ARM_APPENDED_DTB=y
 CONFIG_KEXEC=y
 CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 5/5] ARM: mach-shmobile: kzm9d: update defconfig
From: Simon Horman @ 2013-01-16  6:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358316146-12579-1-git-send-email-horms+renesas@verge.net.au>

* Do not disable SUSPEND

  Suspend seems to work fine on the kzm9d.

  This is part of an effort reduce differences between mach-shmobile
  defconfigs with a view to using a common defconfig.

* Enable PM_RUNTIME

  This also seems to work fine on the kzm9d.

  This is part of an effort reduce differences between mach-shmobile
  defconfigs with a view to using a common defconfig.

* Move kernel command line from defconfig to dts.

  This brings us one small step closer to sharing defconfig
  between kzm9d and other boards.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/emev2-kzm9d.dts |    2 +-
 arch/arm/configs/kzm9d_defconfig  |    4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts
index 297e3ba..b9b3241 100644
--- a/arch/arm/boot/dts/emev2-kzm9d.dts
+++ b/arch/arm/boot/dts/emev2-kzm9d.dts
@@ -21,6 +21,6 @@
 	};
 
 	chosen {
-		bootargs = "console=ttyS1,115200n81";
+		bootargs = "console=tty0 console=ttyS1,115200n81 earlyprintk=serial8250-em.1,115200n81 mem=128M at 0x40000000 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096";
 	};
 };
diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig
index 8c49df6..6c37f4a 100644
--- a/arch/arm/configs/kzm9d_defconfig
+++ b/arch/arm/configs/kzm9d_defconfig
@@ -32,11 +32,9 @@ CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
-CONFIG_CMDLINE="console=tty0 console=ttyS1,115200n81 earlyprintk=serial8250-em.1,115200n81 mem=128M at 0x40000000 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
-CONFIG_CMDLINE_FORCE=y
 CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 15/16] ARM: vexpress/dcscb: handle platform coherency exit/setup and CCI
From: Santosh Shilimkar @ 2013-01-16  6:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130115182059.GB1983@linaro.org>

On Tuesday 15 January 2013 11:50 PM, Dave Martin wrote:
> On Tue, Jan 15, 2013 at 11:53:14AM +0530, Santosh Shilimkar wrote:
>> On Monday 14 January 2013 05:55 PM, Lorenzo Pieralisi wrote:
>>> On Sat, Jan 12, 2013 at 07:21:24AM +0000, Santosh Shilimkar wrote:
>>>> On Saturday 12 January 2013 12:58 AM, Nicolas Pitre wrote:
>>>>> On Fri, 11 Jan 2013, Santosh Shilimkar wrote:
>>>>>
>>>>>> On Thursday 10 January 2013 05:50 AM, Nicolas Pitre wrote:
>>>>>>> From: Dave Martin <dave.martin@linaro.org>
>>>>>>>
>>>>>>> +		/*
>>>>>>> +		 * Flush the local CPU cache.
>>>>>>> +		 *
>>>>>>> +		 * A15/A7 can hit in the cache with SCTLR.C=0, so we don't need
>>>>>>> +		 * a preliminary flush here for those CPUs.  At least, that's
>>>>>>> +		 * the theory -- without the extra flush, Linux explodes on
>>>>>>> +		 * RTSM (maybe not needed anymore, to be investigated).
>>>>>>> +		 */
>>>>>> This is expected if the entire code is not in one stack frame and the
>>>>>> additional flush is needed to avoid possible stack corruption. This
>>>>>> issue has been discussed in past on the list.
>>>>>
>>>>> I missed that.  Do you have a reference or pointer handy?
>>>>>
>>>>> What is strange is that this is 100% reproducible on RTSM while this
>>>>> apparently is not an issue on real hardware so far.
>>>>>
>>>> I tried searching archives and realized the discussion was in private
>>>> email thread. There are some bits and pieces on list but not all the
>>>> information.
>>>>
>>>> The main issue RMK pointed out is- An additional L1 flush needed
>>>> to avoid the effective change of view of memory when the C bit is
>>>> turned off, and the cache is no longer searched for local CPU accesses.
>>>>
>>>> In your case dcscb_power_down() has updated the stack which can be hit
>>>> in cache line and hence cache is dirty now. Then cpu_proc_fin() clears
>>>> the C-bit and hence for sub sequent calls the L1 cache won't be
>>>> searched. You then call flush_cache_all() which again updates the
>>>> stack but avoids searching the L1 cache. So it overwrites previous
>>>> saved stack frame. This seems to be an issue in your case as well.
>>>
>>> On A15/A7 even with the C bit cleared the D-cache is searched, the
>>> situation above cannot happen and if it does we are facing a HW/model bug.
>>> If this code is run on A9 then we have a problem since there, when the C bit
>>> is cleared D-cache is not searched (and that's why the sequence above
>>> should be written in assembly with no data access whatsoever), but on
>>> A15/A7 we do not.
>>>
>> Good point. May be model has modeled A9 and not A15 but in either
>> case, lets be consistent for all ARMv7 machines at least to avoid
>> people debugging similar issues. Many machines share code for ARMv7
>> processors so the best things is to stick to the sequence which works
>> across all ARMv7 processors.
>
> Is it sufficient to clarify the comment to indicate that the code is
> not directly reusable for other CPU combinations?
>
Thats not what I mean. CPU power down sequence is as per the
ARM specs so there shouldn't be an issue in case people
find it useful for other purposes. Thats other topc though.

> DCSCB is incredibly platform-specific, and we would not expect to
> see it in other platforms.
>
> Or do we consider the risk of people copying this code verbatim
> (including the "do not copy this code" comment) too high?
>
I am not sure what exactly you mean. We are discussing the sequence
here on the basis of additional L1 cache flush. As mentioned
clearly the documentation is the ARM ARM(which is generic for
all ARMv7) missing to capture the need of the power
down code and stack usage which at least creates an issue on
A9. Documenting that in code and mainly in ARM specs would avoid
any further confusions.

Regards,
Santosh

^ permalink raw reply

* [PATCH v2] serial: sirf: only use lookup table to set baudrate when ioclk=150MHz
From: Barry Song @ 2013-01-16  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Barry Song <Baohua.Song@csr.com>

The fast lookup table to set baudrate is only right when ioclk
is 150MHz. for most platforms, ioclk is 150MHz, but some boards
might set ioclk to other frequency.

so re-calc the clk_div_reg when ioclk is not 150MHz. this patch
also gets clk in probe and puts it in remove.

Signed-off-by: Barry Song <Baohua.Song@csr.com>
Cc: Russell King <linux@arm.linux.org.uk>
---
 -v2:
 1. Get the clock at probe or port initialization time. Save that pointer
 according to Russell King's feedback;
 2. rebase to tty/tty-next as this one has been applied:
 serial: sirf: add support for new SiRFmarco SMP SoC
 http://git.kernel.org/?p=linux/kernel/git/gregkh/tty.git;h=5425e0

 drivers/tty/serial/sirfsoc_uart.c |   28 +++++++++++++++++++++-------
 drivers/tty/serial/sirfsoc_uart.h |    1 +
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index 8f3d6c0..6bbfe99 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -357,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
 				       struct ktermios *old)
 {
 	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
-	unsigned long	ioclk_rate;
 	unsigned long	config_reg = 0;
 	unsigned long	baud_rate;
 	unsigned long	setted_baud;
@@ -369,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
 	int		threshold_div;
 	int		temp;
 
-	ioclk_rate = 150000000;
 	switch (termios->c_cflag & CSIZE) {
 	default:
 	case CS8:
@@ -425,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
 			sirfsoc_uart_disable_ms(port);
 	}
 
-	/* common rate: fast calculation */
-	for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++)
-		if (baud_rate == baudrate_to_regv[ic].baud_rate)
-			clk_div_reg = baudrate_to_regv[ic].reg_val;
+	if (port->uartclk == 150000000) {
+		/* common rate: fast calculation */
+		for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++)
+			if (baud_rate == baudrate_to_regv[ic].baud_rate)
+				clk_div_reg = baudrate_to_regv[ic].reg_val;
+	}
+
 	setted_baud = baud_rate;
 	/* arbitary rate setting */
 	if (unlikely(clk_div_reg == 0))
-		clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate,
+		clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk,
 								&setted_baud);
 	wr_regl(port, SIRFUART_DIVISOR, clk_div_reg);
 
@@ -691,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
 			goto err;
 	}
 
+	sirfport->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(sirfport->clk)) {
+		ret = PTR_ERR(sirfport->clk);
+		goto clk_err;
+	}
+	clk_prepare_enable(sirfport->clk);
+	port->uartclk = clk_get_rate(sirfport->clk);
+
 	port->ops = &sirfsoc_uart_ops;
 	spin_lock_init(&port->lock);
 
@@ -704,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
 	return 0;
 
 port_err:
+	clk_disable_unprepare(sirfport->clk);
+	clk_put(sirfport->clk);
+clk_err:
 	platform_set_drvdata(pdev, NULL);
 	if (sirfport->hw_flow_ctrl)
 		pinctrl_put(sirfport->p);
@@ -718,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 	if (sirfport->hw_flow_ctrl)
 		pinctrl_put(sirfport->p);
+	clk_disable_unprepare(sirfport->clk);
+	clk_put(sirfport->clk);
 	uart_remove_one_port(&sirfsoc_uart_drv, port);
 	return 0;
 }
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h
index 6431640..85328ba 100644
--- a/drivers/tty/serial/sirfsoc_uart.h
+++ b/drivers/tty/serial/sirfsoc_uart.h
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port {
 
 	struct uart_port		port;
 	struct pinctrl			*p;
+	struct clk			*clk;
 };
 
 /* Hardware Flow Control */
-- 
1.7.5.4



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

^ permalink raw reply related

* [RFC PATCH 3/4] ARM: bL_entry: Match memory barriers to architectural requirements
From: Santosh Shilimkar @ 2013-01-16  6:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358268498-8086-4-git-send-email-dave.martin@linaro.org>

+ Catalin, RMK

Dave,

On Tuesday 15 January 2013 10:18 PM, Dave Martin wrote:
> For architectural correctness even Strongly-Ordered memory accesses
> require barriers in order to guarantee that multiple CPUs have a
> coherent view of the ordering of memory accesses.
>
> Virtually everything done by this early code is done via explicit
> memory access only, so DSBs are seldom required.  Existing barriers
> are demoted to DMB, except where a DSB is needed to synchronise
> non-memory signalling (i.e., before a SEV).  If a particular
> platform performs cache maintenance in its power_up_setup function,
> it should force it to complete explicitly including a DSB, instead
> of relying on the bL_head framework code to do it.
>
> Some additional DMBs are added to ensure all the memory ordering
> properties required by the race avoidance algorithm.  DMBs are also
> moved out of loops, and for clarity some are moved so that most
> directly follow the memory operation which needs to be
> synchronised.
>
> The setting of a CPU's bL_entry_vectors[] entry is also required to
> act as a synchronisation point, so a DMB is added after checking
> that entry to ensure that other CPUs do not observe gated
> operations leaking across the opening of the gate.
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
> ---

Sorry to pick on this again but I am not able to understand why
the strongly ordered access needs barriers. At least from the
ARM point of view, a strongly ordered write will be more of blocking
write and the further interconnect also is suppose to respect that
rule. SO read writes are like adding barrier after every load store
so adding explicit barriers doesn't make sense. Is this a side
effect of some "write early response" kind of optimizations at
interconnect level ?
Will you be able to point to specs or documents which puts
this requirement ?

Regards
santosh

^ permalink raw reply

* [PATCH 4/4] serial: tty: Cleanup code using devm_ function
From: Greg Kroah-Hartman @ 2013-01-16  6:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358225886-5686-5-git-send-email-linux@prisktech.co.nz>

On Tue, Jan 15, 2013 at 05:58:06PM +1300, Tony Prisk wrote:
> Convert the last memory allocation (vt8500_port) to use devm_kzalloc
> and remove the fail path cleanup code from vt8500_serial_probe.
> 
> Reorder iomem mapping above clk_enable to simplify fail code. The
> clock is only enabled if all other resources are available.
> 
> Signed-off-by: Tony Prisk <linux@prisktech.co.nz>

You've send a few different versions of this patch, with no indication
as to what changed, or what one I should take.  Care to send me the
correct one?

thanks,

greg k-h

^ permalink raw reply

* [RFC PATCH 0/7] usb: musb: add driver for control module
From: Felipe Balbi @ 2013-01-16  7:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50F6423C.2020307@ti.com>

On Wed, Jan 16, 2013 at 11:31:32AM +0530, kishon wrote:
> Hi Ravi,
> 
> On Tuesday 15 January 2013 09:36 PM, B, Ravi wrote:
> >>Hi,
> >>
> >>On Tue, Jan 15, 2013 at 08:09:22PM +0530, kishon wrote:
> >>>Hi Arnd,
> >>>
> >>>On Tuesday 15 January 2013 07:11 PM, Arnd Bergmann wrote:
> >>>>On Tuesday 15 January 2013, Kishon Vijay Abraham I wrote:
> >>>>>Added a new driver for the usb part of control module.
> >>This has an
> >>>>>API to power on the USB2 phy and an API to write to the mailbox
> >>>>>depending on whether MUSB has to act in host mode or in
> >>device mode.
> >>>>>
> >>>>>Writing to control module registers for doing the above
> >>task which
> >>>>>was previously done in omap glue and in omap-usb2 phy is removed.
> >>>>>
> >>>>>Also added the dt data to get MUSB working in OMAP platforms.
> >>>>>This series has patches for both drivers and ARCH
> >>folders, so If it
> >>>>>has to be split I'll do it.
> >>>>>
> >>>>
> >>>>The series looks good to me, I just had a minor comment on
> >>one patch.
> >>>>
> >>>>One a somewhat related topic, I wonder whether there are
> >>any plans on
> >>>>your side to change this driver to support multiple bus
> >>glues to be
> >>>>built for one kernel image. With a multiplatform kernel,
> >>we may need
> >>>>all of TUSB6010/OMAP2PLUS/DSPS/UX500 for instance.
> >>>
> >>>We don't have plans as of now. I actually don't expect any
> >>changes in
> >>>the driver other than the Kconfig changes. Anyways the
> >>probe of glue's
> >>>other than the platform it's running won't get called. right Felipe?
> >
> >If understand correctly the control module driver used to configure the respective usb phy of SoC to respective usb modes using the common set of control module APIs.
> What if, if control module interface (register defintions) varies b/w
> different revision or spin of same type of SoCs, if usbphy type is
> changed.
> Well in that case, we can write to the registers based on the IP
> revision check (I think thats the common practice to do).
> 
> In this case whether the single instance of control module driver is
> good enough to cater of all cpu types of same SoC series ?
> Of course. I don't see why we can't have the same driver to handle
> different versions of the same IP.
> The only reason where we might need multiple instance is if the SoC
> have multiple control module which Arnd already pointed out.
> 
> >Whether cpu_is_xxx() can be used to differentiate b/w different cpu types in CM driver?
> Not needed at all IMHO. We can use revision register to differentiate.
> 
> Btw I think Felipe looped you for a different reason ;-)

right, it was to look at removing <mach/*> inclusion from all
davinci-link glue layers (they should be combined, btw).

-- 
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/20130116/6cf028ad/attachment.sig>

^ permalink raw reply

* [GIT PULL] irqchip init infrastructure and GIC/VIC move
From: Rob Herring @ 2013-01-16  7:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOesGMgrAdvRqrnanfRD1gvJ-4O6pT1n2ZR+TCZADjD1ED_+UA@mail.gmail.com>

On 01/14/2013 09:56 PM, Olof Johansson wrote:
> On Sat, Jan 12, 2013 at 9:37 AM, Rob Herring <robherring2@gmail.com> wrote:
>> Arnd, Olof,
>>
>> Please pull for 3.9. This is the initial infrastructure and conversion
>> of the GIC and VIC to use it. Several people are waiting for the irqchip
>> infrastructure to go in in order to convert other irqchip code over.
>>
>> I've left "static asmlinkage" in on the irq handlers. There's been no
>> more discussion, so I think we are in agreement. If asmlinkage defines
>> the procedure call convention for assembly calls, then it still makes
>> sense to have it on a static function called thru a function pointer.
>>
>> Rob
>>
>> The following changes since commit 9931faca02c604c22335f5a935a501bb2ace6e20:
>>
>>   Linux 3.8-rc3 (2013-01-09 18:59:55 -0800)
>>
>> are available in the git repository at:
>>
>>   git://sources.calxeda.com/kernel/linux.git tags/gic-vic-to-irqchip
> 
> Ugh. This conflicts heavily with the timer cleanup from Stephen, due
> to adjacent changes in the machine descriptors.
> 
> I fixed them up, but I would appreciate a second glance at them for
> sanity checking.

Sorry about that. It all looks correct to me.

Rob

^ permalink raw reply

* [PATCH v2 03/10] ARM: dt: tegra30: Add clock information
From: Terje Bergström @ 2013-01-16  8:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1357891289-23500-3-git-send-email-pgaikwad@nvidia.com>

On 11.01.2013 10:01, Prashant Gaikwad wrote:
> diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
> index 6765646..c3e129a 100644
> --- a/arch/arm/boot/dts/tegra30.dtsi
> +++ b/arch/arm/boot/dts/tegra30.dtsi
>  		gr3d {
>  			compatible = "nvidia,tegra30-gr3d";
>  			reg = <0x54180000 0x00040000>;
> +			clocks = <&tegra_car 24>;
>  		};

In Tegra3, 3D has two clocks. I believe you'd need to add <&tegra_car
98> here.

Terje

^ permalink raw reply

* [PATCH V4 0/5] ARM: tegra20: cpuidle: add power-down state
From: Joseph Lo @ 2013-01-16  8:10 UTC (permalink / raw)
  To: linux-arm-kernel

This adds a "powered-down" state in cpuidle for Tegra20. It requires power
gating both CPU cores. When the CPU1 requests to enter "powered-down"
state, it saves its own state and then enters WFI. When the CPU0 requests
the same state, it attempts to put the CPU1 into reset to prevent it from
waking up. Then power down both CPUs together and turn off the CPU rail.

If the CPU1 be woken up before CPU0 entering powered-down state, then it
needs to restore it's CPU state and waits for next chance.

V4:
* rebased on next-20130114 + Tegra-ccf-rework-v4

V3:
* sqash the last 2 patches in previors version to support coupled cpuidle
  directly

V2:
* add a new patch for checking if there is any pending SGI
* if there is a SGI pending for the CPU, then we will abort the
  "powered-down" idle for the both CPUs that already in coupled state

Verified on Seaboard(Tegra20) and Cardhu(Tegra30).

Joseph Lo (5):
  ARM: tegra: add pending SGI checking API
  ARM: tegra20: cpuidle: add powered-down state for secondary CPU
  clk: tegra20: Implementing CPU low-power function for
    tegra_cpu_car_ops
  ARM: tegra20: flowctrl: add support for cpu_suspend_enter/exit
  ARM: tegra20: cpuidle: apply coupled cpuidle for powered-down mode

 arch/arm/mach-tegra/Kconfig           |   1 +
 arch/arm/mach-tegra/cpuidle-tegra20.c | 197 ++++++++++++++++++++++++++++++++-
 arch/arm/mach-tegra/flowctrl.c        |  38 ++++++-
 arch/arm/mach-tegra/flowctrl.h        |   4 +
 arch/arm/mach-tegra/irq.c             |  15 +++
 arch/arm/mach-tegra/irq.h             |  22 ++++
 arch/arm/mach-tegra/pm.c              |   3 +
 arch/arm/mach-tegra/sleep-tegra20.S   | 200 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-tegra/sleep.S           |  19 ++++
 arch/arm/mach-tegra/sleep.h           |  26 +++++
 drivers/clk/tegra/clk-tegra20.c       |  93 ++++++++++++++++
 11 files changed, 609 insertions(+), 9 deletions(-)
 create mode 100644 arch/arm/mach-tegra/irq.h

-- 
1.8.0.3

^ permalink raw reply

* [PATCH V4 1/5] ARM: tegra: add pending SGI checking API
From: Joseph Lo @ 2013-01-16  8:10 UTC (permalink / raw)
  To: linux-arm-kernel

The "powered-down" CPU idle mode of Tegra cut off the vdd_cpu rail, it
include the power of GIC. That caused the SGI (Software Generated
Interrupt) been lost. Because the SGI can't wake up the CPU that in
the "powered-down" CPU idle mode. We need to check if there is any
pending SGI when go into "powered-down" CPU idle mode. This is important
especially when applying the coupled cpuidle framework into "power-down"
cpuidle dirver. Because the coupled cpuidle framework may have the
chance that misses IPI_SINGLE_FUNC handling sometimes.

For the PPI or SPI, something like the legacy peripheral interrupt. It
still can be maintained by Tegra legacy interrupt controller. If there
is any pending PPI or SPI when CPU in "powered-down" CPU idle mode. The
CPU can be woken up immediately. So we don't need to take care the same
situation for PPI or SPI.

Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V4:
* no change
V3:
* move the static mapping of GIC addr into tegra_pending_sgi
V2:
* new in V2
---
 arch/arm/mach-tegra/irq.c | 15 +++++++++++++++
 arch/arm/mach-tegra/irq.h | 22 ++++++++++++++++++++++
 2 files changed, 37 insertions(+)
 create mode 100644 arch/arm/mach-tegra/irq.h

diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index b7886f1..c9976e3 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -45,6 +45,8 @@
 
 #define FIRST_LEGACY_IRQ 32
 
+#define SGI_MASK 0xFFFF
+
 static int num_ictlrs;
 
 static void __iomem *ictlr_reg_base[] = {
@@ -55,6 +57,19 @@ static void __iomem *ictlr_reg_base[] = {
 	IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
 };
 
+bool tegra_pending_sgi(void)
+{
+	u32 pending_set;
+	void __iomem *distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
+
+	pending_set = readl_relaxed(distbase + GIC_DIST_PENDING_SET);
+
+	if (pending_set & SGI_MASK)
+		return true;
+
+	return false;
+}
+
 static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
 {
 	void __iomem *base;
diff --git a/arch/arm/mach-tegra/irq.h b/arch/arm/mach-tegra/irq.h
new file mode 100644
index 0000000..5142649
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012, NVIDIA Corporation. All rights reserved.
+ *
+ * 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/>.
+ */
+
+#ifndef __TEGRA_IRQ_H
+#define __TEGRA_IRQ_H
+
+bool tegra_pending_sgi(void);
+
+#endif
-- 
1.8.0.3

^ permalink raw reply related

* [PATCH V4 2/5] ARM: tegra20: cpuidle: add powered-down state for secondary CPU
From: Joseph Lo @ 2013-01-16  8:10 UTC (permalink / raw)
  To: linux-arm-kernel

The powered-down state of Tegra20 requires power gating both CPU cores.
When the secondary CPU requests to enter powered-down state, it saves
its own contexts and then enters WFI. The Tegra20 had a limition to
power down both CPU cores. The secondary CPU must waits for CPU0 in
powered-down state too. If the secondary CPU be woken up before CPU0
entering powered-down state, then it needs to restore its CPU states
and waits for next chance.

Be aware of that, you may see the legacy power state "LP2" in the code
which is exactly the same meaning of "CPU power down".

Based on the work by:
Colin Cross <ccross@android.com>
Gary King <gking@nvidia.com>

Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V4:
* remove the for loop to copy idle state
* add a checking in tegra_set_cpu_in_lp2 when it is Tegra20
V3:
* dynamic checking of the number of the state counts
* fix the code sequence for aborting cpu_suspend in
  tegra20_sleep_cpu_secondary_finish
V2:
* no change
---
 arch/arm/mach-tegra/cpuidle-tegra20.c |  90 ++++++++++++++++++++-
 arch/arm/mach-tegra/pm.c              |   3 +
 arch/arm/mach-tegra/sleep-tegra20.S   | 147 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-tegra/sleep.h           |  23 ++++++
 4 files changed, 259 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index d32e8b0..50f984d 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -22,21 +22,99 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/clockchips.h>
 
 #include <asm/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <asm/suspend.h>
+#include <asm/smp_plat.h>
+
+#include "pm.h"
+#include "sleep.h"
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra20_idle_lp2(struct cpuidle_device *dev,
+			    struct cpuidle_driver *drv,
+			    int index);
+#endif
+
+static struct cpuidle_state tegra_idle_states[] = {
+	[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
+#ifdef CONFIG_PM_SLEEP
+	[1] = {
+		.enter			= tegra20_idle_lp2,
+		.exit_latency		= 5000,
+		.target_residency	= 10000,
+		.power_usage		= 0,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "powered-down",
+		.desc			= "CPU power gated",
+	},
+#endif
+};
 
 static struct cpuidle_driver tegra_idle_driver = {
 	.name = "tegra_idle",
 	.owner = THIS_MODULE,
 	.en_core_tk_irqen = 1,
-	.state_count = 1,
-	.states = {
-		[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
-	},
 };
 
 static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
 
+#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_SMP
+static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
+					 struct cpuidle_driver *drv,
+					 int index)
+{
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+
+	cpu_suspend(0, tegra20_sleep_cpu_secondary_finish);
+
+	tegra20_cpu_clear_resettable();
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+
+	return true;
+}
+#else
+static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
+						struct cpuidle_driver *drv,
+						int index)
+{
+	return true;
+}
+#endif
+
+static int tegra20_idle_lp2(struct cpuidle_device *dev,
+			    struct cpuidle_driver *drv,
+			    int index)
+{
+	u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
+	bool entered_lp2 = false;
+
+	local_fiq_disable();
+
+	tegra_set_cpu_in_lp2(cpu);
+	cpu_pm_enter();
+
+	if (cpu == 0)
+		cpu_do_idle();
+	else
+		entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
+
+	cpu_pm_exit();
+	tegra_clear_cpu_in_lp2(cpu);
+
+	local_fiq_enable();
+
+	smp_rmb();
+
+	return entered_lp2 ? index : 0;
+}
+#endif
+
 int __init tegra20_cpuidle_init(void)
 {
 	int ret;
@@ -44,6 +122,10 @@ int __init tegra20_cpuidle_init(void)
 	struct cpuidle_device *dev;
 	struct cpuidle_driver *drv = &tegra_idle_driver;
 
+	drv->state_count = ARRAY_SIZE(tegra_idle_states);
+	memcpy(drv->states, tegra_idle_states,
+			drv->state_count * sizeof(drv->states[0]));
+
 	ret = cpuidle_register_driver(&tegra_idle_driver);
 	if (ret) {
 		pr_err("CPUidle driver registration failed\n");
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index abfe9b9..523604d 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -36,6 +36,7 @@
 #include "iomap.h"
 #include "reset.h"
 #include "flowctrl.h"
+#include "fuse.h"
 #include "sleep.h"
 
 #define TEGRA_POWER_CPU_PWRREQ_OE	(1 << 16)  /* CPU pwr req enable */
@@ -173,6 +174,8 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id)
 
 	if ((phy_cpu_id == 0) && cpumask_equal(cpu_lp2_mask, cpu_online_mask))
 		last_cpu = true;
+	else if (tegra_chip_id == TEGRA20 && phy_cpu_id == 1)
+		tegra20_cpu_set_resettable_soon();
 
 	spin_unlock(&tegra_lp2_lock);
 	return last_cpu;
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index ad2ca07..1074364 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -21,6 +21,8 @@
 #include <linux/linkage.h>
 
 #include <asm/assembler.h>
+#include <asm/proc-fns.h>
+#include <asm/cp15.h>
 
 #include "sleep.h"
 #include "flowctrl.h"
@@ -75,3 +77,148 @@ ENTRY(tegra20_cpu_shutdown)
 	mov	pc, lr
 ENDPROC(tegra20_cpu_shutdown)
 #endif
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * tegra_pen_lock
+ *
+ * spinlock implementation with no atomic test-and-set and no coherence
+ * using Peterson's algorithm on strongly-ordered registers
+ * used to synchronize a cpu waking up from wfi with entering lp2 on idle
+ *
+ * The reference link of Peterson's algorithm:
+ * http://en.wikipedia.org/wiki/Peterson's_algorithm
+ *
+ * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
+ * on cpu 0:
+ * r2 = flag[0] (in SCRATCH38)
+ * r3 = flag[1] (in SCRATCH39)
+ * on cpu1:
+ * r2 = flag[1] (in SCRATCH39)
+ * r3 = flag[0] (in SCRATCH38)
+ *
+ * must be called with MMU on
+ * corrupts r0-r3, r12
+ */
+ENTRY(tegra_pen_lock)
+	mov32	r3, TEGRA_PMC_VIRT
+	cpu_id	r0
+	add	r1, r3, #PMC_SCRATCH37
+	cmp	r0, #0
+	addeq	r2, r3, #PMC_SCRATCH38
+	addeq	r3, r3, #PMC_SCRATCH39
+	addne	r2, r3, #PMC_SCRATCH39
+	addne	r3, r3, #PMC_SCRATCH38
+
+	mov	r12, #1
+	str	r12, [r2]		@ flag[cpu] = 1
+	dsb
+	str	r12, [r1]		@ !turn = cpu
+1:	dsb
+	ldr	r12, [r3]
+	cmp	r12, #1			@ flag[!cpu] == 1?
+	ldreq	r12, [r1]
+	cmpeq	r12, r0			@ !turn == cpu?
+	beq	1b			@ while !turn == cpu && flag[!cpu] == 1
+
+	mov	pc, lr			@ locked
+ENDPROC(tegra_pen_lock)
+
+ENTRY(tegra_pen_unlock)
+	dsb
+	mov32	r3, TEGRA_PMC_VIRT
+	cpu_id	r0
+	cmp	r0, #0
+	addeq	r2, r3, #PMC_SCRATCH38
+	addne	r2, r3, #PMC_SCRATCH39
+	mov	r12, #0
+	str	r12, [r2]
+	mov     pc, lr
+ENDPROC(tegra_pen_unlock)
+
+/*
+ * tegra20_cpu_clear_resettable(void)
+ *
+ * Called to clear the "resettable soon" flag in PMC_SCRATCH41 when
+ * it is expected that the secondary CPU will be idle soon.
+ */
+ENTRY(tegra20_cpu_clear_resettable)
+	mov32	r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	mov	r12, #CPU_NOT_RESETTABLE
+	str	r12, [r1]
+	mov	pc, lr
+ENDPROC(tegra20_cpu_clear_resettable)
+
+/*
+ * tegra20_cpu_set_resettable_soon(void)
+ *
+ * Called to set the "resettable soon" flag in PMC_SCRATCH41 when
+ * it is expected that the secondary CPU will be idle soon.
+ */
+ENTRY(tegra20_cpu_set_resettable_soon)
+	mov32	r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	mov	r12, #CPU_RESETTABLE_SOON
+	str	r12, [r1]
+	mov	pc, lr
+ENDPROC(tegra20_cpu_set_resettable_soon)
+
+/*
+ * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
+ *
+ * Enters WFI on secondary CPU by exiting coherency.
+ */
+ENTRY(tegra20_sleep_cpu_secondary_finish)
+	stmfd	sp!, {r4-r11, lr}
+
+	mrc	p15, 0, r11, c1, c0, 1  @ save actlr before exiting coherency
+
+	/* Flush and disable the L1 data cache */
+	bl	tegra_disable_clean_inv_dcache
+
+	mov32	r0, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	mov	r3, #CPU_RESETTABLE
+	str	r3, [r0]
+
+	bl	cpu_do_idle
+
+	/*
+	 * cpu may be reset while in wfi, which will return through
+	 * tegra_resume to cpu_resume
+	 * or interrupt may wake wfi, which will return here
+	 * cpu state is unchanged - MMU is on, cache is on, coherency
+	 * is off, and the data cache is off
+	 *
+	 * r11 contains the original actlr
+	 */
+
+	bl	tegra_pen_lock
+
+	mov32	r3, TEGRA_PMC_VIRT
+	add	r0, r3, #PMC_SCRATCH41
+	mov	r3, #CPU_NOT_RESETTABLE
+	str	r3, [r0]
+
+	bl	tegra_pen_unlock
+
+	/* Re-enable the data cache */
+	mrc	p15, 0, r10, c1, c0, 0
+	orr	r10, r10, #CR_C
+	mcr	p15, 0, r10, c1, c0, 0
+	isb
+
+	mcr	p15, 0, r11, c1, c0, 1	@ reenable coherency
+
+	/* Invalidate the TLBs & BTAC */
+	mov	r1, #0
+	mcr	p15, 0, r1, c8, c3, 0	@ invalidate shared TLBs
+	mcr	p15, 0, r1, c7, c1, 6	@ invalidate shared BTAC
+	dsb
+	isb
+
+	/* the cpu was running with coherency disabled,
+	 * caches may be out of date */
+	bl	v7_flush_kern_cache_louis
+
+	ldmfd	sp!, {r4 - r11, pc}
+ENDPROC(tegra20_sleep_cpu_secondary_finish)
+#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 56505c3..e39a56b 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -25,6 +25,19 @@
 					+ IO_PPSB_VIRT)
 #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
 					+ IO_PPSB_VIRT)
+#define TEGRA_PMC_VIRT	(TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
+
+/* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
+#define PMC_SCRATCH37	0x130
+#define PMC_SCRATCH38	0x134
+#define PMC_SCRATCH39	0x138
+#define PMC_SCRATCH41	0x140
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define CPU_RESETTABLE		2
+#define CPU_RESETTABLE_SOON	1
+#define CPU_NOT_RESETTABLE	0
+#endif
 
 #ifdef __ASSEMBLY__
 /* returns the offset of the flow controller halt register for a cpu */
@@ -104,6 +117,8 @@ exit_l2_resume:
 .endm
 #endif /* CONFIG_CACHE_L2X0 */
 #else
+void tegra_pen_lock(void);
+void tegra_pen_unlock(void);
 void tegra_resume(void);
 int tegra_sleep_cpu_finish(unsigned long);
 void tegra_disable_clean_inv_dcache(void);
@@ -116,6 +131,14 @@ static inline void tegra20_hotplug_init(void) {}
 static inline void tegra30_hotplug_init(void) {}
 #endif
 
+void tegra20_cpu_clear_resettable(void);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+void tegra20_cpu_set_resettable_soon(void);
+#else
+static inline void tegra20_cpu_set_resettable_soon(void) {}
+#endif
+
+int tegra20_sleep_cpu_secondary_finish(unsigned long);
 int tegra30_sleep_cpu_secondary_finish(unsigned long);
 void tegra30_tear_down_cpu(void);
 
-- 
1.8.0.3

^ permalink raw reply related

* [PATCH V4 3/5] clk: tegra20: Implementing CPU low-power function for tegra_cpu_car_ops
From: Joseph Lo @ 2013-01-16  8:10 UTC (permalink / raw)
  To: linux-arm-kernel

Implementing suspend, resume and rail_off_ready API for tegra_cpu_car_ops. These
functions were used for CPU powered-down state maintenance.

Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V4:
* rebased on Tegra-ccf-rework-v4
V3:
* no change
V2:
* refine the code sequence in "tegra20_cpu_rail_off_ready"
---
 drivers/clk/tegra/clk-tegra20.c | 93 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 9383b85..cb6971d 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/clk/tegra.h>
+#include <linux/delay.h>
 
 #include "clk.h"
 
@@ -104,6 +105,13 @@
 #define SUPER_SCLK_DIVIDER 0x2c
 #define CLK_SYSTEM_RATE 0x30
 
+#define CCLK_BURST_POLICY_SHIFT	28
+#define CCLK_RUN_POLICY_SHIFT	4
+#define CCLK_IDLE_POLICY_SHIFT	0
+#define CCLK_IDLE_POLICY	1
+#define CCLK_RUN_POLICY		2
+#define CCLK_BURST_POLICY_PLLX	8
+
 #define CLK_SOURCE_I2S1 0x100
 #define CLK_SOURCE_I2S2 0x104
 #define CLK_SOURCE_SPDIF_OUT 0x108
@@ -169,6 +177,17 @@
 #define CPU_CLOCK(cpu)	(0x1 << (8 + cpu))
 #define CPU_RESET(cpu)	(0x1111ul << (cpu))
 
+#ifdef CONFIG_PM_SLEEP
+static struct cpu_clk_suspend_context {
+	u32 pllx_misc;
+	u32 pllx_base;
+
+	u32 cpu_burst;
+	u32 clk_csite_src;
+	u32 cclk_divider;
+} tegra20_cpu_clk_sctx;
+#endif
+
 static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
 
 static void __iomem *clk_base;
@@ -1121,12 +1140,86 @@ static void tegra20_disable_cpu_clock(u32 cpu)
 	       clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static bool tegra20_cpu_rail_off_ready(void)
+{
+	unsigned int cpu_rst_status;
+
+	cpu_rst_status = readl(clk_base +
+			       TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET);
+
+	return !!(cpu_rst_status & 0x2);
+}
+
+static void tegra20_cpu_clock_suspend(void)
+{
+	/* switch coresite to clk_m, save off original source */
+	tegra20_cpu_clk_sctx.clk_csite_src =
+				readl(clk_base + CLK_SOURCE_CSITE);
+	writel(3<<30, clk_base + CLK_SOURCE_CSITE);
+
+	tegra20_cpu_clk_sctx.cpu_burst =
+				readl(clk_base + CCLK_BURST_POLICY);
+	tegra20_cpu_clk_sctx.pllx_base =
+				readl(clk_base + PLLX_BASE);
+	tegra20_cpu_clk_sctx.pllx_misc =
+				readl(clk_base + PLLX_MISC);
+	tegra20_cpu_clk_sctx.cclk_divider =
+				readl(clk_base + SUPER_CCLK_DIVIDER);
+}
+
+static void tegra20_cpu_clock_resume(void)
+{
+	unsigned int reg, policy;
+
+	/* Is CPU complex already running on PLLX? */
+	reg = readl(clk_base + CCLK_BURST_POLICY);
+	policy = (reg >> CCLK_BURST_POLICY_SHIFT) & 0xF;
+
+	if (policy == CCLK_IDLE_POLICY)
+		reg = (reg >> CCLK_IDLE_POLICY_SHIFT) & 0xF;
+	else if (policy == CCLK_RUN_POLICY)
+		reg = (reg >> CCLK_RUN_POLICY_SHIFT) & 0xF;
+	else
+		BUG();
+
+	if (reg != CCLK_BURST_POLICY_PLLX) {
+		/* restore PLLX settings if CPU is on different PLL */
+		writel(tegra20_cpu_clk_sctx.pllx_misc,
+					clk_base + PLLX_MISC);
+		writel(tegra20_cpu_clk_sctx.pllx_base,
+					clk_base + PLLX_BASE);
+
+		/* wait for PLL stabilization if PLLX was enabled */
+		if (tegra20_cpu_clk_sctx.pllx_base & (1 << 30))
+			udelay(300);
+	}
+
+	/*
+	 * Restore original burst policy setting for calls resulting from CPU
+	 * LP2 in idle or system suspend.
+	 */
+	writel(tegra20_cpu_clk_sctx.cclk_divider,
+					clk_base + SUPER_CCLK_DIVIDER);
+	writel(tegra20_cpu_clk_sctx.cpu_burst,
+					clk_base + CCLK_BURST_POLICY);
+
+	writel(tegra20_cpu_clk_sctx.clk_csite_src,
+					clk_base + CLK_SOURCE_CSITE);
+}
+#endif
+
 static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
 	.wait_for_reset	= tegra20_wait_cpu_in_reset,
 	.put_in_reset	= tegra20_put_cpu_in_reset,
 	.out_of_reset	= tegra20_cpu_out_of_reset,
 	.enable_clock	= tegra20_enable_cpu_clock,
 	.disable_clock	= tegra20_disable_cpu_clock,
+#ifdef CONFIG_PM_SLEEP
+	.rail_off_ready = tegra20_cpu_rail_off_ready,
+	.suspend	= tegra20_cpu_clock_suspend,
+	.resume		= tegra20_cpu_clock_resume,
+#endif
 };
 
 static __initdata struct tegra_clk_init_table init_table[] = {
-- 
1.8.0.3

^ permalink raw reply related

* [PATCH V4 4/5] ARM: tegra20: flowctrl: add support for cpu_suspend_enter/exit
From: Joseph Lo @ 2013-01-16  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

The flow controller can help CPU to go into suspend mode (powered-down
state). When CPU go into powered-down state, it needs some careful
settings before getting into and after leaving. The enter and exit
functions do that by configuring appropriate mode for flow controller.

Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V4:
* no change
V3:
* no change
V2:
* no change
---
 arch/arm/mach-tegra/flowctrl.c | 38 +++++++++++++++++++++++++++++++++-----
 arch/arm/mach-tegra/flowctrl.h |  4 ++++
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-tegra/flowctrl.c b/arch/arm/mach-tegra/flowctrl.c
index 5393eb2..b477ef3 100644
--- a/arch/arm/mach-tegra/flowctrl.c
+++ b/arch/arm/mach-tegra/flowctrl.c
@@ -25,6 +25,7 @@
 
 #include "flowctrl.h"
 #include "iomap.h"
+#include "fuse.h"
 
 static u8 flowctrl_offset_halt_cpu[] = {
 	FLOW_CTRL_HALT_CPU0_EVENTS,
@@ -75,11 +76,26 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
 	int i;
 
 	reg = flowctrl_read_cpu_csr(cpuid);
-	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;	/* clear wfe bitmap */
-	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;	/* clear wfi bitmap */
+	switch (tegra_chip_id) {
+	case TEGRA20:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
+		/* pwr gating on wfe */
+		reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid;
+		break;
+	case TEGRA30:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
+		/* pwr gating on wfi */
+		reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;
+		break;
+	}
 	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr flag */
 	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event flag */
-	reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid;	/* pwr gating on wfi */
 	reg |= FLOW_CTRL_CSR_ENABLE;			/* pwr gating */
 	flowctrl_write_cpu_csr(cpuid, reg);
 
@@ -99,8 +115,20 @@ void flowctrl_cpu_suspend_exit(unsigned int cpuid)
 
 	/* Disable powergating via flow controller for CPU0 */
 	reg = flowctrl_read_cpu_csr(cpuid);
-	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;	/* clear wfe bitmap */
-	reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;	/* clear wfi bitmap */
+	switch (tegra_chip_id) {
+	case TEGRA20:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP;
+		break;
+	case TEGRA30:
+		/* clear wfe bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
+		/* clear wfi bitmap */
+		reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP;
+		break;
+	}
 	reg &= ~FLOW_CTRL_CSR_ENABLE;			/* clear enable */
 	reg |= FLOW_CTRL_CSR_INTR_FLAG;			/* clear intr */
 	reg |= FLOW_CTRL_CSR_EVENT_FLAG;		/* clear event */
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
index 0798dec..67eab56 100644
--- a/arch/arm/mach-tegra/flowctrl.h
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -34,6 +34,10 @@
 #define FLOW_CTRL_HALT_CPU1_EVENTS	0x14
 #define FLOW_CTRL_CPU1_CSR		0x18
 
+#define TEGRA20_FLOW_CTRL_CSR_WFE_CPU0		(1 << 4)
+#define TEGRA20_FLOW_CTRL_CSR_WFE_BITMAP	(3 << 4)
+#define TEGRA20_FLOW_CTRL_CSR_WFI_BITMAP	0
+
 #define TEGRA30_FLOW_CTRL_CSR_WFI_CPU0		(1 << 8)
 #define TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP	(0xF << 4)
 #define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP	(0xF << 8)
-- 
1.8.0.3

^ permalink raw reply related

* [PATCH V4 5/5] ARM: tegra20: cpuidle: apply coupled cpuidle for powered-down mode
From: Joseph Lo @ 2013-01-16  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

The "powered-down" cpuidle mode of Tegra20 needs the CPU0 be the last one
core to go into this mode before other core. The coupled cpuidle framework
can help to sync the MPCore to coupled state then go into "powered-down"
idle mode together. The driver can just assume the MPCore come into
"powered-down" mode at the same time. No need to take care if the CPU_0
goes into this mode along and only can put it into safe idle mode (WFI).

The powered-down state of Tegra20 requires power gating both CPU cores.
When the secondary CPU requests to enter powered-down state, it saves
its own contexts and then enters WFI for waiting CPU0 in the same state.
When the CPU0 requests powered-down state, it attempts to put the secondary
CPU into reset to prevent it from waking up. Then power down both CPUs
together and power off the cpu rail.

Be aware of that, you may see the legacy power state "LP2" in the code
which is exactly the same meaning of "CPU power down".

Based on the work by:
Colin Cross <ccross@android.com>
Gary King <gking@nvidia.com>

Signed-off-by: Joseph Lo <josephl@nvidia.com>
---
V4:
* rename the function to "tegra20_wake_cpu1_from_reset"
* make the coupled cpuidle can be disabled if SMP is disabled
V3:
* sqash last two patch in previous version to support coupled cpuidle
  directly
V2:
* refine the cpu control function that dedicate for CPU_1
* rename "tegra_cpu_pllp" to "tegra_switch_cpu_to_pllp"
---
 arch/arm/mach-tegra/Kconfig           |   1 +
 arch/arm/mach-tegra/cpuidle-tegra20.c | 125 +++++++++++++++++++++++++++++++---
 arch/arm/mach-tegra/sleep-tegra20.S   |  53 ++++++++++++++
 arch/arm/mach-tegra/sleep.S           |  19 ++++++
 arch/arm/mach-tegra/sleep.h           |   3 +
 5 files changed, 192 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 1ec7f80..abc688f 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -4,6 +4,7 @@ comment "NVIDIA Tegra options"
 
 config ARCH_TEGRA_2x_SOC
 	bool "Enable support for Tegra20 family"
+	select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_742230 if SMP
diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
index 50f984d..63ab9c2 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
@@ -24,6 +24,7 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/clockchips.h>
+#include <linux/clk/tegra.h>
 
 #include <asm/cpuidle.h>
 #include <asm/proc-fns.h>
@@ -32,22 +33,28 @@
 
 #include "pm.h"
 #include "sleep.h"
+#include "iomap.h"
+#include "irq.h"
+#include "flowctrl.h"
 
 #ifdef CONFIG_PM_SLEEP
-static int tegra20_idle_lp2(struct cpuidle_device *dev,
-			    struct cpuidle_driver *drv,
-			    int index);
+static atomic_t abort_flag;
+static atomic_t abort_barrier;
+static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
+				    struct cpuidle_driver *drv,
+				    int index);
 #endif
 
 static struct cpuidle_state tegra_idle_states[] = {
 	[0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
 #ifdef CONFIG_PM_SLEEP
 	[1] = {
-		.enter			= tegra20_idle_lp2,
+		.enter			= tegra20_idle_lp2_coupled,
 		.exit_latency		= 5000,
 		.target_residency	= 10000,
 		.power_usage		= 0,
-		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.flags			= CPUIDLE_FLAG_TIME_VALID |
+					  CPUIDLE_FLAG_COUPLED,
 		.name			= "powered-down",
 		.desc			= "CPU power gated",
 	},
@@ -64,6 +71,88 @@ static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_SMP
+static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+
+static int tegra20_reset_sleeping_cpu_1(void)
+{
+	int ret = 0;
+
+	tegra_pen_lock();
+
+	if (readl(pmc + PMC_SCRATCH41) == CPU_RESETTABLE)
+		tegra20_cpu_shutdown(1);
+	else
+		ret = -EINVAL;
+
+	tegra_pen_unlock();
+
+	return ret;
+}
+
+static void tegra20_wake_cpu1_from_reset(void)
+{
+	tegra_pen_lock();
+
+	tegra20_cpu_clear_resettable();
+
+	/* enable cpu clock on cpu */
+	tegra_enable_cpu_clock(1);
+
+	/* take the CPU out of reset */
+	tegra_cpu_out_of_reset(1);
+
+	/* unhalt the cpu */
+	flowctrl_write_cpu_halt(1, 0);
+
+	tegra_pen_unlock();
+}
+
+static int tegra20_reset_cpu_1(void)
+{
+	if (!cpu_online(1) || !tegra20_reset_sleeping_cpu_1())
+		return 0;
+
+	tegra20_wake_cpu1_from_reset();
+	return -EBUSY;
+}
+#else
+static inline void tegra20_wake_cpu1_from_reset(void)
+{
+}
+
+static inline int tegra20_reset_cpu_1(void)
+{
+	return 0;
+}
+#endif
+
+static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
+					   struct cpuidle_driver *drv,
+					   int index)
+{
+	struct cpuidle_state *state = &drv->states[index];
+	u32 cpu_on_time = state->exit_latency;
+	u32 cpu_off_time = state->target_residency - state->exit_latency;
+
+	while (tegra20_cpu_is_resettable_soon())
+		cpu_relax();
+
+	if (tegra20_reset_cpu_1() || !tegra_cpu_rail_off_ready())
+		return false;
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
+
+	tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
+
+	if (cpu_online(1))
+		tegra20_wake_cpu1_from_reset();
+
+	return true;
+}
+
+#ifdef CONFIG_SMP
 static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
 					 struct cpuidle_driver *drv,
 					 int index)
@@ -87,20 +176,31 @@ static inline bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,
 }
 #endif
 
-static int tegra20_idle_lp2(struct cpuidle_device *dev,
-			    struct cpuidle_driver *drv,
-			    int index)
+static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
+				    struct cpuidle_driver *drv,
+				    int index)
 {
 	u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
 	bool entered_lp2 = false;
 
+	if (tegra_pending_sgi())
+		atomic_inc(&abort_flag);
+
+	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+
+	if (atomic_read(&abort_flag) > 0) {
+		cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+		atomic_set(&abort_flag, 0);	/* clean flag for next coming */
+		return -EINTR;
+	}
+
 	local_fiq_disable();
 
 	tegra_set_cpu_in_lp2(cpu);
 	cpu_pm_enter();
 
 	if (cpu == 0)
-		cpu_do_idle();
+		entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index);
 	else
 		entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);
 
@@ -122,6 +222,10 @@ int __init tegra20_cpuidle_init(void)
 	struct cpuidle_device *dev;
 	struct cpuidle_driver *drv = &tegra_idle_driver;
 
+#ifdef CONFIG_PM_SLEEP
+	tegra_tear_down_cpu = tegra20_tear_down_cpu;
+#endif
+
 	drv->state_count = ARRAY_SIZE(tegra_idle_states);
 	memcpy(drv->states, tegra_idle_states,
 			drv->state_count * sizeof(drv->states[0]));
@@ -135,6 +239,9 @@ int __init tegra20_cpuidle_init(void)
 	for_each_possible_cpu(cpu) {
 		dev = &per_cpu(tegra_idle_device, cpu);
 		dev->cpu = cpu;
+#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
+		dev->coupled_cpus = *cpu_online_mask;
+#endif
 
 		dev->state_count = drv->state_count;
 		ret = cpuidle_register_device(dev);
diff --git a/arch/arm/mach-tegra/sleep-tegra20.S b/arch/arm/mach-tegra/sleep-tegra20.S
index 1074364..9f6bfaf 100644
--- a/arch/arm/mach-tegra/sleep-tegra20.S
+++ b/arch/arm/mach-tegra/sleep-tegra20.S
@@ -57,6 +57,9 @@ ENDPROC(tegra20_hotplug_shutdown)
 ENTRY(tegra20_cpu_shutdown)
 	cmp	r0, #0
 	moveq	pc, lr			@ must not be called for CPU 0
+	mov32	r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	mov	r12, #CPU_RESETTABLE
+	str	r12, [r1]
 
 	cpu_to_halt_reg r1, r0
 	ldr	r3, =TEGRA_FLOW_CTRL_VIRT
@@ -163,6 +166,21 @@ ENTRY(tegra20_cpu_set_resettable_soon)
 ENDPROC(tegra20_cpu_set_resettable_soon)
 
 /*
+ * tegra20_cpu_is_resettable_soon(void)
+ *
+ * Returns true if the "resettable soon" flag in PMC_SCRATCH41 has been
+ * set because it is expected that the secondary CPU will be idle soon.
+ */
+ENTRY(tegra20_cpu_is_resettable_soon)
+	mov32	r1, TEGRA_PMC_VIRT + PMC_SCRATCH41
+	ldr	r12, [r1]
+	cmp	r12, #CPU_RESETTABLE_SOON
+	moveq	r0, #1
+	movne	r0, #0
+	mov	pc, lr
+ENDPROC(tegra20_cpu_is_resettable_soon)
+
+/*
  * tegra20_sleep_cpu_secondary_finish(unsigned long v2p)
  *
  * Enters WFI on secondary CPU by exiting coherency.
@@ -221,4 +239,39 @@ ENTRY(tegra20_sleep_cpu_secondary_finish)
 
 	ldmfd	sp!, {r4 - r11, pc}
 ENDPROC(tegra20_sleep_cpu_secondary_finish)
+
+/*
+ * tegra20_tear_down_cpu
+ *
+ * Switches the CPU cluster to PLL-P and enters sleep.
+ */
+ENTRY(tegra20_tear_down_cpu)
+	bl	tegra_switch_cpu_to_pllp
+	b	tegra20_enter_sleep
+ENDPROC(tegra20_tear_down_cpu)
+
+/*
+ * tegra20_enter_sleep
+ *
+ * uses flow controller to enter sleep state
+ * executes from IRAM with SDRAM in selfrefresh when target state is LP0 or LP1
+ * executes from SDRAM with target state is LP2
+ */
+tegra20_enter_sleep:
+	mov32   r6, TEGRA_FLOW_CTRL_BASE
+
+	mov     r0, #FLOW_CTRL_WAIT_FOR_INTERRUPT
+	orr	r0, r0, #FLOW_CTRL_HALT_CPU_IRQ | FLOW_CTRL_HALT_CPU_FIQ
+	cpu_id	r1
+	cpu_to_halt_reg r1, r1
+	str	r0, [r6, r1]
+	dsb
+	ldr	r0, [r6, r1] /* memory barrier */
+
+halted:
+	dsb
+	wfe	/* CPU should be power gated here */
+	isb
+	b	halted
+
 #endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
index addae35..364d845 100644
--- a/arch/arm/mach-tegra/sleep.S
+++ b/arch/arm/mach-tegra/sleep.S
@@ -34,6 +34,9 @@
 #include "flowctrl.h"
 #include "sleep.h"
 
+#define CLK_RESET_CCLK_BURST	0x20
+#define CLK_RESET_CCLK_DIVIDER  0x24
+
 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_PM_SLEEP)
 /*
  * tegra_disable_clean_inv_dcache
@@ -110,4 +113,20 @@ ENTRY(tegra_shut_off_mmu)
 	mov	pc, r0
 ENDPROC(tegra_shut_off_mmu)
 	.popsection
+
+/*
+ * tegra_switch_cpu_to_pllp
+ *
+ * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
+ */
+ENTRY(tegra_switch_cpu_to_pllp)
+	/* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
+	mov32	r5, TEGRA_CLK_RESET_BASE
+	mov	r0, #(2 << 28)			@ burst policy = run mode
+	orr	r0, r0, #(4 << 4)		@ use PLLP in run mode burst
+	str	r0, [r5, #CLK_RESET_CCLK_BURST]
+	mov	r0, #0
+	str	r0, [r5, #CLK_RESET_CCLK_DIVIDER]
+	mov	pc, lr
+ENDPROC(tegra_switch_cpu_to_pllp)
 #endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index e39a56b..4ffae54 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -131,6 +131,8 @@ static inline void tegra20_hotplug_init(void) {}
 static inline void tegra30_hotplug_init(void) {}
 #endif
 
+void tegra20_cpu_shutdown(int cpu);
+int tegra20_cpu_is_resettable_soon(void);
 void tegra20_cpu_clear_resettable(void);
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 void tegra20_cpu_set_resettable_soon(void);
@@ -139,6 +141,7 @@ static inline void tegra20_cpu_set_resettable_soon(void) {}
 #endif
 
 int tegra20_sleep_cpu_secondary_finish(unsigned long);
+void tegra20_tear_down_cpu(void);
 int tegra30_sleep_cpu_secondary_finish(unsigned long);
 void tegra30_tear_down_cpu(void);
 
-- 
1.8.0.3

^ permalink raw reply related

* [PATCH v4 2/9] clk: tegra: Add tegra specific clocks
From: Hiroshi Doyu @ 2013-01-16  8:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50F085A0.4090100@wwwdotorg.org>

Stephen Warren <swarren@wwwdotorg.org> wrote @ Fri, 11 Jan 2013 22:35:28 +0100:

> On 01/11/2013 04:48 AM, Hiroshi Doyu wrote:
> > Hi Prahant,
> > 
> > Some nit-pick/cosmetic comments inlined...
> 
> FYI, Prashant is on vacation for the next week or two, so I'll take over
> this series to clean up any last review comments.
> 
> > Prashant Gaikwad <pgaikwad@nvidia.com> wrote @ Fri, 11 Jan 2013 08:46:20 +0100:
> > 
> >> Add tegra specific clocks, pll, pll_out, peripheral,
> >> frac_divider, super.
> 
> (it's a good idea to quote as little text as possible; paging through
> the whole patch to find your comments was slightly painful).
> 
> >> diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c
> 
> >> +struct clk *tegra_clk_sync_source(const char *name, unsigned long rate,
> >> +                                 unsigned long max_rate)
> >> +{
> >> +       struct tegra_clk_sync_source *sync;
> >> +       struct clk_init_data init;
> >> +       struct clk *clk;
> >> +
> >> +       sync = kzalloc(sizeof(struct tegra_clk_sync_source), GFP_KERNEL);
> >> +       if (!sync) {
> >> +               pr_err("%s: could not allocate sync source clk\n", __func__);
> >> +               return ERR_PTR(-ENOMEM);
> >> +       }
> >> +
> >> +       sync->rate = rate;
> >> +       sync->max_rate = max_rate;
> >> +
> >> +       init.ops = &tegra_clk_sync_source_ops;
> >> +       init.name = name;
> >> +       init.flags = CLK_IS_ROOT;
> >> +       init.parent_names = NULL;
> >> +       init.num_parents = 0;
> >> +
> >> +       sync->hw.init = &init;
> >> +
> >> +       clk = clk_register(NULL, &sync->hw);
> > 
> > The above usage of "init" from stack may be a bit
> > unfamilier. I can guess that its content is copied in clk_register()
> > but it's originally defined in stack. So I just prefer to writing this
> > as below. It may be somewhat explict that we know init is from stack.
> 
> The issue you mention is more about whether "init" is copied from the
> stack or not; simplying changing the initialization to:
> 
> > struct clk *tegra_clk_sync_source(const char *name, unsigned long rate,
> >                                  unsigned long max_rate)
> > {
> >         struct tegra_clk_sync_source *sync;
> >         struct clk_init_data init = {
> >                 .ops = &tegra_clk_sync_source_ops;
> >                 .name = name;
> >                 .flags = CLK_IS_ROOT;
> >                 .parent_names = NULL;
> >                 .num_parents = 0;
> >         };

Also since "init" is allocated from stack, members are expected to be
initialized *zero*. The last 2 lines are not necessary in the above.

         struct clk_init_data init = {
                 .ops = &tegra_clk_sync_source_ops;
                 .name = name;
                 .flags = CLK_IS_ROOT;
         };

> ... doesn't really address that, although it's a perfectly reasonable
> change.
> 
> To address the copying issue, why not just add a comment:

OK

>        /*
>         * This data pointed at by this field is copied by
>         * clk_register(), so a pointer to the stack is OK.
>         */
>        sync->hw.init = &init;
> 
>        clk = clk_register(NULL, &sync->hw);
> 
> I'll make the other changes you suggested.

^ permalink raw reply

* [PATCH 1/3] MTD: at91: atmel_nand: for PMECC, add code to choose the ecc bits and sector size according to the ONFI parameter ECC requirement.
From: Josh Wu @ 2013-01-16  8:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358252760.2731.133.camel@sauron.fi.intel.com>

Hi, Artem

On 1/15/2013 8:26 PM, Artem Bityutskiy wrote:
> I cannot compile this patch:
>
> ERROR (phandle_references): Reference to non-existent node or label "pinctrl_ssc0_tx"
>
> ERROR: Input tree has errors, aborting (use -f to force output)
> make[2]: *** [arch/arm/boot/dts/at91sam9g20ek.dtb] Error 2

As Bo Shen already mentioned, they are caused by ssc pinctrl patches. it 
will be merged in next rc or late.

>
> On Wed, 2012-12-19 at 18:27 +0800, Josh Wu wrote:
>> This patch will check NAND flash's ecc minimum requirement in ONFI parameter. If it is equal or smaller than pmecc-cap in dtsi, then use ecc_bits in ONFI. otherwise, return an error since pmecc-cap in dtsi don't meet the ecc minimum reqirement.
>>
>> This patch also check sector size (codeword) requirement in ONFI. If it is equal or bigger than sector_size in dtsi, then use the one of ONFI. otherwise return error.
>>
>> Currently we don't support to read the ECC parameter in ONFI extended parameter page. So in that case we just use the value specified in dts.
>>
>> For non-ONFI nand flash, we assume the minimum ecc requirement is 2bits in 512 bytes.
>>
>> Signed-off-by: Josh Wu <josh.wu@atmel.com>
> Please, wrap the lines like kernel developers usually do.

OK. I will resend the whole patch series with wrapped commit message. 
thanks.

Best Regards,
Josh Wu
>

^ permalink raw reply

* [PATCH V4 1/3] ARM: davinci: da850: add pinctrl driver DT entries
From: Kumar, Anil @ 2013-01-16  8:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358308102-8169-2-git-send-email-anilkumar.v@ti.com>

On Wed, Jan 16, 2013 at 09:18:20, Kumar, Anil wrote:
> For DT, DaVinci platform can use pinctrl-single driver for handling
> padconf registers.
> 
> Enable PINCTRL Kconfig for MACH_DA8XX_DT platform. Add required
> pinctrl DT entries in da850 dts file.
> 
>  Test procedure
>   1)Populate DT file with NAND node information.
>   2)Populate board DT file with pinmux information for NAND.
>   3)Boot and confirm NAND is detected by the kernel.
>   4)cat /proc/mtd to show partitions.
> 
> Signed-off-by: Kumar, Anil <anilkumar.v@ti.com>
> ---
> :100644 100644 37dc5a3... c7609d0... M	arch/arm/boot/dts/da850-evm.dts
> :100644 100644 fbada87... e9c6e82... M	arch/arm/boot/dts/da850.dtsi
> :100644 100644 0153950... a075b3e... M	arch/arm/mach-davinci/Kconfig
>  arch/arm/boot/dts/da850-evm.dts |    3 +++
>  arch/arm/boot/dts/da850.dtsi    |   10 ++++++++++
>  arch/arm/mach-davinci/Kconfig   |    1 +
>  3 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
> index 37dc5a3..c7609d0 100644
> --- a/arch/arm/boot/dts/da850-evm.dts
> +++ b/arch/arm/boot/dts/da850-evm.dts
> @@ -15,6 +15,9 @@
>  	model = "DA850/AM1808/OMAP-L138 EVM";
>  
>  	soc {
> +		pmx_core:pinmux at 1c14120 {

I have found cosmetics issue here. I will correct it and send next version.

> +			status = "okay";
> +		};
>  		serial0: serial at 1c42000 {
>  			status = "okay";
>  		};
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index fbada87..e9c6e82 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -29,6 +29,16 @@
>  		#size-cells = <1>;
>  		ranges = <0x0 0x01c00000 0x400000>;
>  
> +		pmx_core:pinmux at 1c14120 {

I have found cosmetics issue here. I will correct it and send next version.

> +			compatible = "pinctrl-single";
> +			reg = <0x14120 0x50>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-single,bit-per-mux;
> +			pinctrl-single,register-width = <32>;
> +			pinctrl-single,function-mask = <0xffffffff>;
> +			status = "disabled";
> +		};
>  		serial0: serial at 1c42000 {
>  			compatible = "ns16550a";
>  			reg = <0x42000 0x100>;
> diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
> index 0153950..a075b3e 100644
> --- a/arch/arm/mach-davinci/Kconfig
> +++ b/arch/arm/mach-davinci/Kconfig
> @@ -62,6 +62,7 @@ config MACH_DA8XX_DT
>  	bool "Support DA8XX platforms using device tree"
>  	default y
>  	depends on ARCH_DAVINCI_DA8XX
> +	select PINCTRL
>  	help
>  	  Say y here to include support for TI DaVinci DA850 based using
>  	  Flattened Device Tree. More information at Documentation/devicetree
> -- 
> 1.7.4.1
> 
> 

^ permalink raw reply

* [PATCH 06/18] power: ab8500_bm: Recharge condition not optimal for battery
From: Lee Jones @ 2013-01-16  8:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130116014442.GA17659@lizard.fhda.edu>

On Tue, 15 Jan 2013, Anton Vorontsov wrote:

> On Fri, Jan 11, 2013 at 01:12:54PM +0000, Lee Jones wrote:
> > From: Marcus Cooper <marcus.xm.cooper@stericsson.com>
> > 
> > Today the battery recharge is determined with a voltage threshold. This
> > voltage threshold is only valid when the battery is relaxed. In charging
> > algorithm the voltage read is the loaded battery voltage and no
> > compensation is done to get the relaxed voltage. When maintenance
> > charging is not selected, this makes the recharging condition to almost
> > immediately activate when there is a discharge present on the battery.
> > 
> > Depending on which vendor the battery comes from this behavior can wear
> > out the battery much faster than normal.
> > 
> > The fuelgauge driver is responsible to monitor the actual battery
> > capacity and is able to estimate the remaining capacity. It is better to
> > use the remaining capacity as a limit to determine when battery should
> > be recharged.
> > 
> > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > Signed-off-by: Marcus Cooper <marcus.xm.cooper@stericsson.com>
> > Reviewed-by: Hakan BERG <hakan.berg@stericsson.com>
> > Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
> > ---
> > +	.maint_thres = 95,
> >  	.user_cap_limit = 15,
> >  	.maint_thres = 97,
> >  };
> 
> 95 or 97? These are both specified. I removed 97, assuming it was a merge
> error on your side. But please double check, it could be that you really
> want 97 here.

You did the correct thing, thanks.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH 03/18] power: ab8500_charger: Detect charger removal
From: Lee Jones @ 2013-01-16  8:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130116013640.GA11105@lizard.fhda.edu>

On Tue, 15 Jan 2013, Anton Vorontsov wrote:

> On Fri, Jan 11, 2013 at 01:12:51PM +0000, Lee Jones wrote:
> > Add two new work queues to provide USB and AC charger disconnect
> > detection.
> > 
> > Signed-off-by: Lee Jones <lee.jones@linaro.org>
> > ---
> [....]
> > +		if ((statval & usbch)) != usbch)
> 
>   CC      drivers/power/ab8500_charger.o
> drivers/power/ab8500_charger.c: In function ?ab8500_charger_usb_attached_work?:
> drivers/power/ab8500_charger.c:1812:26: error: expected expression before ?!=? token
> drivers/power/ab8500_charger.c:1812:34: error: expected statement before ?)? token
> drivers/power/ab8500_charger.c: In function ?ab8500_charger_ac_attached_work?:
> drivers/power/ab8500_charger.c:1852:27: error: expected expression before ?!=? token
> drivers/power/ab8500_charger.c:1852:36: error: expected statement before ?)? token
> 
> I fixed it up...

You're a star.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH 00/18] AB8500 battery management series upgrade
From: Lee Jones @ 2013-01-16  8:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130116014812.GA27065@lizard.fhda.edu>

On Tue, 15 Jan 2013, Anton Vorontsov wrote:

> On Fri, Jan 11, 2013 at 01:12:48PM +0000, Lee Jones wrote:
> > Here we go again. This patches include your suggested fixups.
> > 
> > Please find the next instalment of the AB8500 Power drivers upgrade.
> > A lot of work has taken place on the internal development track, but
> > little effort has gone into mainlining it. At last count there were
> > around 70+ patches which are in need of forward-porting, then
> > upstreaming. This patch-set aims to make a good start. :)
> 
> All except 14/18 applied, thanks!
> 
> Some general notes:
> 
> - No need for the power: prefix in the subject, unless it is a core
>   change;
> - Try be consistent on the capitalization (I tend to capitalize the first
>   word, "driver: Fix something". But it's up to you, just be consistent).
> - Try keep the patches compilable. :)
> - ..and applicable to the battery tree.
> 
> Thanks!
> 
> Anton
> 
> p.s. I'll push out the battery tree a bit later (in a couple of hours), so
> don't worry if the commits won't appear just now.

I'll keep 14/18 back until the next push and I'll try to be
diligent in adhering to your requests.

Very nice. Thanks Anton.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ 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