Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Samsung GPIO changes break boot on Cragganmore
From: Mark Brown @ 2011-09-22 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Something in the recent GPIO changes have broken the boot for me on
Cragganmore (S3C6410 based) systems.  The boot dies before any console
output is produced so it's hard to isolate exactly what went wrong but
backing out:

   5ec7414 ARM: SAMSUNG: Remove useless Samsung GPIO related CONFIGs
   7c15788 ARM: SAMSUNG: Update the name of regarding Samsung GPIO
   bedcda6 gpio/samsung: gpio-samsung.c to support Samsung GPIOs

fixes the system boot for me.  The diff is rather substantial so it's
hard to check by eyeball unfortunately.

Thanks,
Mark

^ permalink raw reply

* [PATCH] ARM i.MX avic: convert to use generic irq chip
From: Shawn Guo @ 2011-09-22 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316684408-12196-1-git-send-email-jason77.wang@gmail.com>

On Thu, Sep 22, 2011 at 05:40:08PM +0800, Hui Wang wrote:
> Convert i.MX avic irq handler to use generic irq chip. This not only
> provides a cleanup implementation of irq chip handler, but also
> implements suspend/resume interface with the help of generic irq chip
> interface.
> 
> Change mxc_irq_chip to a new structure mxc_extra_irq to handle fiq
> and priority functions.
> 
> Signed-off-by: Hui Wang <jason77.wang@gmail.com>
> ---
> 
> This patch is basing on imx-features branch of linux-pengu. Have
> validated this patch on 31pdk and 35pdk platforms, while have no
> chance to validate it on mx2 and mx1 platforms since we don't have
> those hardwares.
> 
> The purpose of changing avic to use generic irq chip is because i
> added suspend/resume functions for 35pdk, and generic irq chip
> naturally has suspend/resume interface. If this patch can be
> accepted, i will continue to send out those 35pdk pm patches.
> 
>  arch/arm/plat-mxc/avic.c       |   79 ++++++++++++++++++++++++++++------------
>  arch/arm/plat-mxc/irq-common.c |   21 ++++++-----
>  arch/arm/plat-mxc/irq-common.h |    3 +-
>  arch/arm/plat-mxc/tzic.c       |    8 ++++-
>  4 files changed, 75 insertions(+), 36 deletions(-)
> 
Acked-by: Shawn Guo <shawn.guo@linaro.org>

However, I'm wondering if you can add the suspend/resume interface for
tzic as well.

-- 
Regards,
Shawn

^ permalink raw reply

* [PATCH 7/7] ARM: ux500: Reprogram timers upon resume
From: Linus Walleij @ 2011-09-22 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Aaberg <jonas.aberg@stericsson.com>

On ux500 the MTU timer blocks are powered off during
suspend/resume, so these need some reinitialization when
coming back from suspend.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ux500/timer.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index 36a82bf..08c55a5 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -53,6 +53,13 @@ static void __init ux500_timer_init(void)
 	clksrc_dbx500_prcmu_init();
 }
 
+static void ux500_timer_reset(void)
+{
+	nmdk_clkevt_reset();
+	nmdk_clksrc_reset();
+}
+
 struct sys_timer ux500_timer = {
 	.init		= ux500_timer_init,
+	.resume		= ux500_timer_reset,
 };
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 6/7] ARM: plat-nomadik: timer: Export reset functions
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Aaberg <jonas.aberg@stericsson.com>

We make the reset function from the driver public, then
we also move of all register defines from the public header
file into driver, where they belong.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/plat-nomadik/include/plat/mtu.h |   47 +---------------------------
 arch/arm/plat-nomadik/timer.c            |   50 ++++++++++++++++++++++++++++--
 2 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
index 65704a3..6508e76 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -1,54 +1,11 @@
 #ifndef __PLAT_MTU_H
 #define __PLAT_MTU_H
 
-/*
- * Guaranteed runtime conversion range in seconds for
- * the clocksource and clockevent.
- */
-#define MTU_MIN_RANGE 4
-
 /* should be set by the platform code */
 extern void __iomem *mtu_base;
 
-/*
- * The MTU device hosts four different counters, with 4 set of
- * registers. These are register names.
- */
-
-#define MTU_IMSC	0x00	/* Interrupt mask set/clear */
-#define MTU_RIS		0x04	/* Raw interrupt status */
-#define MTU_MIS		0x08	/* Masked interrupt status */
-#define MTU_ICR		0x0C	/* Interrupt clear register */
-
-/* per-timer registers take 0..3 as argument */
-#define MTU_LR(x)	(0x10 + 0x10 * (x) + 0x00)	/* Load value */
-#define MTU_VAL(x)	(0x10 + 0x10 * (x) + 0x04)	/* Current value */
-#define MTU_CR(x)	(0x10 + 0x10 * (x) + 0x08)	/* Control reg */
-#define MTU_BGLR(x)	(0x10 + 0x10 * (x) + 0x0c)	/* At next overflow */
-
-/* bits for the control register */
-#define MTU_CRn_ENA		0x80
-#define MTU_CRn_PERIODIC	0x40	/* if 0 = free-running */
-#define MTU_CRn_PRESCALE_MASK	0x0c
-#define MTU_CRn_PRESCALE_1		0x00
-#define MTU_CRn_PRESCALE_16		0x04
-#define MTU_CRn_PRESCALE_256		0x08
-#define MTU_CRn_32BITS		0x02
-#define MTU_CRn_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR*/
-
-/* Other registers are usual amba/primecell registers, currently not used */
-#define MTU_ITCR	0xff0
-#define MTU_ITOP	0xff4
-
-#define MTU_PERIPH_ID0	0xfe0
-#define MTU_PERIPH_ID1	0xfe4
-#define MTU_PERIPH_ID2	0xfe8
-#define MTU_PERIPH_ID3	0xfeC
-
-#define MTU_PCELL0	0xff0
-#define MTU_PCELL1	0xff4
-#define MTU_PCELL2	0xff8
-#define MTU_PCELL3	0xffC
+void nmdk_clkevt_reset(void);
+void nmdk_clksrc_reset(void);
 
 #endif /* __PLAT_MTU_H */
 
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index a04b521..30b6433 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -21,7 +21,51 @@
 #include <asm/mach/time.h>
 #include <asm/sched_clock.h>
 
-#include <plat/mtu.h>
+/*
+ * Guaranteed runtime conversion range in seconds for
+ * the clocksource and clockevent.
+ */
+#define MTU_MIN_RANGE 4
+
+/*
+ * The MTU device hosts four different counters, with 4 set of
+ * registers. These are register names.
+ */
+
+#define MTU_IMSC	0x00	/* Interrupt mask set/clear */
+#define MTU_RIS		0x04	/* Raw interrupt status */
+#define MTU_MIS		0x08	/* Masked interrupt status */
+#define MTU_ICR		0x0C	/* Interrupt clear register */
+
+/* per-timer registers take 0..3 as argument */
+#define MTU_LR(x)	(0x10 + 0x10 * (x) + 0x00)	/* Load value */
+#define MTU_VAL(x)	(0x10 + 0x10 * (x) + 0x04)	/* Current value */
+#define MTU_CR(x)	(0x10 + 0x10 * (x) + 0x08)	/* Control reg */
+#define MTU_BGLR(x)	(0x10 + 0x10 * (x) + 0x0c)	/* At next overflow */
+
+/* bits for the control register */
+#define MTU_CRn_ENA		0x80
+#define MTU_CRn_PERIODIC	0x40	/* if 0 = free-running */
+#define MTU_CRn_PRESCALE_MASK	0x0c
+#define MTU_CRn_PRESCALE_1		0x00
+#define MTU_CRn_PRESCALE_16		0x04
+#define MTU_CRn_PRESCALE_256		0x08
+#define MTU_CRn_32BITS		0x02
+#define MTU_CRn_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR*/
+
+/* Other registers are usual amba/primecell registers, currently not used */
+#define MTU_ITCR	0xff0
+#define MTU_ITOP	0xff4
+
+#define MTU_PERIPH_ID0	0xfe0
+#define MTU_PERIPH_ID1	0xfe4
+#define MTU_PERIPH_ID2	0xfe8
+#define MTU_PERIPH_ID3	0xfeC
+
+#define MTU_PCELL0	0xff0
+#define MTU_PCELL1	0xff4
+#define MTU_PCELL2	0xff8
+#define MTU_PCELL3	0xffC
 
 static bool clkevt_periodic;
 static u32 clk_prescale;
