Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98130278 authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'swarren-for-3.9-arm-timer-rework' of...

Merge tag 'swarren-for-3.9-arm-timer-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/cleanup

From Stephen Warren:
ARM/...: timer and clock events cleanup, and remove struct sys_timer

This branch contains a number of cleanups and unifications to various
timer- clock-events- and ARM timer code. The main points are:

1) Convert arch_gettimeoffset to a pointer, so that architectures with
   multiple timer implementations can simply set this standard pointer
   rather than maintaining their own arch-specific pointers for the
   same purpose. Various architectures are converted to using this new
   feature.

2) Conversion of ARM timer implementations to use clock_event_devices's
   suspend/resume operations, rather than the ARM-specific sys_timer
   versions. Thus, the ARM code begins to use more common infra-structure
   rather than arch-specific code.

3) Removal of ARM's struct sys_timer completely, now that everything uses
   common code.

4) Introduction of drivers/clocksource/clksrc-of.c, which allows ARM clock
   source implementations to be moved into drivers/clocksource, with the
   need to add SoC-specific header files for each timer initialization
   function; instead, all enabled implementations are registered into a
   table which a single core function iterates over, and calls the
   relevant initialization functions based on device tree. At least the
   Tegra and BCM2835 clocksource implementations will use this feature in
   the 3.9 kernel cycle.

* tag 'swarren-for-3.9-arm-timer-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra

:
  clocksource: add common of_clksrc_init() function
  ARM: delete struct sys_timer
  ARM: remove struct sys_timer suspend and resume fields
  ARM: samsung: register syscore_ops for timer resume directly
  ARM: ux500: convert timer suspend/resume to clock_event_device
  ARM: sa1100: convert timer suspend/resume to clock_event_device
  ARM: pxa: convert timer suspend/resume to clock_event_device
  ARM: at91: convert timer suspend/resume to clock_event_device
  ARM: set arch_gettimeoffset directly
  m68k: set arch_gettimeoffset directly
  time: convert arch_gettimeoffset to a pointer
  cris: move usec/nsec conversion to do_slow_gettimeoffset

Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents d1c3ed66 ae278a93
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@

struct tag;
struct meminfo;
struct sys_timer;
struct pt_regs;
struct smp_operations;
#ifdef CONFIG_SMP
@@ -48,7 +47,7 @@ struct machine_desc {
	void			(*map_io)(void);/* IO mapping function	*/
	void			(*init_early)(void);
	void			(*init_irq)(void);
	struct sys_timer	*timer;		/* system tick timer	*/
	void			(*init_time)(void);
	void			(*init_machine)(void);
	void			(*init_late)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
+0 −30
Original line number Diff line number Diff line
@@ -10,36 +10,6 @@
#ifndef __ASM_ARM_MACH_TIME_H
#define __ASM_ARM_MACH_TIME_H

/*
 * This is our kernel timer structure.
 *
 * - init
 *   Initialise the kernels jiffy timer source, claim interrupt
 *   using setup_irq.  This is called early on during initialisation
 *   while interrupts are still disabled on the local CPU.
 * - suspend
 *   Suspend the kernel jiffy timer source, if necessary.  This
 *   is called with interrupts disabled, after all normal devices
 *   have been suspended.  If no action is required, set this to
 *   NULL.
 * - resume
 *   Resume the kernel jiffy timer source, if necessary.  This
 *   is called with interrupts disabled before any normal devices
 *   are resumed.  If no action is required, set this to NULL.
 * - offset
 *   Return the timer offset in microseconds since the last timer
 *   interrupt.  Note: this must take account of any unprocessed
 *   timer interrupt which may be pending.
 */
struct sys_timer {
	void			(*init)(void);
	void			(*suspend)(void);
	void			(*resume)(void);
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
	unsigned long		(*offset)(void);
#endif
};

extern void timer_tick(void);

struct timespec;
+1 −52
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@
#include <linux/timex.h>
#include <linux/errno.h>
#include <linux/profile.h>
#include <linux/syscore_ops.h>
#include <linux/timer.h>
#include <linux/irq.h>

@@ -31,11 +30,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>

/*
 * Our system timer.
 */
static struct sys_timer *system_timer;

#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \
    defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE)
/* this needs a better home */
@@ -69,16 +63,6 @@ unsigned long profile_pc(struct pt_regs *regs)
EXPORT_SYMBOL(profile_pc);
#endif

