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

Commit 62f08283 authored by Tkhai Kirill's avatar Tkhai Kirill Committed by David S. Miller
Browse files

sparc32: generic clockevent support



The kernel uses l14 timers as clockevents. l10 timer is used
as clocksource if platform master_l10_counter isn't constantly
zero. The clocksource is continuous, so it's possible to use
high resolution timers. l10 timer is also used as clockevent
on UP configurations.

This realization is for sun4m, sun4d, sun4c, microsparc-IIep
and LEON platforms. The appropriate LEON changes was made by
Konrad Eisele.

In case of sun4m's oneshot mode, profile irq is zeroed in
smp4m_percpu_timer_interrupt(). It is maybe
needless (double, triple etc overflow does nothing).

sun4d is able to have oneshot mode too, but I haven't
any way to test it. So code of its percpu timer handler
is made as much equal to the current code as possible.

The patch is tested on sun4m box in SMP mode by me,
and tested by Konrad on leon in up mode (leon smp
is broken atm - due to other reasons).

Signed-off-by: default avatarTkhai Kirill <tkhai@yandex.ru>
Tested-by: Konrad Eisele <konrad@gaisler.com> [leon up]
[sam: revised patch to provide generic support for leon]
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 472bc4f2
Loading
Loading
Loading
Loading
+1 −6
Original line number Original line Diff line number Diff line
@@ -73,17 +73,12 @@ config BITS
	default 32 if SPARC32
	default 32 if SPARC32
	default 64 if SPARC64
	default 64 if SPARC64


config ARCH_USES_GETTIMEOFFSET
	bool
	default y if SPARC32

config GENERIC_CMOS_UPDATE
config GENERIC_CMOS_UPDATE
	bool
	bool
	default y
	default y


config GENERIC_CLOCKEVENTS
config GENERIC_CLOCKEVENTS
	bool
	def_bool y
	default y if SPARC64


config IOMMU_HELPER
config IOMMU_HELPER
	bool
	bool
+0 −1
Original line number Original line Diff line number Diff line
@@ -14,7 +14,6 @@
typedef struct {
typedef struct {
	unsigned long udelay_val;
	unsigned long udelay_val;
	unsigned long clock_tick;
	unsigned long clock_tick;
	unsigned int multiplier;
	unsigned int counter;
	unsigned int counter;
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	unsigned int irq_resched_count;
	unsigned int irq_resched_count;
+1 −1
Original line number Original line Diff line number Diff line
@@ -323,7 +323,7 @@ extern void leon_update_virq_handling(unsigned int virq,
			      const char *name, int do_ack);
			      const char *name, int do_ack);
extern void leon_clear_clock_irq(void);
extern void leon_clear_clock_irq(void);
extern void leon_load_profile_irq(int cpu, unsigned int limit);
extern void leon_load_profile_irq(int cpu, unsigned int limit);
extern void leon_init_timers(irq_handler_t counter_fn);
extern void leon_init_timers(void);
extern void leon_clear_clock_irq(void);
extern void leon_clear_clock_irq(void);
extern void leon_load_profile_irq(int cpu, unsigned int limit);
extern void leon_load_profile_irq(int cpu, unsigned int limit);
extern void leon_trans_init(struct device_node *dp);
extern void leon_trans_init(struct device_node *dp);
+29 −0
Original line number Original line Diff line number Diff line
@@ -8,11 +8,40 @@
#ifndef _SPARC_TIMER_H
#ifndef _SPARC_TIMER_H
#define _SPARC_TIMER_H
#define _SPARC_TIMER_H


#include <linux/clocksource.h>
#include <linux/irqreturn.h>

#include <asm-generic/percpu.h>

#include <asm/cpu_type.h>  /* For SUN4M_NCPUS */
#include <asm/cpu_type.h>  /* For SUN4M_NCPUS */
#include <asm/btfixup.h>
#include <asm/btfixup.h>


#define SBUS_CLOCK_RATE   2000000 /* 2MHz */
#define TIMER_VALUE_SHIFT 9
#define TIMER_VALUE_MASK  0x3fffff
#define TIMER_LIMIT_BIT   (1 << 31)  /* Bit 31 in Counter-Timer register */

/* The counter timer register has the value offset by 9 bits.
 * From sun4m manual:
 * When a counter reaches the value in the corresponding limit register,
 * the Limit bit is set and the counter is set to 500 nS (i.e. 0x00000200).
 *
 * To compensate for this add one to the value.
 */
static inline unsigned int timer_value(unsigned int value)
{
	return (value + 1) << TIMER_VALUE_SHIFT;
}

extern __volatile__ unsigned int *master_l10_counter;
extern __volatile__ unsigned int *master_l10_counter;


extern irqreturn_t notrace timer_interrupt(int dummy, void *dev_id);

#ifdef CONFIG_SMP
DECLARE_PER_CPU(struct clock_event_device, sparc32_clockevent);
extern void register_percpu_ce(int cpu);
#endif

/* FIXME: Make do_[gs]ettimeofday btfixup calls */
/* FIXME: Make do_[gs]ettimeofday btfixup calls */
struct timespec;
struct timespec;
BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
+0 −1
Original line number Original line Diff line number Diff line
@@ -12,5 +12,4 @@
typedef unsigned long cycles_t;
typedef unsigned long cycles_t;
#define get_cycles()	(0)
#define get_cycles()	(0)


extern u32 (*do_arch_gettimeoffset)(void);
#endif
#endif
Loading