@@ -68,7 +112,7 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
 	return 0;
 }
 
-static void nmdk_clkevt_reset(void)
+void nmdk_clkevt_reset(void)
 {
 	if (clkevt_periodic) {
 
@@ -138,7 +182,7 @@ static struct irqaction nmdk_timer_irq = {
 	.dev_id		= &nmdk_clkevt,
 };
 
-static void nmdk_clksrc_reset(void)
+void nmdk_clksrc_reset(void)
 {
 	/* Disable */
 	writel(0, mtu_base + MTU_CR(0));
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 5/7] ARM: plat-nomadik: timer: Add support for periodic timers
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Aaberg <jonas.aberg@stericsson.com>

This adds support for a periodic mode in the MTU (Nomadik)
timer clockevent driver. It also include changes needed for
deeper powerstates where MTU block gets powered off.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/plat-nomadik/timer.c |   88 ++++++++++++++++++++++++++++-------------
 1 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index bd638c5..a04b521 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -23,7 +23,12 @@
 
 #include <plat/mtu.h>
 
+static bool clkevt_periodic;
+static u32 clk_prescale;
+static u32 nmdk_cycle;		/* write-once */
+
 void __iomem *mtu_base; /* Assigned by machine code */
+
 #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
 /*
  * Override the global weak sched_clock symbol with this
@@ -49,31 +54,55 @@ static void notrace nomadik_update_sched_clock(void)
 	update_sched_clock(&cd, cyc, (u32)~0);
 }
 #endif
+
 /* Clockevent device: use one-shot mode */
+static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
+{
+	writel(1 << 1, mtu_base + MTU_IMSC);
+	writel(evt, mtu_base + MTU_LR(1));
+	/* Load highest value, enable device, enable interrupts */
+	writel(MTU_CRn_ONESHOT | clk_prescale |
+	       MTU_CRn_32BITS | MTU_CRn_ENA,
+	       mtu_base + MTU_CR(1));
+
+	return 0;
+}
+
+static void nmdk_clkevt_reset(void)
+{
+	if (clkevt_periodic) {
+
+		/* Timer: configure load and background-load, and fire it up */
+		writel(nmdk_cycle, mtu_base + MTU_LR(1));
+		writel(nmdk_cycle, mtu_base + MTU_BGLR(1));
+
+		writel(MTU_CRn_PERIODIC | clk_prescale |
+		       MTU_CRn_32BITS | MTU_CRn_ENA,
+		       mtu_base + MTU_CR(1));
+		writel(1 << 1, mtu_base + MTU_IMSC);
+	} else {
+		/* Generate an interrupt to start the clockevent again */
+		(void) nmdk_clkevt_next(nmdk_cycle, NULL);
+	}
+}
+
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
 			     struct clock_event_device *dev)
 {
-	u32 cr;
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		pr_err("%s: periodic mode not supported\n", __func__);
+		clkevt_periodic = true;
+		nmdk_clkevt_reset();
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
-		/* Load highest value, enable device, enable interrupts */
-		cr = readl(mtu_base + MTU_CR(1));
-		writel(0, mtu_base + MTU_LR(1));
-		writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1));
-		writel(1 << 1, mtu_base + MTU_IMSC);
+		clkevt_periodic = false;
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
-		/* disable irq */
 		writel(0, mtu_base + MTU_IMSC);
 		/* disable timer */
-		cr = readl(mtu_base + MTU_CR(1));
-		cr &= ~MTU_CRn_ENA;
-		writel(cr, mtu_base + MTU_CR(1));
+		writel(0, mtu_base + MTU_CR(1));
 		/* load some high default value */
 		writel(0xffffffff, mtu_base + MTU_LR(1));
 		break;
@@ -82,16 +111,9 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode,
 	}
 }
 
-static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
-{
-	/* writing the value has immediate effect */
-	writel(evt, mtu_base + MTU_LR(1));
-	return 0;
-}
-
 static struct clock_event_device nmdk_clkevt = {
 	.name		= "mtu_1",
-	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.features	= CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
 	.rating		= 200,
 	.set_mode	= nmdk_clkevt_mode,
 	.set_next_event	= nmdk_clkevt_next,
@@ -116,11 +138,23 @@ static struct irqaction nmdk_timer_irq = {
 	.dev_id		= &nmdk_clkevt,
 };
 
+static void nmdk_clksrc_reset(void)
+{
+	/* Disable */
+	writel(0, mtu_base + MTU_CR(0));
+
+	/* ClockSource: configure load and background-load, and fire it up */
+	writel(nmdk_cycle, mtu_base + MTU_LR(0));
+	writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
+
+	writel(clk_prescale | MTU_CRn_32BITS | MTU_CRn_ENA,
+	       mtu_base + MTU_CR(0));
+}
+
 void __init nmdk_timer_init(void)
 {
 	unsigned long rate;
 	struct clk *clk0;
-	u32 cr = MTU_CRn_32BITS;
 
 	clk0 = clk_get_sys("mtu0", NULL);
 	BUG_ON(IS_ERR(clk0));
@@ -138,16 +172,16 @@ void __init nmdk_timer_init(void)
 	rate = clk_get_rate(clk0);
 	if (rate > 32000000) {
 		rate /= 16;
-		cr |= MTU_CRn_PRESCALE_16;
+		clk_prescale = MTU_CRn_PRESCALE_16;
 	} else {
-		cr |= MTU_CRn_PRESCALE_1;
+		clk_prescale = MTU_CRn_PRESCALE_1;
 	}
 
+	nmdk_cycle = (rate + HZ/2) / HZ;
+
+
 	/* Timer 0 is the free running clocksource */
-	writel(cr, mtu_base + MTU_CR(0));
-	writel(0, mtu_base + MTU_LR(0));
-	writel(0, mtu_base + MTU_BGLR(0));
-	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
+	nmdk_clksrc_reset();
 
 	if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0",
 			rate, 200, 32, clocksource_mmio_readl_down))
@@ -160,8 +194,6 @@ void __init nmdk_timer_init(void)
 
 	clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
 
-	writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
-
 	nmdk_clkevt.max_delta_ns =
 		clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
 	nmdk_clkevt.min_delta_ns =
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 4/7] ARM: ux500: Move timer code to separate file
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Jonas Aaberg <jonas.aberg@stericsson.com>

Just split off the timer code to its own file so we have a
more fine-grained file tree.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ux500/Makefile |    2 +-
 arch/arm/mach-ux500/cpu.c    |   36 --------------------------
 arch/arm/mach-ux500/timer.c  |   58 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 37 deletions(-)
 create mode 100644 arch/arm/mach-ux500/timer.c

diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 1694916..be915a1 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -3,7 +3,7 @@
 #
 
 obj-y				:= clock.o cpu.o devices.o devices-common.o \
-				   id.o usb.o
+				   id.o usb.o timer.o
 obj-$(CONFIG_UX500_SOC_DB5500)	+= cpu-db5500.o dma-db5500.o
 obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o devices-db8500.o
 obj-$(CONFIG_MACH_U8500)	+= board-mop500.o board-mop500-sdi.o \
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index c0e4593..797f364 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -18,7 +18,6 @@
 #include <asm/mach/map.h>
 #include <asm/localtimer.h>
 
-#include <plat/mtu.h>
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
@@ -120,38 +119,3 @@ static int ux500_l2x0_init(void)
 }
 early_initcall(ux500_l2x0_init);
 #endif
