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>
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;