Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 295803
b: refs/heads/master
c: b2f1df8
h: refs/heads/master
i:
  295801: 7147975
  295799: f9b054f
v: v3
  • Loading branch information
Arnd Bergmann committed Mar 20, 2012
1 parent bd59f26 commit a12abb7
Show file tree
Hide file tree
Showing 50 changed files with 521 additions and 538 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5cd9eb2736a572a9ef2689829f47ffd4262adc00
refs/heads/master: b2f1df8d2fc14bf7e6d9d967043d4b60c2efd8dc
48 changes: 48 additions & 0 deletions trunk/Documentation/devicetree/bindings/arm/twd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
* ARM Timer Watchdog

ARM 11MP, Cortex-A5 and Cortex-A9 are often associated with a per-core
Timer-Watchdog (aka TWD), which provides both a per-cpu local timer
and watchdog.

The TWD is usually attached to a GIC to deliver its two per-processor
interrupts.

** Timer node required properties:

- compatible : Should be one of:
"arm,cortex-a9-twd-timer"
"arm,cortex-a5-twd-timer"
"arm,arm11mp-twd-timer"

- interrupts : One interrupt to each core

- reg : Specify the base address and the size of the TWD timer
register window.

Example:

twd-timer@2c000600 {
compatible = "arm,arm11mp-twd-timer"";
reg = <0x2c000600 0x20>;
interrupts = <1 13 0xf01>;
};

** Watchdog node properties:

- compatible : Should be one of:
"arm,cortex-a9-twd-wdt"
"arm,cortex-a5-twd-wdt"
"arm,arm11mp-twd-wdt"

- interrupts : One interrupt to each core

- reg : Specify the base address and the size of the TWD watchdog
register window.

Example:

twd-watchdog@2c000620 {
compatible = "arm,arm11mp-twd-wdt";
reg = <0x2c000620 0x20>;
interrupts = <1 14 0xf01>;
};
8 changes: 4 additions & 4 deletions trunk/arch/arm/boot/dts/highbank.dts
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@
ranges;

timer@fff10600 {
compatible = "arm,smp-twd";
compatible = "arm,cortex-a9-twd-timer";
reg = <0xfff10600 0x20>;
interrupts = <1 13 0xf04>;
interrupts = <1 13 0xf01>;
};

watchdog@fff10620 {
compatible = "arm,cortex-a9-wdt";
compatible = "arm,cortex-a9-twd-wdt";
reg = <0xfff10620 0x20>;
interrupts = <1 14 0xf04>;
interrupts = <1 14 0xf01>;
};

intc: interrupt-controller@fff11000 {
Expand Down
6 changes: 3 additions & 3 deletions trunk/arch/arm/boot/dts/imx6q.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@
ranges;

timer@00a00600 {
compatible = "arm,smp-twd";
reg = <0x00a00600 0x100>;
interrupts = <1 13 0xf4>;
compatible = "arm,cortex-a9-twd-timer";
reg = <0x00a00600 0x20>;
interrupts = <1 13 0xf01>;
};

L2: l2-cache@00a02000 {
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/arm/include/asm/hardware/arm_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
*
* Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
* can have 16-bit or 32-bit selectable via a bit in the control register.
*
* Every SP804 contains two identical timers.
*/
#define TIMER_1_BASE 0x00
#define TIMER_2_BASE 0x20

#define TIMER_LOAD 0x00 /* ACVR rw */
#define TIMER_VALUE 0x04 /* ACVR ro */
#define TIMER_CTRL 0x08 /* ACVR rw */
Expand Down
37 changes: 7 additions & 30 deletions trunk/arch/arm/include/asm/localtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,24 @@
#define __ASM_ARM_LOCALTIMER_H

#include <linux/errno.h>
#include <linux/interrupt.h>

struct clock_event_device;

/*
* Setup a per-cpu timer, whether it be a local timer or dummy broadcast
*/
void percpu_timer_setup(void);
struct local_timer_ops {
int (*setup)(struct clock_event_device *);
void (*stop)(struct clock_event_device *);
};

#ifdef CONFIG_LOCAL_TIMERS

#ifdef CONFIG_HAVE_ARM_TWD

#include "smp_twd.h"

#define local_timer_stop(c) twd_timer_stop((c))

#else

/*
* Stop the local timer
*/
void local_timer_stop(struct clock_event_device *);

#endif

/*
* Setup a local timer interrupt for a CPU.
* Register a local timer driver
*/
int local_timer_setup(struct clock_event_device *);

int local_timer_register(struct local_timer_ops *);
#else

static inline int local_timer_setup(struct clock_event_device *evt)
static inline int local_timer_register(struct local_timer_ops *ops)
{
return -ENXIO;
}

static inline void local_timer_stop(struct clock_event_device *evt)
{
}
#endif

#endif
25 changes: 21 additions & 4 deletions trunk/arch/arm/include/asm/smp_twd.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,28 @@
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)

struct clock_event_device;
#include <linux/ioport.h>

extern void __iomem *twd_base;
struct twd_local_timer {
struct resource res[2];
};

void twd_timer_setup(struct clock_event_device *);
void twd_timer_stop(struct clock_event_device *);
#define DEFINE_TWD_LOCAL_TIMER(name,base,irq) \
struct twd_local_timer name __initdata = { \
.res = { \
DEFINE_RES_MEM(base, 0x10), \
DEFINE_RES_IRQ(irq), \
}, \
};

int twd_local_timer_register(struct twd_local_timer *);

#ifdef CONFIG_HAVE_ARM_TWD
void twd_local_timer_of_register(void);
#else
static inline void twd_local_timer_of_register(void)
{
}
#endif

#endif
22 changes: 19 additions & 3 deletions trunk/arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
store_cpu_topology(cpuid);
}

static void percpu_timer_setup(void);

/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
Expand Down Expand Up @@ -459,15 +461,28 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
clockevents_register_device(evt);
}

void __cpuinit percpu_timer_setup(void)
static struct local_timer_ops *lt_ops;

#ifdef CONFIG_LOCAL_TIMERS
int local_timer_register(struct local_timer_ops *ops)
{
if (lt_ops)
return -EBUSY;

lt_ops = ops;
return 0;
}
#endif

static void __cpuinit percpu_timer_setup(void)
{
unsigned int cpu = smp_processor_id();
struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);

evt->cpumask = cpumask_of(cpu);
evt->broadcast = smp_timer_broadcast;

if (local_timer_setup(evt))
if (!lt_ops || lt_ops->setup(evt))
broadcast_timer_setup(evt);
}

Expand All @@ -482,7 +497,8 @@ static void percpu_timer_stop(void)
unsigned int cpu = smp_processor_id();
struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);

local_timer_stop(evt);
if (lt_ops)
lt_ops->stop(evt);
}
#endif

Expand Down
Loading

0 comments on commit a12abb7

Please sign in to comment.