-
-static void __init ux500_timer_init(void)
-{
-#ifdef CONFIG_LOCAL_TIMERS
-	/* Setup the local timer base */
-	if (cpu_is_u5500())
-		twd_base = __io_address(U5500_TWD_BASE);
-	else if (cpu_is_u8500())
-		twd_base = __io_address(U8500_TWD_BASE);
-	else
-		ux500_unknown_soc();
-#endif
-	if (cpu_is_u5500())
-		mtu_base = __io_address(U5500_MTU0_BASE);
-	else if (cpu_is_u8500ed())
-		mtu_base = __io_address(U8500_MTU0_BASE_ED);
-	else if (cpu_is_u8500())
-		mtu_base = __io_address(U8500_MTU0_BASE);
-	else
-		ux500_unknown_soc();
-
-	if (cpu_is_u8500())
-		clksrc_dbx500_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
-	else if (cpu_is_u5500())
-		clksrc_dbx500_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
-	else
-		ux500_unknown_soc();
-
-	nmdk_timer_init();
-	clksrc_dbx500_prcmu_init();
-}
-
-struct sys_timer ux500_timer = {
-	.init	= ux500_timer_init,
-};
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
new file mode 100644
index 0000000..36a82bf
--- /dev/null
+++ b/arch/arm/mach-ux500/timer.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson
+ */
+#include <linux/io.h>
+#include <linux/clksrc-dbx500-prcmu.h>
+
+#include <asm/localtimer.h>
+
+#include <plat/mtu.h>
+
+#include <mach/setup.h>
+#include <mach/hardware.h>
+
+static void __init ux500_timer_init(void)
+{
+	if (cpu_is_u5500()) {
+#ifdef CONFIG_LOCAL_TIMERS
+		twd_base = __io_address(U5500_TWD_BASE);
+#endif
+		mtu_base = __io_address(U5500_MTU0_BASE);
+		clksrc_dbx500_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
+	} else if (cpu_is_u8500()) {
+#ifdef CONFIG_LOCAL_TIMERS
+		twd_base = __io_address(U8500_TWD_BASE);
+#endif
+		mtu_base = __io_address(U8500_MTU0_BASE);
+		clksrc_dbx500_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
+	} else {
+		ux500_unknown_soc();
+	}
+
+	/*
+	 * Here we register the timerblocks active in the system.
+	 * Localtimers (twd) is started when both cpu is up and running.
+	 * MTU register a clocksource, clockevent and sched_clock.
+	 * Since the MTU is located in the VAPE power domain
+	 * it will be cleared in sleep which makes it unsuitable.
+	 * We however need it as a timer tick (clockevent)
+	 * during boot to calibrate delay until twd is started.
+	 * RTC-RTT have problems as timer tick during boot since it is
+	 * depending on delay which is not yet calibrated. RTC-RTT is in the
+	 * always-on powerdomain and is used as clockevent instead of twd when
+	 * sleeping.
+	 * The PRCMU timer 4(3 for DB5500) register a clocksource and
+	 * sched_clock with higher rating then MTU since is always-on.
+	 *
+	 */
+
+	nmdk_timer_init();
+	clksrc_dbx500_prcmu_init();
+}
+
+struct sys_timer ux500_timer = {
+	.init		= ux500_timer_init,
+};
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 3/7] ARM: ux500: add support for clocksource DBX500 PRCMU
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mattias Wallin <mattias.wallin@stericsson.com>

This patch adds support for the DBX500 PRCMU clocksource
to ux500 platforms.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.co>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ux500/cpu.c                      |    9 +++++++++
 arch/arm/mach-ux500/include/mach/db5500-regs.h |    2 ++
 arch/arm/mach-ux500/include/mach/db8500-regs.h |    3 +++
 3 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 1da23bb..c0e4593 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/mfd/db8500-prcmu.h>
 #include <linux/mfd/db5500-prcmu.h>
+#include <linux/clksrc-dbx500-prcmu.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -140,7 +141,15 @@ static void __init ux500_timer_init(void)
 	else
 		ux500_unknown_soc();
 
+	if (cpu_is_u8500())
+		clksrc_dbx500_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
+	else if (cpu_is_u5500())
+		clksrc_dbx500_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
+	else
+		ux500_unknown_soc();
+
 	nmdk_timer_init();
+	clksrc_dbx500_prcmu_init();
 }
 
 struct sys_timer ux500_timer = {
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
index 6ad9832..994b5fe 100644
--- a/arch/arm/mach-ux500/include/mach/db5500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h
@@ -61,6 +61,8 @@
 #define U5500_SCR_BASE		(U5500_PER4_BASE + 0x5000)
 #define U5500_DMC_BASE		(U5500_PER4_BASE + 0x6000)
 #define U5500_PRCMU_BASE	(U5500_PER4_BASE + 0x7000)
+#define U5500_PRCMU_TIMER_3_BASE (U5500_PER4_BASE + 0x07338)
+#define U5500_PRCMU_TIMER_4_BASE (U5500_PER4_BASE + 0x07450)
 #define U5500_MSP1_BASE		(U5500_PER4_BASE + 0x9000)
 #define U5500_GPIO2_BASE	(U5500_PER4_BASE + 0xA000)
 #define U5500_CDETECT_BASE	(U5500_PER4_BASE + 0xF000)
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index 0499971..751b0e6 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -102,10 +102,13 @@
 #define U8500_SCR_BASE		(U8500_PER4_BASE + 0x05000)
 #define U8500_DMC_BASE		(U8500_PER4_BASE + 0x06000)
 #define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
+#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
 #define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000)
 #define U8500_PRCMU_TCDM_BASE	(U8500_PER4_BASE + 0x68000)
 #define U8500_PRCMU_TCPM_BASE   (U8500_PER4_BASE + 0x60000)
 
+
 /* per3 base addresses */
 #define U8500_FSMC_BASE		(U8500_PER3_BASE + 0x0000)
 #define U8500_SSP0_BASE		(U8500_PER3_BASE + 0x2000)
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 2/7] clocksource: add DBX500 PRCMU Timer support
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mattias Wallin <mattias.wallin@stericsson.com>

This patch adds the DBX500 PRCMU Timer driver as a clocksource
and as sched_clock.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/Kconfig               |   15 ++++
 drivers/clocksource/Makefile              |    1 +
 drivers/clocksource/clksrc-dbx500-prcmu.c |  104 +++++++++++++++++++++++++++++
 include/linux/clksrc-dbx500-prcmu.h       |   22 ++++++
 4 files changed, 142 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clocksource/clksrc-dbx500-prcmu.c
 create mode 100644 include/linux/clksrc-dbx500-prcmu.h

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 34e9c4f..999d6a0 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -15,3 +15,18 @@ config CLKSRC_MMIO
 
 config DW_APB_TIMER
 	bool
+
+config CLKSRC_DBX500_PRCMU
+	bool "Clocksource PRCMU Timer"
+	depends on UX500_SOC_DB5500 || UX500_SOC_DB8500
+	default y
+	help
+	  Use the always on PRCMU Timer as clocksource
+
+config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
+	bool "Clocksource PRCMU Timer sched_clock"
+	depends on (CLKSRC_DBX500_PRCMU && !NOMADIK_MTU_SCHED_CLOCK)
+	select HAVE_SCHED_CLOCK
+	default y
+	help
+	  Use the always on PRCMU Timer as sched_clock
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 85ad1646..8d81a1d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
 obj-$(CONFIG_CLKBLD_I8253)	+= i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
+obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
\ No newline at end of file
diff --git a/drivers/clocksource/clksrc-dbx500-prcmu.c b/drivers/clocksource/clksrc-dbx500-prcmu.c
new file mode 100644
index 0000000..0ac5093
--- /dev/null
+++ b/drivers/clocksource/clksrc-dbx500-prcmu.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson
+ * Author: Sundar Iyer for ST-Ericsson
+ * sched_clock implementation is based on:
+ * plat-nomadik/timer.c Linus Walleij <linus.walleij@stericsson.com>
+ *
+ * DBx500-PRCMU Timer
+ * The PRCMU has 5 timers which are available in a always-on
+ * power domain.  We use the Timer 4 for our always-on clock
+ * source on DB8500 and Timer 3 on DB5500.
+ */
+#include <linux/clockchips.h>
+#include <linux/clksrc-dbx500-prcmu.h>
+
+#include <asm/sched_clock.h>
+
+#include <mach/setup.h>
+#include <mach/hardware.h>
+
+#define RATE_32K		32768
+
+#define TIMER_MODE_CONTINOUS	0x1
+#define TIMER_DOWNCOUNT_VAL	0xffffffff
+
+#define PRCMU_TIMER_REF		0
+#define PRCMU_TIMER_DOWNCOUNT	0x4
+#define PRCMU_TIMER_MODE	0x8
+
+#define SCHED_CLOCK_MIN_WRAP 131072 /* 2^32 / 32768 */
+
+void __iomem *clksrc_dbx500_timer_base;
+
+static cycle_t clksrc_dbx500_prcmu_read(struct clocksource *cs)
+{
+	u32 count, count2;
+
+	do {
+		count = readl(clksrc_dbx500_timer_base +
+			      PRCMU_TIMER_DOWNCOUNT);
+		count2 = readl(clksrc_dbx500_timer_base +
+			       PRCMU_TIMER_DOWNCOUNT);
+	} while (count2 != count);
+
+	/* Negate because the timer is a decrementing counter */
+	return ~count;
+}
+
+static struct clocksource clocksource_dbx500_prcmu = {
+	.name		= "dbx500-prcmu-timer",
+	.rating		= 300,
+	.read		= clksrc_dbx500_prcmu_read,
+	.shift		= 10,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+	u32 cyc;
+
+	if (unlikely(!clksrc_dbx500_timer_base))
+		return 0;
+
+	cyc = clksrc_dbx500_prcmu_read(&clocksource_dbx500_prcmu);
+
+	return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace clksrc_dbx500_prcmu_update_sched_clock(void)
+{
+	u32 cyc = clksrc_dbx500_prcmu_read(&clocksource_dbx500_prcmu);
+	update_sched_clock(&cd, cyc, (u32)~0);
+}
+#endif
+
+void __init clksrc_dbx500_prcmu_init(void)
+{
+	/*
+	 * The A9 sub system expects the timer to be configured as
+	 * a continous looping timer.
+	 * The PRCMU should configure it but if it for some reason
+	 * don't we do it here.
+	 */
+	if (readl(clksrc_dbx500_timer_base + PRCMU_TIMER_MODE) !=
+	    TIMER_MODE_CONTINOUS) {
+		writel(TIMER_MODE_CONTINOUS,
+		       clksrc_dbx500_timer_base + PRCMU_TIMER_MODE);
+		writel(TIMER_DOWNCOUNT_VAL,
+		       clksrc_dbx500_timer_base + PRCMU_TIMER_REF);
+	}
+#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK
+	init_sched_clock(&cd, clksrc_dbx500_prcmu_update_sched_clock,
+			 32, RATE_32K);
+#endif
+	clocksource_calc_mult_shift(&clocksource_dbx500_prcmu,
+				    RATE_32K, SCHED_CLOCK_MIN_WRAP);
+	clocksource_register(&clocksource_dbx500_prcmu);
+}
diff --git a/include/linux/clksrc-dbx500-prcmu.h b/include/linux/clksrc-dbx500-prcmu.h
new file mode 100644
index 0000000..d1e9504
--- /dev/null
+++ b/include/linux/clksrc-dbx500-prcmu.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com>
+ *
+ */
+#ifndef __CLKSRC_DBX500_PRCMU_H
+#define __CLKSRC_DBX500_PRCMU_H
+
+#include <linux/init.h>
+#include <linux/io.h>
+
+extern void __iomem *clksrc_dbx500_timer_base;
+
+#ifdef CONFIG_CLKSRC_DBX500_PRCMU
+void __init clksrc_dbx500_prcmu_init(void);
+#else
+void __init clksrc_dbx500_prcmu_init(void) {}
+#endif
+
+#endif
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 1/7] ARM: plat-nomadik: MTU sched_clock as an option
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mattias Wallin <mattias.wallin@stericsson.com>

This patch makes it possible to configure away the sched_clock
part of the MTU timer.

Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Mattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: Jonas Aberg <jonas.aberg@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/plat-nomadik/Kconfig |    8 +++++++-
 arch/arm/plat-nomadik/timer.c |    8 ++++----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index ce65901..bca4914 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -15,10 +15,16 @@ if PLAT_NOMADIK
 
 config HAS_MTU
 	bool
-	select HAVE_SCHED_CLOCK
 	help
 	  Support for Multi Timer Unit. MTU provides access
 	  to multiple interrupt generating programmable
 	  32-bit free running decrementing counters.
 
+config NOMADIK_MTU_SCHED_CLOCK
+	bool
+	depends on HAS_MTU
+	select HAVE_SCHED_CLOCK
+	help
+	  Use the Multi Timer Unit as the sched_clock.
+
 endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index ef74e15..bd638c5 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -24,7 +24,7 @@
 #include <plat/mtu.h>
 
 void __iomem *mtu_base; /* Assigned by machine code */
-
+#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
@@ -48,7 +48,7 @@ static void notrace nomadik_update_sched_clock(void)
 	u32 cyc = -readl(mtu_base + MTU_VAL(0));
 	update_sched_clock(&cd, cyc, (u32)~0);
 }
-
+#endif
 /* Clockevent device: use one-shot mode */
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
 			     struct clock_event_device *dev)
@@ -153,9 +153,9 @@ void __init nmdk_timer_init(void)
 			rate, 200, 32, clocksource_mmio_readl_down))
 		pr_err("timer: failed to initialize clock source %s\n",
 		       "mtu_0");
-
+#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
 	init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
-
+#endif
 	/* Timer 1 is used for events */
 
 	clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
-- 
1.7.3.2

^ permalink raw reply related

* [PATCH 0/7] Ux500 timer patches for 3.2
From: Linus Walleij @ 2011-09-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

From: Linus Walleij <linus.walleij@linaro.org>

This patch series improves the Ux500/Nomadik timers to the point
where we can actually use them in a power-constrained system
which also tend to power off some of them from time to time.

Patches 1 & 2 has been floated before:
http://marc.info/?l=linux-arm-kernel&m=130700730707168&w=2

I'm not gonna claim this solves any issue of lost
sched_clock or so. What it does is to add the PRCMU timer
as an alternative clock source and sched_clock, nothing
more, nothing less.

If sched_clock() can be made to retain its value across
suspend/resume cycles as proposed by Russell here is
a really good question:
http://marc.info/?l=linux-arm-kernel&m=130700801907853&w=2

We would *still* need to be able to use the PRCMU as
clock source, since it's the only truly continous thing
we have in the system, and IIRC from my discussions with
tglx it's really not a good idea to have clock sources
that come and go.

On top of this it merely adds the optional possibility to
also use the PRCMU timer as sched_clock, if the MTU
(Nomadik) timer is not used for this. If this selectable
sched_clock base is frowned upon (there can be only one!)
I can delete those hunks of the patch.

Apart from this we have an update of the MTU (Nomadik)
timer to support periodic mode and some reset calls.

Jonas Aaberg (4):
  ARM: ux500: Move timer code to separate file
  ARM: plat-nomadik: timer: Add support for periodic timers
  ARM: plat-nomadik: timer: Export reset functions
  ARM: ux500: Reprogram timers upon resume

Mattias Wallin (3):
  ARM: plat-nomadik: MTU sched_clock as an option
  clocksource: add DBX500 PRCMU Timer support
  ARM: ux500: add support for clocksource DBX500 PRCMU

 arch/arm/mach-ux500/Makefile                   |    2 +-
 arch/arm/mach-ux500/cpu.c                      |   29 +-----
 arch/arm/mach-ux500/include/mach/db5500-regs.h |    2 +
 arch/arm/mach-ux500/include/mach/db8500-regs.h |    3 +
 arch/arm/mach-ux500/timer.c                    |   65 +++++++++++
 arch/arm/plat-nomadik/Kconfig                  |    8 ++-
 arch/arm/plat-nomadik/include/plat/mtu.h       |   47 +--------
 arch/arm/plat-nomadik/timer.c                  |  138 ++++++++++++++++++------
 drivers/clocksource/Kconfig                    |   15 +++
 drivers/clocksource/Makefile                   |    1 +
 drivers/clocksource/clksrc-dbx500-prcmu.c      |  104 ++++++++++++++++++
 include/linux/clksrc-dbx500-prcmu.h            |   22 ++++
 12 files changed, 330 insertions(+), 106 deletions(-)
 create mode 100644 arch/arm/mach-ux500/timer.c
 create mode 100644 drivers/clocksource/clksrc-dbx500-prcmu.c
 create mode 100644 include/linux/clksrc-dbx500-prcmu.h