#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
u32 arch_gettimeoffset(void)
{
	if (system_timer->offset != NULL)
		return system_timer->offset() * 1000;

	return 0;
}
#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */

#ifndef CONFIG_GENERIC_CLOCKEVENTS
/*
 * Kernel system timer support.
@@ -129,43 +113,8 @@ int __init register_persistent_clock(clock_access_fn read_boot,
	return -EINVAL;
}

#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
static int timer_suspend(void)
{
	if (system_timer->suspend)
		system_timer->suspend();

	return 0;
}

static void timer_resume(void)
{
	if (system_timer->resume)
		system_timer->resume();
}
#else
#define timer_suspend NULL
#define timer_resume NULL
#endif

static struct syscore_ops timer_syscore_ops = {
	.suspend	= timer_suspend,
	.resume		= timer_resume,
};

static int __init timer_init_syscore_ops(void)
{
	register_syscore_ops(&timer_syscore_ops);

	return 0;
}

device_initcall(timer_init_syscore_ops);

void __init time_init(void)
{
	system_timer = machine_desc->timer;
	system_timer->init();
	machine_desc->init_time();
	sched_clock_postinit();
}
+0 −5
Original line number Diff line number Diff line
@@ -274,8 +274,3 @@ void __init at91rm9200_timer_init(void)
	/* register clocksource */
	clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
}

struct sys_timer at91rm9200_timer = {
	.init		= at91rm9200_timer_init,
};
+27 −26
Original line number Diff line number Diff line
@@ -104,12 +104,38 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
	}
}

static void at91sam926x_pit_suspend(struct clock_event_device *cedev)
{
	/* Disable timer */
	pit_write(AT91_PIT_MR, 0);
}

static void at91sam926x_pit_reset(void)
{
	/* Disable timer and irqs */
	pit_write(AT91_PIT_MR, 0);

	/* Clear any pending interrupts, wait for PIT to stop counting */
	while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0)
		cpu_relax();

	/* Start PIT but don't enable IRQ */
	pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
}

static void at91sam926x_pit_resume(struct clock_event_device *cedev)
{
	at91sam926x_pit_reset();
}

static struct clock_event_device pit_clkevt = {
	.name		= "pit",
	.features	= CLOCK_EVT_FEAT_PERIODIC,
	.shift		= 32,
	.rating		= 100,
	.set_mode	= pit_clkevt_mode,
	.suspend	= at91sam926x_pit_suspend,
	.resume		= at91sam926x_pit_resume,
};


@@ -150,19 +176,6 @@ static struct irqaction at91sam926x_pit_irq = {
	.irq		= NR_IRQS_LEGACY + AT91_ID_SYS,
};

static void at91sam926x_pit_reset(void)
{
	/* Disable timer and irqs */
	pit_write(AT91_PIT_MR, 0);

	/* Clear any pending interrupts, wait for PIT to stop counting */
	while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0)
		cpu_relax();

	/* Start PIT but don't enable IRQ */
	pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
}

#ifdef CONFIG_OF
static struct of_device_id pit_timer_ids[] = {
	{ .compatible = "atmel,at91sam9260-pit" },
@@ -211,7 +224,7 @@ static int __init of_at91sam926x_pit_init(void)
/*
 * Set up both clocksource and clockevent support.
 */
static void __init at91sam926x_pit_init(void)
void __init at91sam926x_pit_init(void)
{
	unsigned long	pit_rate;
	unsigned	bits;
@@ -250,12 +263,6 @@ static void __init at91sam926x_pit_init(void)
	clockevents_register_device(&pit_clkevt);
}

static void at91sam926x_pit_suspend(void)
{
	/* Disable timer */
	pit_write(AT91_PIT_MR, 0);
}

void __init at91sam926x_ioremap_pit(u32 addr)
{
#if defined(CONFIG_OF)
@@ -272,9 +279,3 @@ void __init at91sam926x_ioremap_pit(u32 addr)
	if (!pit_base_addr)
		panic("Impossible to ioremap PIT\n");
}

struct sys_timer at91sam926x_timer = {
	.init		= at91sam926x_pit_init,
	.suspend	= at91sam926x_pit_suspend,
	.resume		= at91sam926x_pit_reset,
};
Loading