ia64/xen-unstable
changeset 18805:85fda344dba7
x86, time: Clean up platform timer initialisation.
Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Nov 18 15:39:31 2008 +0000 (2008-11-18) |
parents | ae891977a4d3 |
children | ed8524f4a044 |
files | xen/arch/x86/time.c |
line diff
1.1 --- a/xen/arch/x86/time.c Tue Nov 18 11:16:36 2008 +0000 1.2 +++ b/xen/arch/x86/time.c Tue Nov 18 15:39:31 2008 +0000 1.3 @@ -59,6 +59,7 @@ struct platform_timesource { 1.4 char *name; 1.5 u64 frequency; 1.6 u64 (*read_counter)(void); 1.7 + int (*init)(struct platform_timesource *); 1.8 int counter_bits; 1.9 }; 1.10 1.11 @@ -360,15 +361,21 @@ static u64 read_pit_count(void) 1.12 return count32; 1.13 } 1.14 1.15 -static void init_pit(struct platform_timesource *pts) 1.16 +static int init_pit(struct platform_timesource *pts) 1.17 { 1.18 - pts->name = "PIT"; 1.19 - pts->frequency = CLOCK_TICK_RATE; 1.20 - pts->read_counter = read_pit_count; 1.21 - pts->counter_bits = 32; 1.22 using_pit = 1; 1.23 + return 1; 1.24 } 1.25 1.26 +static struct platform_timesource plt_pit = 1.27 +{ 1.28 + .name = "PIT", 1.29 + .frequency = CLOCK_TICK_RATE, 1.30 + .read_counter = read_pit_count, 1.31 + .counter_bits = 32, 1.32 + .init = init_pit 1.33 +}; 1.34 + 1.35 /************************************************************ 1.36 * PLATFORM TIMER 2: HIGH PRECISION EVENT TIMER (HPET) 1.37 */ 1.38 @@ -385,14 +392,18 @@ static int init_hpet(struct platform_tim 1.39 if ( hpet_rate == 0 ) 1.40 return 0; 1.41 1.42 - pts->name = "HPET"; 1.43 pts->frequency = hpet_rate; 1.44 - pts->read_counter = read_hpet_count; 1.45 - pts->counter_bits = 32; 1.46 - 1.47 return 1; 1.48 } 1.49 1.50 +static struct platform_timesource plt_hpet = 1.51 +{ 1.52 + .name = "HPET", 1.53 + .read_counter = read_hpet_count, 1.54 + .counter_bits = 32, 1.55 + .init = init_hpet 1.56 +}; 1.57 + 1.58 /************************************************************ 1.59 * PLATFORM TIMER 3: IBM 'CYCLONE' TIMER 1.60 */ 1.61 @@ -440,20 +451,23 @@ static int init_cyclone(struct platform_ 1.62 printk(KERN_ERR "Cyclone: Could not find valid CBAR value.\n"); 1.63 return 0; 1.64 } 1.65 - 1.66 + 1.67 /* Enable timer and map the counter register. */ 1.68 *(map_cyclone_reg(base + CYCLONE_PMCC_OFFSET)) = 1; 1.69 *(map_cyclone_reg(base + CYCLONE_MPCS_OFFSET)) = 1; 1.70 cyclone_timer = map_cyclone_reg(base + CYCLONE_MPMC_OFFSET); 1.71 - 1.72 - pts->name = "IBM Cyclone"; 1.73 - pts->frequency = CYCLONE_TIMER_FREQ; 1.74 - pts->read_counter = read_cyclone_count; 1.75 - pts->counter_bits = 32; 1.76 - 1.77 return 1; 1.78 } 1.79 1.80 +static struct platform_timesource plt_cyclone = 1.81 +{ 1.82 + .name = "IBM Cyclone", 1.83 + .frequency = CYCLONE_TIMER_FREQ, 1.84 + .read_counter = read_cyclone_count, 1.85 + .counter_bits = 32, 1.86 + .init = init_cyclone 1.87 +}; 1.88 + 1.89 /************************************************************ 1.90 * PLATFORM TIMER 4: ACPI PM TIMER 1.91 */ 1.92 @@ -473,14 +487,18 @@ static int init_pmtimer(struct platform_ 1.93 if ( pmtmr_ioport == 0 ) 1.94 return 0; 1.95 1.96 - pts->name = "ACPI PM Timer"; 1.97 - pts->frequency = ACPI_PM_FREQUENCY; 1.98 - pts->read_counter = read_pmtimer_count; 1.99 - pts->counter_bits = 24; 1.100 - 1.101 return 1; 1.102 } 1.103 1.104 +static struct platform_timesource plt_pmtimer = 1.105 +{ 1.106 + .name = "ACPI PM Timer", 1.107 + .frequency = ACPI_PM_FREQUENCY, 1.108 + .read_counter = read_pmtimer_count, 1.109 + .counter_bits = 24, 1.110 + .init = init_pmtimer 1.111 +}; 1.112 + 1.113 /************************************************************ 1.114 * GENERIC PLATFORM TIMER INFRASTRUCTURE 1.115 */ 1.116 @@ -555,19 +573,24 @@ static void resume_platform_timer(void) 1.117 1.118 static void init_platform_timer(void) 1.119 { 1.120 - struct platform_timesource *pts = &plt_src; 1.121 - int rc = -1; 1.122 + static struct platform_timesource * const plt_timers[] = { 1.123 + &plt_cyclone, &plt_hpet, &plt_pmtimer, &plt_pit 1.124 + }; 1.125 + 1.126 + struct platform_timesource *pts; 1.127 + int i, rc = -1; 1.128 1.129 if ( opt_clocksource[0] != '\0' ) 1.130 { 1.131 - if ( !strcmp(opt_clocksource, "pit") ) 1.132 - rc = (init_pit(pts), 1); 1.133 - else if ( !strcmp(opt_clocksource, "hpet") ) 1.134 - rc = init_hpet(pts); 1.135 - else if ( !strcmp(opt_clocksource, "cyclone") ) 1.136 - rc = init_cyclone(pts); 1.137 - else if ( !strcmp(opt_clocksource, "acpi") ) 1.138 - rc = init_pmtimer(pts); 1.139 + for ( i = 0; i < ARRAY_SIZE(plt_timers); i++ ) 1.140 + { 1.141 + pts = plt_timers[i]; 1.142 + if ( !strcmp(opt_clocksource, pts->name) ) 1.143 + { 1.144 + rc = pts->init(pts); 1.145 + break; 1.146 + } 1.147 + } 1.148 1.149 if ( rc <= 0 ) 1.150 printk("WARNING: %s clocksource '%s'.\n", 1.151 @@ -575,11 +598,17 @@ static void init_platform_timer(void) 1.152 opt_clocksource); 1.153 } 1.154 1.155 - if ( (rc <= 0) && 1.156 - !init_cyclone(pts) && 1.157 - !init_hpet(pts) && 1.158 - !init_pmtimer(pts) ) 1.159 - init_pit(pts); 1.160 + if ( rc <= 0 ) 1.161 + { 1.162 + for ( i = 0; i < ARRAY_SIZE(plt_timers); i++ ) 1.163 + { 1.164 + pts = plt_timers[i]; 1.165 + if ( (rc = pts->init(pts)) > 0 ) 1.166 + break; 1.167 + } 1.168 + } 1.169 + 1.170 + BUG_ON(rc <= 0); 1.171 1.172 plt_mask = (u64)~0ull >> (64 - pts->counter_bits); 1.173 1.174 @@ -588,6 +617,7 @@ static void init_platform_timer(void) 1.175 plt_overflow_period = scale_delta( 1.176 1ull << (pts->counter_bits-1), &plt_scale); 1.177 init_timer(&plt_overflow_timer, plt_overflow, NULL, 0); 1.178 + plt_src = *pts; 1.179 plt_overflow(NULL); 1.180 1.181 platform_timer_stamp = plt_stamp64;