-- 
1.7.3.2

^ permalink raw reply

* DT vs ARM static mappings
From: Pawel Moll @ 2011-09-22 13:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110922131302.GO17169@n2100.arm.linux.org.uk>

> > Ok, what I did was grepping for all .map_io-s. Then I sorted the list
> > and had a look at first 100 and about 50% of them were doing more than
> > just creating mappings.
> 
> The answer to that is: they shouldn't be now that we have the init_early
> hook.  The only remainder for .map_io is where platforms make run-time
> decisions about what to map based on some register value somewhere
> (eg, Assabet vs Assabet+Neponset).
> 
> I do have a large patch series floating around in my git tree which tries
> to clean up to all those map_io functions - the biggest stumbling block
> to them is the Samsung stuff being indirected through its own tables.

Awesome. I'll work with an assumption that future map_io-s will only
create static mappings and nothing more then.

Cheers!

Pawe?

^ permalink raw reply

* [PATCH v3 3/3] OMAP3: Remove auto-selection of PMICs
From: Abhilash K V @ 2011-09-22 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316698155-954-3-git-send-email-abhilash.kv@ti.com>

The current implementation almost assumes that only
TWL4030/TWL5030/TWl6030 are (or can be) used with the
OMAP processors. This is, however, not true.

This patch removes the automatic selection of the PMIC
from Kconfig.
All currently used PMICs are now added to omap2plus_defconfig;
any new PMIC that gets supported in future could now be
enabled here rather than by changing Kconfig for
ARCH_OMAP2PLUS_TYPICAL

Signed-off-by: Sanjeev Premi <premi@ti.com>
Signed-off-by: Abhilash K V <abhilash.kv@ti.com>
---
 arch/arm/configs/omap2plus_defconfig |    3 +++
 arch/arm/mach-omap2/Kconfig          |    3 ---
 drivers/mfd/Kconfig                  |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index d5f00d7..076b131 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -130,6 +130,9 @@ CONFIG_POWER_SUPPLY=y
 CONFIG_WATCHDOG=y
 CONFIG_OMAP_WATCHDOG=y
 CONFIG_TWL4030_WATCHDOG=y
+CONFIG_MENELAUS=y
+CONFIG_TWL4030_CORE=y
+CONFIG_TWL4030_POWER=y
 CONFIG_REGULATOR_TWL4030=y
 CONFIG_REGULATOR_TPS65023=y
 CONFIG_REGULATOR_TPS6507X=y
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 7edf802..d40f6d2 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -15,9 +15,6 @@ config ARCH_OMAP2PLUS_TYPICAL
 	select I2C
 	select I2C_OMAP
 	select MFD_SUPPORT
-	select MENELAUS if ARCH_OMAP2
-	select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
-	select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
 	help
 	  Compile a kernel suitable for booting most boards
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 21574bd..72e15c8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -238,7 +238,7 @@ config TWL4030_MADC
 
 config TWL4030_POWER
 	bool "Support power resources on TWL4030 family chips"
-	depends on TWL4030_CORE && ARM
+	depends on TWL4030_CORE
 	help
 	  Say yes here if you want to use the power resources on the
 	  TWL4030 family chips.  Most of these resources are regulators,
-- 
1.7.1

^ permalink raw reply related

* [PATCH v3 2/3] OMAP3: Add support for TPS65023 (AM35x only)
From: Abhilash K V @ 2011-09-22 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316698155-954-2-git-send-email-abhilash.kv@ti.com>

From: Sanjeev Premi <premi@ti.com>

This patch adds support for TPS65023 used with
OMAP3 devices. The PMIC is currently hooked to
AM35x devices, but can easily be extended for
other OMAP3 devices.

Signed-off-by: Sanjeev Premi <premi@ti.com>
Signed-off-by: Abhilash K V <abhilash.kv@ti.com>
---
 arch/arm/mach-omap2/Makefile        |    3 +-
 arch/arm/mach-omap2/pm.c            |    1 +
 arch/arm/mach-omap2/pm.h            |    9 ++++
 arch/arm/mach-omap2/pmic_tps65023.c |   84 +++++++++++++++++++++++++++++++++++
 4 files changed, 96 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pmic_tps65023.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 46a3497..e71e4bc 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -18,7 +18,8 @@ obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common)
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
-obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+obj-$(CONFIG_TWL4030_CORE)		+= omap_twl.o
+obj-$(CONFIG_REGULATOR_TPS65023)	+= pmic_tps65023.o
 
 # SMP support ONLY available for OMAP4
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index da71abc..bb64383 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -255,6 +255,7 @@ static int __init omap2_common_pm_late_init(void)
 	if (omap3_has_sr())
 		omap3_twl_init();
 	omap4_twl_init();
+	omap3_tps65023_init();
 
 	/* Init the voltage layer */
 	omap_voltage_late_init();
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 4e166ad..ce028f6 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -133,5 +133,14 @@ static inline int omap4_twl_init(void)
 	return -EINVAL;
 }
 #endif
+#ifdef CONFIG_REGULATOR_TPS65023
+extern int omap3_tps65023_init(void);
+#else
+static inline int omap3_tps65023_init(void)
+{
+	return -EINVAL;
+}
+#endif
+
 
 #endif
diff --git a/arch/arm/mach-omap2/pmic_tps65023.c b/arch/arm/mach-omap2/pmic_tps65023.c
new file mode 100644
index 0000000..415d804
--- /dev/null
+++ b/arch/arm/mach-omap2/pmic_tps65023.c
@@ -0,0 +1,84 @@
+/**
+ * Implements support for TPS65023
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/i2c/twl.h>
+
+#include "voltage.h"
+
+#include "pm.h"
+
+#define	TPS65023_VDCDC1_MIN		800000	/* 0.8V		*/
+#define	TPS65023_VDCDC1_STEP		25000	/* 0.025V	*/
+
+
+/*
+ * Get voltage corresponding to specified vsel value using this formula:
+ *	Vout = 0.8V + (25mV x Vsel)
+ */
+static unsigned long tps65023_vsel_to_uv(const u8 vsel)
+{
+	return TPS65023_VDCDC1_MIN + (TPS65023_VDCDC1_STEP * vsel);
+}
+
+/*
+ * Get vsel value corresponding to specified voltage using this formula:
+ *	Vsel = (Vout - 0.8V)/ 25mV
+ */
+static u8 tps65023_uv_to_vsel(unsigned long uv)
+{
+	return DIV_ROUND_UP(uv - TPS65023_VDCDC1_MIN, TPS65023_VDCDC1_STEP);
+}
+
+/*
+ * TPS65023 is currently supported only for AM35x devices.
+ * Therefore, implementation below is specific to this device pair.
+ */
+
+/**
+ * Voltage information related to the MPU voltage domain of the
+ * AM35x processors - in relation to the TPS65023.
+ */
+static struct omap_voltdm_pmic tps65023_am35xx_mpu_volt_info = {
+	.step_size		= 25000,
+	.on_volt                = 1200000,
+	.vsel_to_uv		= tps65023_vsel_to_uv,
+	.uv_to_vsel		= tps65023_uv_to_vsel,
+};
+
+int __init omap3_tps65023_init(void)
+{
+	struct voltagedomain *voltdm;
+
+	if (!cpu_is_omap34xx())
+		return -ENODEV;
+
+	if (cpu_is_omap3505() || cpu_is_omap3517()) {
+		voltdm = voltdm_lookup("mpu");
+		omap_voltage_register_pmic(voltdm,
+					&tps65023_am35xx_mpu_volt_info);
+		voltdm = voltdm_lookup("core");
+		omap_voltage_register_pmic(voltdm,
+					&tps65023_am35xx_mpu_volt_info);
+	} else {
+		/* TODO:
+		 * Support for other devices that support TPS65023
+		 */
+	}
+
+	return 0;
+}
-- 
1.7.1

