Commit 3ba05012 authored by Andries E. Brouwer's avatar Andries E. Brouwer Committed by Linus Torvalds

[PATCH] __init and i386 timers

The i386 timers use a struct timer_opts that has a field init
pointing at a __init function. The rest of the struct is not __init.

Nothing is wrong, but if we want to avoid having references to init stuff
in non-init sections, some reshuffling is needed.

The below replaces

struct timer_opts {
	int (*init)(char *override);
	... more ...
};

by the two structs

struct timer_opts {
	... more ...
};

struct init_time_opts {
	int (*init)(char *override);
	struct timer_opts *opts;
};

where the second is __initdata.
parent 1018d211
......@@ -12,18 +12,18 @@
*/
#endif
/* list of timers, ordered by preference, NULL terminated */
static struct timer_opts* timers[] = {
static struct init_timer_opts* __initdata timers[] = {
#ifdef CONFIG_X86_CYCLONE_TIMER
&timer_cyclone,
&timer_cyclone_init,
#endif
#ifdef CONFIG_HPET_TIMER
&timer_hpet,
&timer_hpet_init,
#endif
#ifdef CONFIG_X86_PM_TIMER
&timer_pmtmr,
&timer_pmtmr_init,
#endif
&timer_tsc,
&timer_pit,
&timer_tsc_init,
&timer_pit_init,
NULL,
};
......@@ -49,7 +49,7 @@ void clock_fallback(void)
/* iterates through the list of timers, returning the first
* one that initializes successfully.
*/
struct timer_opts* select_timer(void)
struct timer_opts* __init select_timer(void)
{
int i = 0;
......@@ -57,7 +57,7 @@ struct timer_opts* select_timer(void)
while (timers[i]) {
if (timers[i]->init)
if (timers[i]->init(clock_override) == 0)
return timers[i];
return timers[i]->opts;
++i;
}
......
......@@ -245,11 +245,15 @@ static void delay_cyclone(unsigned long loops)
/************************************************************/
/* cyclone timer_opts struct */
struct timer_opts timer_cyclone = {
static struct timer_opts timer_cyclone = {
.name = "cyclone",
.init = init_cyclone,
.mark_offset = mark_offset_cyclone,
.get_offset = get_offset_cyclone,
.monotonic_clock = monotonic_clock_cyclone,
.delay = delay_cyclone,
};
struct init_timer_opts __initdata timer_cyclone_init = {
.init = init_cyclone,
.opts = &timer_cyclone,
};
......@@ -177,11 +177,15 @@ static int __init init_hpet(char* override)
/************************************************************/
/* tsc timer_opts struct */
struct timer_opts timer_hpet = {
static struct timer_opts timer_hpet = {
.name = "hpet",
.init = init_hpet,
.mark_offset = mark_offset_hpet,
.get_offset = get_offset_hpet,
.monotonic_clock = monotonic_clock_hpet,
.delay = delay_hpet,
};
struct init_timer_opts __initdata timer_hpet_init = {
.init = init_hpet,
.opts = &timer_hpet,
};
#include <linux/init.h>
#include <asm/timer.h>
static int __init init_none(char* override)
{
return 0;
}
static void mark_offset_none(void)
{
/* nothing needed */
......@@ -37,7 +32,6 @@ static void delay_none(unsigned long loops)
/* none timer_opts struct */
struct timer_opts timer_none = {
.name = "none",
.init = init_none,
.mark_offset = mark_offset_none,
.get_offset = get_offset_none,
.monotonic_clock = monotonic_clock_none,
......
......@@ -152,14 +152,18 @@ static unsigned long get_offset_pit(void)
/* tsc timer_opts struct */
struct timer_opts timer_pit = {
.name = "pit",
.init = init_pit,
.mark_offset = mark_offset_pit,
.get_offset = get_offset_pit,
.name = "pit",
.mark_offset = mark_offset_pit,
.get_offset = get_offset_pit,
.monotonic_clock = monotonic_clock_pit,
.delay = delay_pit,
};
struct init_timer_opts __initdata timer_pit_init = {
.init = init_pit,
.opts = &timer_pit,
};
void setup_pit_timer(void)
{
extern spinlock_t i8253_lock;
......
......@@ -240,15 +240,18 @@ static unsigned long get_offset_pmtmr(void)
/* acpi timer_opts struct */
struct timer_opts timer_pmtmr = {
static struct timer_opts timer_pmtmr = {
.name = "pmtmr",
.init = init_pmtmr,
.mark_offset = mark_offset_pmtmr,
.get_offset = get_offset_pmtmr,
.monotonic_clock = monotonic_clock_pmtmr,
.delay = delay_pmtmr,
};
struct init_timer_opts __initdata timer_pmtmr_init = {
.init = init_pmtmr,
.opts = &timer_pmtmr,
};
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
......
......@@ -28,7 +28,7 @@
#ifdef CONFIG_HPET_TIMER
static unsigned long hpet_usec_quotient;
static unsigned long hpet_last;
struct timer_opts timer_tsc;
static struct timer_opts timer_tsc;
#endif
static inline void cpufreq_delayed_get(void);
......@@ -546,11 +546,15 @@ __setup("notsc", tsc_setup);
/************************************************************/
/* tsc timer_opts struct */
struct timer_opts timer_tsc = {
.name = "tsc",
.init = init_tsc,
.mark_offset = mark_offset_tsc,
.get_offset = get_offset_tsc,
.monotonic_clock = monotonic_clock_tsc,
static struct timer_opts timer_tsc = {
.name = "tsc",
.mark_offset = mark_offset_tsc,
.get_offset = get_offset_tsc,
.monotonic_clock = monotonic_clock_tsc,
.delay = delay_tsc,
};
struct init_timer_opts __initdata timer_tsc_init = {
.init = init_tsc,
.opts = &timer_tsc,
};
#ifndef _ASMi386_TIMER_H
#define _ASMi386_TIMER_H
#include <linux/init.h>
/**
* struct timer_ops - used to define a timer source
......@@ -15,18 +16,22 @@
* timer.
* @delay: delays this many clock cycles.
*/
struct timer_opts{
struct timer_opts {
char* name;
int (*init)(char *override);
void (*mark_offset)(void);
unsigned long (*get_offset)(void);
unsigned long long (*monotonic_clock)(void);
void (*delay)(unsigned long);
};
struct init_timer_opts {
int (*init)(char *override);
struct timer_opts *opts;
};
#define TICK_SIZE (tick_nsec / 1000)
extern struct timer_opts* select_timer(void);
extern struct timer_opts* __init select_timer(void);
extern void clock_fallback(void);
void setup_pit_timer(void);
......@@ -40,19 +45,20 @@ extern int timer_ack;
/* list of externed timers */
extern struct timer_opts timer_none;
extern struct timer_opts timer_pit;
extern struct timer_opts timer_tsc;
extern struct init_timer_opts timer_pit_init;
extern struct init_timer_opts timer_tsc_init;
#ifdef CONFIG_X86_CYCLONE_TIMER
extern struct timer_opts timer_cyclone;
extern struct init_timer_opts timer_cyclone_init;
#endif
extern unsigned long calibrate_tsc(void);
extern void init_cpu_khz(void);
#ifdef CONFIG_HPET_TIMER
extern struct timer_opts timer_hpet;
extern struct init_timer_opts timer_hpet_init;
extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr);
#endif
#ifdef CONFIG_X86_PM_TIMER
extern struct timer_opts timer_pmtmr;
extern struct init_timer_opts timer_pmtmr_init;
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment