Merge branch 'pmtimer-overflow' into release
authorLen Brown <len.brown@intel.com>
Sun, 5 Apr 2009 05:39:07 +0000 (01:39 -0400)
committerLen Brown <len.brown@intel.com>
Sun, 5 Apr 2009 05:39:07 +0000 (01:39 -0400)
1  2 
drivers/acpi/processor_idle.c

@@@ -64,7 -64,6 +64,6 @@@
  #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
  ACPI_MODULE_NAME("processor_idle");
  #define ACPI_PROCESSOR_FILE_POWER     "power"
- #define US_TO_PM_TIMER_TICKS(t)               ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
  #define PM_TIMER_TICK_NS              (1000000000ULL/PM_TIMER_FREQUENCY)
  #define C2_OVERHEAD                   1       /* 1us */
  #define C3_OVERHEAD                   1       /* 1us */
@@@ -78,6 -77,10 +77,10 @@@ module_param(nocst, uint, 0000)
  static unsigned int latency_factor __read_mostly = 2;
  module_param(latency_factor, uint, 0644);
  
+ static s64 us_to_pm_timer_ticks(s64 t)
+ {
+       return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+ }
  /*
   * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
   * For now disable this. Probably a bug somewhere else.
@@@ -101,6 -104,57 +104,6 @@@ static int set_max_cstate(const struct 
  /* Actually this shouldn't be __cpuinitdata, would be better to fix the
     callers to only run once -AK */
  static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
 -      { set_max_cstate, "IBM ThinkPad R40e", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
 -      { set_max_cstate, "Medion 41700", {
 -        DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 -        DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
        { set_max_cstate, "Clevo 5600D", {
          DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
          DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
        {},
  };
  
- static inline u32 ticks_elapsed(u32 t1, u32 t2)
- {
-       if (t2 >= t1)
-               return (t2 - t1);
-       else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-               return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-       else
-               return ((0xFFFFFFFF - t1) + t2);
- }
- static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
- {
-       if (t2 >= t1)
-               return PM_TIMER_TICKS_TO_US(t2 - t1);
-       else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-               return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-       else
-               return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
- }
  
  /*
   * Callers should disable interrupts before the call and enable
@@@ -579,7 -614,7 +563,7 @@@ static void acpi_processor_power_verify
         * In either case, the proper way to
         * handle BM_RLD is to set it and leave it set.
         */
 -      acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 +      acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
  
        return;
  }
@@@ -749,9 -784,9 +733,9 @@@ static int acpi_idle_bm_check(void
  {
        u32 bm_status = 0;
  
 -      acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
 +      acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
        if (bm_status)
 -              acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 +              acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
        /*
         * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
         * the true state of bus mastering activity; forcing us to
@@@ -802,7 -837,8 +786,8 @@@ static inline void acpi_idle_do_entry(s
  static int acpi_idle_enter_c1(struct cpuidle_device *dev,
                              struct cpuidle_state *state)
  {
-       u32 t1, t2;
+       ktime_t  kt1, kt2;
+       s64 idle_time;
        struct acpi_processor *pr;
        struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
  
                return 0;
        }
  
-       t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       kt1 = ktime_get_real();
        acpi_idle_do_entry(cx);
-       t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       kt2 = ktime_get_real();
+       idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
  
        local_irq_enable();
        cx->usage++;
  
-       return ticks_elapsed_in_us(t1, t2);
+       return idle_time;
  }
  
  /**
@@@ -840,8 -877,9 +826,9 @@@ static int acpi_idle_enter_simple(struc
  {
        struct acpi_processor *pr;
        struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-       u32 t1, t2;
-       int sleep_ticks = 0;
+       ktime_t  kt1, kt2;
+       s64 idle_time;
+       s64 sleep_ticks = 0;
  
        pr = __get_cpu_var(processors);
  
        if (cx->type == ACPI_STATE_C3)
                ACPI_FLUSH_CPU_CACHE();
  
-       t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       kt1 = ktime_get_real();
        /* Tell the scheduler that we are going deep-idle: */
        sched_clock_idle_sleep_event();
        acpi_idle_do_entry(cx);
-       t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       kt2 = ktime_get_real();
+       idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
  
  #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
        /* TSC could halt in idle, so notify users */
        if (tsc_halts_in_c(cx->type))
                mark_tsc_unstable("TSC halts in idle");;
  #endif
-       sleep_ticks = ticks_elapsed(t1, t2);
+       sleep_ticks = us_to_pm_timer_ticks(idle_time);
  
        /* Tell the scheduler how much we idled: */
        sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
  
        acpi_state_timer_broadcast(pr, cx, 0);
        cx->time += sleep_ticks;
-       return ticks_elapsed_in_us(t1, t2);
+       return idle_time;
  }
  
  static int c3_cpu_count;
@@@ -915,8 -954,10 +903,10 @@@ static int acpi_idle_enter_bm(struct cp
  {
        struct acpi_processor *pr;
        struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-       u32 t1, t2;
-       int sleep_ticks = 0;
+       ktime_t  kt1, kt2;
+       s64 idle_time;
+       s64 sleep_ticks = 0;
  
        pr = __get_cpu_var(processors);
  
                c3_cpu_count++;
                /* Disable bus master arbitration when all CPUs are in C3 */
                if (c3_cpu_count == num_online_cpus())
 -                      acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
 +                      acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
                spin_unlock(&c3_lock);
        } else if (!pr->flags.bm_check) {
                ACPI_FLUSH_CPU_CACHE();
        }
  
-       t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       kt1 = ktime_get_real();
        acpi_idle_do_entry(cx);
-       t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+       kt2 = ktime_get_real();
+       idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
  
        /* Re-enable bus master arbitration */
        if (pr->flags.bm_check && pr->flags.bm_control) {
                spin_lock(&c3_lock);
 -              acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
 +              acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
                c3_cpu_count--;
                spin_unlock(&c3_lock);
        }
        if (tsc_halts_in_c(ACPI_STATE_C3))
                mark_tsc_unstable("TSC halts in idle");
  #endif
-       sleep_ticks = ticks_elapsed(t1, t2);
+       sleep_ticks = us_to_pm_timer_ticks(idle_time);
        /* Tell the scheduler how much we idled: */
        sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
  
  
        acpi_state_timer_broadcast(pr, cx, 0);
        cx->time += sleep_ticks;
-       return ticks_elapsed_in_us(t1, t2);
+       return idle_time;
  }
  
  struct cpuidle_driver acpi_idle_driver = {