^ permalink raw reply related

* [PATCH v3 1/3] AM35x: voltage: Basic initialization
From: Abhilash K V @ 2011-09-22 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316698155-954-1-git-send-email-abhilash.kv@ti.com>

This patch adds the basic initialization of voltage layer
for AM35x. Since AM35x doesn't support voltage scaling,
Many functions have been defined to plug into existing
voltage layer.

Signed-off-by: Sanjeev Premi <premi@ti.com>
Signed-off-by: Abhilash K V <abhilash.kv@ti.com>
---
 arch/arm/mach-omap2/omap_opp_data.h           |    1 +
 arch/arm/mach-omap2/opp3xxx_data.c            |    9 +++++++++
 arch/arm/mach-omap2/voltagedomains3xxx_data.c |   10 ++++++++--
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
index c784c12..c7cedf3 100644
--- a/arch/arm/mach-omap2/omap_opp_data.h
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -88,6 +88,7 @@ extern struct omap_volt_data omap34xx_vddmpu_volt_data[];
 extern struct omap_volt_data omap34xx_vddcore_volt_data[];
 extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
 extern struct omap_volt_data omap36xx_vddcore_volt_data[];
+extern struct omap_volt_data am35xx_vdd_volt_data[];
 
 extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
 extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index d95f3f9..e4a5ee6 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -85,6 +85,15 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = {
 	VOLT_DATA_DEFINE(0, 0, 0, 0),
 };
 
+/* AM35x
+ *
+ * Fields related to SmartReflex and Voltage Processor are set to 0.
+ */
+struct omap_volt_data am35xx_vdd_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, 0x0, 0x0, 0x0),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
 /* OPP data */
 
 static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index 071101d..530082f 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -85,7 +85,10 @@ void __init omap3xxx_voltagedomains_init(void)
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
-	if (cpu_is_omap3630()) {
+	if (cpu_is_omap3505() || cpu_is_omap3517()) {
+		omap3_voltdm_mpu.volt_data = am35xx_vdd_volt_data;
+		omap3_voltdm_core.volt_data = am35xx_vdd_volt_data;
+	} else if (cpu_is_omap3630()) {
 		omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data;
 		omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data;
 	} else {
@@ -93,8 +96,11 @@ void __init omap3xxx_voltagedomains_init(void)
 		omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
 	}
 
-	for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++)
+	for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++) {
+		if (cpu_is_omap3505() || cpu_is_omap3517())
+			voltdm->scalable = false;
 		voltdm->sys_clk.name = sys_clk_name;
+	}
 
 	voltdm_init(voltagedomains_omap3);
 };
-- 
1.7.1

^ permalink raw reply related

* [PATCH v3 0/3] AM35x: Adding PM init
From: Abhilash K V @ 2011-09-22 13:29 UTC (permalink / raw)
  To: linux-arm-kernel

This patch-set fixes the power and voltage management initialization sequence
for AM35x.
These patches are dependent on the following patch-set
	[PATCH v4 0/3] AM3517: Booting up
which gets the AM3517 EVM booting.

The patches are tested on master of git://github.com/tmlind/linux.git
Kernel version is 3.1.0-rc6 and last commit on top of which these patches
were added is:
	0c2838d00350afc5259730c35bbda81598e8875f: Linux-omap rebuilt: Updated
	to -rc7, merged in dmtimer

Cc: Sanjeev Premi <premi@ti.com>
---
Changes in v3:
  * Reworked against the cleaned-up voltage management layer.
Changes in v2:
  * TWL4030 CORE and POWER drivers are no longer built only for ARM and OMAP
  * changed comments to mark AM35x voltgate-scaling code as ad hoc

Abhilash K V (2):
  AM35x: voltage: Basic initialization
  OMAP3: Remove auto-selection of PMICs

Sanjeev Premi (1):
  OMAP3: Add support for TPS65023 (AM35x only)

 arch/arm/configs/omap2plus_defconfig          |    3 +
 arch/arm/mach-omap2/Kconfig                   |    3 -
 arch/arm/mach-omap2/Makefile                  |    3 +-
 arch/arm/mach-omap2/omap_opp_data.h           |    1 +
 arch/arm/mach-omap2/opp3xxx_data.c            |    9 +++
 arch/arm/mach-omap2/pm.c                      |    1 +
 arch/arm/mach-omap2/pm.h                      |    9 +++
 arch/arm/mach-omap2/pmic_tps65023.c           |   84 +++++++++++++++++++++++++
 arch/arm/mach-omap2/voltagedomains3xxx_data.c |   10 +++-
 drivers/mfd/Kconfig                           |    2 +-
 10 files changed, 118 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pmic_tps65023.c

^ permalink raw reply

* [PATCH] arm/tegra: select AUTO_ZRELADDR by default
From: Peter De Schrijver @ 2011-09-22 13:27 UTC (permalink / raw)
  To: linux-arm-kernel

This patch causes the kernel uncompressor to determine the physical address
of the SDRAM at runtime. This allows the kernel to boot on both tegra2 and
tegra3 even though SDRAM is at different physical addresses on both SoCs.

Change-Id: I91857a590946bbc54168c04bea3a5bd576d87824
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
 arch/arm/Kconfig |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4fda167..9fc0678 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -600,6 +600,7 @@ config ARCH_TEGRA
 	select HAVE_CLK
 	select HAVE_SCHED_CLOCK
 	select ARCH_HAS_CPUFREQ
+	select AUTO_ZRELADDR
 	help
 	  This enables support for NVIDIA Tegra based systems (Tegra APX,
 	  Tegra 6xx and Tegra 2 series).
-- 
1.7.7.rc0.72.g4b5ea.dirty

^ permalink raw reply related

* [PATCH v4 3/3] OMAP2+: voltage: add check for missing PMIC info in vp init
From: Abhilash K V @ 2011-09-22 13:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316697993-696-3-git-send-email-abhilash.kv@ti.com>

If PMIC info is not available in omap_vp_init(), abort.

Signed-off-by: Abhilash K V <abhilash.kv@ti.com>
---
 arch/arm/mach-omap2/vp.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 66bd700..2c99837 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -41,6 +41,13 @@ void __init omap_vp_init(struct voltagedomain *voltdm)
 	u32 val, sys_clk_rate, timeout, waittime;
 	u32 vddmin, vddmax, vstepmin, vstepmax;
 
+	if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+		pr_err("%s: PMIC info requried to configure vp for"
+			"vdd_%s not populated.Hence cannot initialize vp\n",
+			__func__, voltdm->name);
+		return;
+	}
+
 	if (!voltdm->read || !voltdm->write) {
 		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
 			__func__, voltdm->name);
-- 
1.7.1

^ permalink raw reply related

* [PATCH v4 2/3] omap_twl: Prevent SR to enable for am3517/am3505 devices
From: Abhilash K V @ 2011-09-22 13:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316697993-696-2-git-send-email-abhilash.kv@ti.com>

In case of AM3517 & AM3505, SmartReflex is not applicable so
we must not enable it. So omap3_twl_init() is now not called
when the processor does not support SR.

Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Abhilash K V <abhilash.kv@ti.com>
---
 arch/arm/mach-omap2/id.c              |    2 +-
 arch/arm/mach-omap2/pm.c              |    3 ++-
 arch/arm/plat-omap/include/plat/cpu.h |    2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index d27daf9..b7e3082 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -188,7 +188,7 @@ static void __init omap3_check_features(void)
 	if (cpu_is_omap3630())
 		omap_features |= OMAP3_HAS_192MHZ_CLK;
 	if (!cpu_is_omap3505() && !cpu_is_omap3517())
