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