-		omap_features |= OMAP3_HAS_IO_WAKEUP;
+		omap_features |= (OMAP3_HAS_IO_WAKEUP | OMAP3_HAS_SR);
 
 	omap_features |= OMAP3_HAS_SDRC;
 
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d34fc52..da71abc 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -252,7 +252,8 @@ postcore_initcall(omap2_common_pm_init);
 static int __init omap2_common_pm_late_init(void)
 {
 	/* Init the OMAP TWL parameters */
-	omap3_twl_init();
+	if (omap3_has_sr())
+		omap3_twl_init();
 	omap4_twl_init();
 
 	/* Init the voltage layer */
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 2f90269..cc6fcd3 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -413,6 +413,7 @@ extern u32 omap_features;
 #define OMAP4_HAS_MPU_1GHZ		BIT(8)
 #define OMAP4_HAS_MPU_1_2GHZ		BIT(9)
 #define OMAP4_HAS_MPU_1_5GHZ		BIT(10)
+#define OMAP3_HAS_SR			BIT(11)
 
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
@@ -429,6 +430,7 @@ OMAP3_HAS_FEATURE(isp, ISP)
 OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
+OMAP3_HAS_FEATURE(sr, SR)
 
 /*
  * Runtime detection of OMAP4 features
-- 
1.7.1

^ permalink raw reply related

* [PATCH v4 1/3] AM35x: Using OMAP3 generic hwmods
From: Abhilash K V @ 2011-09-22 13:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316697993-696-1-git-send-email-abhilash.kv@ti.com>

This patch enables AM35x SoCs to use generic OMAP3 hwmods
(i,e. omap3xxx_hwmods) by allowing am35xx_init_early() to
disable the modules which are not present in AM3517.

Reviewed-by: Sanjeev Premi <premi@ti.com>
Signed-off-by: Abhilash K V <abhilash.kv@ti.com>
---
 arch/arm/mach-omap2/io.c                     |   11 +++++++++++
 arch/arm/mach-omap2/omap_hwmod.c             |    2 ++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c   |   18 ++++++++++++++++++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    3 +++
 4 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 15f91c4..6a6e2cc 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -240,6 +240,16 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
 };
 #endif
 
+static char *am3517_unused_hwmods[] = {
+	"iva",
+	"sr1_hwmod",
+	"sr2_hwmod",
+	"mailbox",
+	"usb_otg_hs",
+	NULL,
+};
+
+
 static void __init _omap2_map_common_io(void)
 {
 	/* Normally devicemaps_init() would flush caches and tlb after
@@ -432,6 +442,7 @@ void __init omap3630_init_early(void)
 
 void __init am35xx_init_early(void)
 {
+	omap2_disable_unused_hwmods(am3517_unused_hwmods);
 	omap2_init_common_infrastructure();
 }
 
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index d713807..c7b0395 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1954,6 +1954,8 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs)
 
 	i = 0;
 	do {
+		if (ohs[i]->flags & HWMOD_UNUSED)
+			continue;
 		r = _register(ohs[i]);
 		WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name,
 		     r);
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 3008e16..682171c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3259,6 +3259,24 @@ static __initdata struct omap_hwmod *am35xx_hwmods[] = {
 	NULL
 };
 
+void __init omap2_disable_unused_hwmods(char *unused_hwmods[])
+{
+	int index;
+
+	for (index = 0; omap3xxx_hwmods[index]; index++) {
+		char **hwmods = unused_hwmods;
+		while (*hwmods) {
+			if (strcmp(omap3xxx_hwmods[index]->name,
+					*hwmods) == 0) {
+				omap3xxx_hwmods[index]->flags
+							= HWMOD_UNUSED;
+				break;
+			}
+			hwmods++;
+		}
+	}
+}
+
 int __init omap3xxx_hwmod_init(void)
 {
 	int r;
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 5419f1a..96650f3 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -398,6 +398,7 @@ struct omap_hwmod_omap4_prcm {
  *     in order to complete the reset. Optional clocks will be disabled
  *     again after the reset.
  * HWMOD_16BIT_REG: Module has 16bit registers
+ * HWMOD_UNUSED: The IP for this module is unused or disabled on current SoC
  */
 #define HWMOD_SWSUP_SIDLE			(1 << 0)
 #define HWMOD_SWSUP_MSTANDBY			(1 << 1)
@@ -408,6 +409,7 @@ struct omap_hwmod_omap4_prcm {
 #define HWMOD_NO_IDLEST				(1 << 6)
 #define HWMOD_CONTROL_OPT_CLKS_IN_RESET		(1 << 7)
 #define HWMOD_16BIT_REG				(1 << 8)
+#define HWMOD_UNUSED				(1 << 9)
 
 /*
  * omap_hwmod._int_flags definitions
@@ -612,5 +614,6 @@ extern int omap2420_hwmod_init(void);
 extern int omap2430_hwmod_init(void);
 extern int omap3xxx_hwmod_init(void);
 extern int omap44xx_hwmod_init(void);
+extern void omap2_disable_unused_hwmods(char *unused_hwmods[]);
 
 #endif
-- 
1.7.1

^ permalink raw reply related

* [PATCH v4 0/3] AM3517: Booting up
From: Abhilash K V @ 2011-09-22 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

This patch-set gets the kernel booting up on a AM3517 EVM.
The board is able to boot with ramdisk after this,but the MMC and Ethernet
drivers are not up yet. Lots of warnings remain which will be addressed in
subsequent patches.

The patches are tested on master of git://github.com/tmlind/linux.git
Kernel version is 3.1.0-rc6 and last commit on top of which these patches
were added is:
	0c2838d00350afc5259730c35bbda81598e8875f: Linux-omap rebuilt: Updated
	to -rc7, merged in dmtimer

Cc: Sanjeev Premi <premi@ti.com>
---
Changes in v4:
 -Rebased and tested against the latest 3.1.0-rc6.
 -Added a patch [3/3] to check for missing PMIC info in vp init.

Changes in v3:
 Presence of SR feature is now used to decide if TWL4030 initialisation is to
 be done or not.

Changes in v2: Incorporated Kevin's comments to add SmartReflex as a FEATURE,
  and use omap3_has_sr() to fall out of omap3_twl_init() for AM35x case.
	

Abhilash K V (3):
  AM35x: Using OMAP3 generic hwmods
  omap_twl: Prevent SR to enable for am3517/am3505 devices
  OMAP2+: voltage: add check for missing PMIC info in vp init

 arch/arm/mach-omap2/id.c                     |    2 +-
 arch/arm/mach-omap2/io.c                     |   11 +++++++++++
 arch/arm/mach-omap2/omap_hwmod.c             |    2 ++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c   |   18 ++++++++++++++++++
 arch/arm/mach-omap2/pm.c                     |    3 ++-
 arch/arm/mach-omap2/vp.c                     |    7 +++++++
 arch/arm/plat-omap/include/plat/cpu.h        |    2 ++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    3 +++
 8 files changed, 46 insertions(+), 2 deletions(-)

^ permalink raw reply

* [PATCH] arm: Add unwinding annotations for 64bit division functions
From: Jon Medhurst (Tixy) @ 2011-09-22 13:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110922130031.GK12025@e102109-lin.cambridge.arm.com>

On Thu, 2011-09-22 at 14:00 +0100, Catalin Marinas wrote:
> The unwinding fix should be simple (I haven't tested it yet):
> 
> 8<-----------------------------
> ARM: Ignore the unwinding information for the first instruction in a function
> 
> From: Catalin Marinas <catalin.marinas@arm.com>
> 
> When backtracing from the first instruction of a function, the prologue
> has not been executed and the unwinding information is not valid. This
> patch checks for this case and just assumes that the return address is
> in LR.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm/kernel/unwind.c |   10 ++++++++++
>  1 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
> index d2cb0b3..946face 100644
> --- a/arch/arm/kernel/unwind.c
> +++ b/arch/arm/kernel/unwind.c
> @@ -293,6 +293,16 @@ int unwind_frame(struct stackframe *frame)
>  		return -URC_FAILURE;
>  	}
>  
> +	/*
> +	 * Check for backtrace on the first instruction of a function. The
> +	 * prologue has not been executed yet and the unwinding information is
> +	 * not valid. Assume that the return address is in LR.
> +	 */
> +	if (idx.addr == frame->pc) {
> +		frame->pc = frame->lr;
> +		return URC_OK;
> +	}
> +
>  	ctrl.vrs[FP] = frame->fp;
>  	ctrl.vrs[SP] = frame->sp;
>  	ctrl.vrs[LR] = frame->lr;
> 

I've never looked at the unwinding code before but the one comment I
would make is: does the patch work with Thumb code? I.e. does bit zero
of idx.addr, frame->pc or frame->lr ever get set to indicate Thumb
state? And if so, they had better all get set otherwise it won't
work :-)

-- 
Tixy

^ permalink raw reply

* DT vs ARM static mappings
From: Russell King - ARM Linux @ 2011-09-22 13:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316696696.4611.844.camel@hornet.cambridge.arm.com>

On Thu, Sep 22, 2011 at 02:04:56PM +0100, Pawel Moll wrote:
> > > ARM machine description contains a "map_io" method, which is used to
> > > create static memory mappings (using iotable_init() function) for things
> > > like peripherals or SRAMs. At least that's the theory, because most of
> > > the platforms are doing much more stuff there, like clocking/GPIOs/UARTs
> > > initialization, hardware probing etc.
> > 
> > No, most of them don't.  Maybe a few cases do for historical reasons, 
> > but there are other hooks now to link probing and initialization code 
> > to.
> 
> Ok, what I did was grepping for all .map_io-s. Then I sorted the list
> and had a look at first 100 and about 50% of them were doing more than
> just creating mappings.

The answer to that is: they shouldn't be now that we have the init_early
hook.  The only remainder for .map_io is where platforms make run-time
decisions about what to map based on some register value somewhere
(eg, Assabet vs Assabet+Neponset).

I do have a large patch series floating around in my git tree which tries
to clean up to all those map_io functions - the biggest stumbling block
to them is the Samsung stuff being indirected through its own tables.

Of course, with all the changes to .boot_params etc, the patches no longer
apply to current kernels.

^ permalink raw reply

* DT vs ARM static mappings
From: Pawel Moll @ 2011-09-22 13:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1109211320090.12663@xanadu.home>

> > ARM machine description contains a "map_io" method, which is used to
> > create static memory mappings (using iotable_init() function) for things
> > like peripherals or SRAMs. At least that's the theory, because most of
> > the platforms are doing much more stuff there, like clocking/GPIOs/UARTs
> > initialization, hardware probing etc.
> 
> No, most of them don't.  Maybe a few cases do for historical reasons, 
> but there are other hooks now to link probing and initialization code 
> to.

Ok, what I did was grepping for all .map_io-s. Then I sorted the list
and had a look at first 100 and about 50% of them were doing more than
just creating mappings.

Never mind - I'll rephrase myself to "many" instead of "most" :-)

> The static mappings should be just that: static.  Most things should be 
> dynamically mapped instead.  With the series I'm working on, everybody 
> will get the benefit of a static mapping when one is available even if 
> the dynamic mapping interface like ioremap() is used.  So having a bunch 
> of static mappings is not bad, especially if they are easy.  But you 
> should defer as much hardware probing as possible after the memory is 
> initialized and the standard interfaces are available, keeping reliance 
> on direct access to static mappings as small as possible.

You won't get any argument from me here - my task would be easier
without the additional things happening in map_io...

> Your best bet would probably consist of keeping the virtual address 
> constant while the physical address is variable.  Adjusting the .pfn 
> field in the v2m_io_desc table right before calling iotable_init() 
> should be fine.  Alternatively you could have two such tables and select 
> the right one at run time.  The io_p2v macro doesn't make any sense 
> anymore in that context so it should be eliminated, and keeping only a 
> minimum set of fixed virtual addresses for the peripherals that can't 
> wait until ioremap is available should be fine.

Yep, that's (roughly) what my code is doing now. There is some hackery
involved (manual operations on pointers) that will disappear with your
changes.

And MMIO_P2V macro is dying - motherboard code is not using it any more,
the tile code will stop using it next week.

> And if static mappings are a problem, then try to live without them as 
> much as possible.  Again there is no reason you should be doing too much 
> hardware probing at .map_io time.

Current implementation is doing very little (just probing tile ID and
calling tile's private map_io) but it's enough to be a pain in the neck.

Anyway, patch (on top of Dave's initial support) to follow soon.

Cheers!

Pawe?

^ permalink raw reply

* [PATCH] arm: Add unwinding annotations for 64bit division functions
From: Catalin Marinas @ 2011-09-22 13:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316693581.2053.38.camel@linaro1>

On Thu, Sep 22, 2011 at 01:13:01PM +0100, Jon Medhurst (Tixy) wrote:
> On Thu, 2011-09-22 at 12:57 +0100, Catalin Marinas wrote:
> > On Thu, Sep 22, 2011 at 12:06:46PM +0100, Jon Medhurst (Tixy) wrote:
> > > On Thu, 2011-09-22 at 10:48 +0100, Catalin Marinas wrote:
> > > > We could improve things a bit in the unwinder and assume
> > > > that if the fault address is the same as the .fnstart address, the
> > > > return value is always in LR and the SP not affected (that's unwinding
> > > > bytecode 0xb0). For a few instructions into the function prologue we
> > > > can't reliably get the unwinding information.
> > > 
> > > That would help make it possible to unwind out of kprobes handlers to
> > > the probed function. The kprobes code itself would need work as well,
> > > and possibly the undef handler. Do we think it is worthwhile to do
> > > this? 
> > 
> > Does kprobes need to trace beyond the probed function? If not, you get
> > the address of the probed function via pt_regs anyway, so no need for
> > unwinding beyond that.
> 
> To be honest, I'm not very sure how kprobes get used in the real world.
> Though, if stack unwinding from their handlers currently doesn't work
> and people had a usecase for it, we would expect them to complain.

The unwinding fix should be simple (I haven't tested it yet):

8<-----------------------------
ARM: Ignore the unwinding information for the first instruction in a function

From: Catalin Marinas <catalin.marinas@arm.com>

When backtracing from the first instruction of a function, the prologue
has not been executed and the unwinding information is not valid. This
patch checks for this case and just assumes that the return address is
in LR.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/kernel/unwind.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index d2cb0b3..946face 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -293,6 +293,16 @@ int unwind_frame(struct stackframe *frame)
 		return -URC_FAILURE;
 	}
 
+	/*
+	 * Check for backtrace on the first instruction of a function. The
+	 * prologue has not been executed yet and the unwinding information is
+	 * not valid. Assume that the return address is in LR.
+	 */
+	if (idx.addr == frame->pc) {
+		frame->pc = frame->lr;
+		return URC_OK;
+	}
+
 	ctrl.vrs[FP] = frame->fp;
 	ctrl.vrs[SP] = frame->sp;
 	ctrl.vrs[LR] = frame->lr;

-- 
Catalin

^ permalink raw reply related

* booting single uImage on platforms with different base addresses for SDRAM
From: Nicolas Pitre @ 2011-09-22 12:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110922111523.GM17169@n2100.arm.linux.org.uk>

On Thu, 22 Sep 2011, Russell King - ARM Linux wrote:

> On Thu, Sep 22, 2011 at 02:04:12PM +0300, Peter De Schrijver wrote:
> > Currently uImages have the load address hardcoded. As we now try to support
> > as many ARM platforms as possible with a single binary, this becomes a
> > problem. On tegra20 SDRAM starts at physical address 0, but on tegra30 SDRAM
> > starts at 0x80000000. It's possible to build a kernel image which can deal
> > with this, but the uImage still uses a hardcoded address. This results
> > in requiring 2 different uImages even though the zImage is the same.
> 
> This is a problem with the uImage format.  It can only be fixed in uboot
> - it's not a kernel problem.
> 
> > Has anyone thought of a solution to this problem?
> 
> There was talk about making '0' or something a special address, and
> fixing uboot to place it appropriately (in much the same way that the
> other boot loaders such as blob's offset from the start of RAM, or
> redboot's scripted loading which takes the load address.)

... or make u-Boot support plain zImage on ARM (like it apparently does 
for MIPS).  The u-Boot load command can accept a destination memory 
address just fine, but u-Boot always insists on relocating it when it is 
a uImage.


Nicolas

^ 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