aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/hpet.c43
-rw-r--r--arch/x86/kernel/quirks.c58
-rw-r--r--arch/x86/kernel/tsc_32.c6
-rw-r--r--arch/x86/kernel/tsc_64.c2
4 files changed, 77 insertions, 32 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 9b5cfcdfc426..ea230ec69057 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -17,7 +17,7 @@
17 17
18/* FSEC = 10^-15 18/* FSEC = 10^-15
19 NSEC = 10^-9 */ 19 NSEC = 10^-9 */
20#define FSEC_PER_NSEC 1000000 20#define FSEC_PER_NSEC 1000000L
21 21
22/* 22/*
23 * HPET address is set in acpi/boot.c, when an ACPI entry exists 23 * HPET address is set in acpi/boot.c, when an ACPI entry exists
@@ -206,20 +206,19 @@ static void hpet_enable_legacy_int(void)
206 206
207static void hpet_legacy_clockevent_register(void) 207static void hpet_legacy_clockevent_register(void)
208{ 208{
209 uint64_t hpet_freq;
210
211 /* Start HPET legacy interrupts */ 209 /* Start HPET legacy interrupts */
212 hpet_enable_legacy_int(); 210 hpet_enable_legacy_int();
213 211
214 /* 212 /*
215 * The period is a femto seconds value. We need to calculate the 213 * The mult factor is defined as (include/linux/clockchips.h)
216 * scaled math multiplication factor for nanosecond to hpet tick 214 * mult/2^shift = cyc/ns (in contrast to ns/cyc in clocksource.h)
217 * conversion. 215 * hpet_period is in units of femtoseconds (per cycle), so
216 * mult/2^shift = cyc/ns = 10^6/hpet_period
217 * mult = (10^6 * 2^shift)/hpet_period
218 * mult = (FSEC_PER_NSEC << hpet_clockevent.shift)/hpet_period
218 */ 219 */
219 hpet_freq = 1000000000000000ULL; 220 hpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC,
220 do_div(hpet_freq, hpet_period); 221 hpet_period, hpet_clockevent.shift);
221 hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
222 NSEC_PER_SEC, hpet_clockevent.shift);
223 /* Calculate the min / max delta */ 222 /* Calculate the min / max delta */
224 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, 223 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
225 &hpet_clockevent); 224 &hpet_clockevent);
@@ -324,7 +323,7 @@ static struct clocksource clocksource_hpet = {
324 323
325static int hpet_clocksource_register(void) 324static int hpet_clocksource_register(void)
326{ 325{
327 u64 tmp, start, now; 326 u64 start, now;
328 cycle_t t1; 327 cycle_t t1;
329 328
330 /* Start the counter */ 329 /* Start the counter */
@@ -351,21 +350,15 @@ static int hpet_clocksource_register(void)
351 return -ENODEV; 350 return -ENODEV;
352 } 351 }
353 352
354 /* Initialize and register HPET clocksource 353 /*
355 * 354 * The definition of mult is (include/linux/clocksource.h)
356 * hpet period is in femto seconds per cycle 355 * mult/2^shift = ns/cyc and hpet_period is in units of fsec/cyc
357 * so we need to convert this to ns/cyc units 356 * so we first need to convert hpet_period to ns/cyc units:
358 * approximated by mult/2^shift 357 * mult/2^shift = ns/cyc = hpet_period/10^6
359 * 358 * mult = (hpet_period * 2^shift)/10^6
360 * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift 359 * mult = (hpet_period << shift)/FSEC_PER_NSEC
361 * fsec/cyc * 1ns/1000000fsec * 2^shift = mult
362 * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
363 * (fsec/cyc << shift)/1000000 = mult
364 * (hpet_period << shift)/FSEC_PER_NSEC = mult
365 */ 360 */
366 tmp = (u64)hpet_period << HPET_SHIFT; 361 clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);
367 do_div(tmp, FSEC_PER_NSEC);
368 clocksource_hpet.mult = (u32)tmp;
369 362
370 clocksource_register(&clocksource_hpet); 363 clocksource_register(&clocksource_hpet);
371 364
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index d89a648fe710..79bdcd11c66e 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -65,6 +65,7 @@ static enum {
65 ICH_FORCE_HPET_RESUME, 65 ICH_FORCE_HPET_RESUME,
66 VT8237_FORCE_HPET_RESUME, 66 VT8237_FORCE_HPET_RESUME,
67 NVIDIA_FORCE_HPET_RESUME, 67 NVIDIA_FORCE_HPET_RESUME,
68 ATI_FORCE_HPET_RESUME,
68} force_hpet_resume_type; 69} force_hpet_resume_type;
69 70
70static void __iomem *rcba_base; 71static void __iomem *rcba_base;
@@ -158,6 +159,8 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
158 159
159DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, 160DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
160 ich_force_enable_hpet); 161 ich_force_enable_hpet);
162DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0,
163 ich_force_enable_hpet);
161DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, 164DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
162 ich_force_enable_hpet); 165 ich_force_enable_hpet);
163DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, 166DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
@@ -174,6 +177,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7,
174 177
175static struct pci_dev *cached_dev; 178static struct pci_dev *cached_dev;
176 179
180static void hpet_print_force_info(void)
181{
182 printk(KERN_INFO "HPET not enabled in BIOS. "
183 "You might try hpet=force boot option\n");
184}
185
177static void old_ich_force_hpet_resume(void) 186static void old_ich_force_hpet_resume(void)
178{ 187{
179 u32 val; 188 u32 val;
@@ -253,6 +262,8 @@ static void old_ich_force_enable_hpet_user(struct pci_dev *dev)
253{ 262{
254 if (hpet_force_user) 263 if (hpet_force_user)
255 old_ich_force_enable_hpet(dev); 264 old_ich_force_enable_hpet(dev);
265 else
266 hpet_print_force_info();
256} 267}
257 268
258DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, 269DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
@@ -290,8 +301,13 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev)
290{ 301{
291 u32 uninitialized_var(val); 302 u32 uninitialized_var(val);
292 303
293 if (!hpet_force_user || hpet_address || force_hpet_address) 304 if (hpet_address || force_hpet_address)
305 return;
306
307 if (!hpet_force_user) {
308 hpet_print_force_info();
294 return; 309 return;
310 }
295 311
296 pci_read_config_dword(dev, 0x68, &val); 312 pci_read_config_dword(dev, 0x68, &val);
297 /* 313 /*
@@ -330,6 +346,36 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
330DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, 346DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
331 vt8237_force_enable_hpet); 347 vt8237_force_enable_hpet);
332 348
349static void ati_force_hpet_resume(void)
350{
351 pci_write_config_dword(cached_dev, 0x14, 0xfed00000);
352 printk(KERN_DEBUG "Force enabled HPET at resume\n");
353}
354
355static void ati_force_enable_hpet(struct pci_dev *dev)
356{
357 u32 uninitialized_var(val);
358
359 if (hpet_address || force_hpet_address)
360 return;
361
362 if (!hpet_force_user) {
363 hpet_print_force_info();
364 return;
365 }
366
367 pci_write_config_dword(dev, 0x14, 0xfed00000);
368 pci_read_config_dword(dev, 0x14, &val);
369 force_hpet_address = val;
370 force_hpet_resume_type = ATI_FORCE_HPET_RESUME;
371 dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at 0x%lx\n",
372 force_hpet_address);
373 cached_dev = dev;
374 return;
375}
376DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,
377 ati_force_enable_hpet);
378
333/* 379/*
334 * Undocumented chipset feature taken from LinuxBIOS. 380 * Undocumented chipset feature taken from LinuxBIOS.
335 */ 381 */
@@ -343,8 +389,13 @@ static void nvidia_force_enable_hpet(struct pci_dev *dev)
343{ 389{
344 u32 uninitialized_var(val); 390 u32 uninitialized_var(val);
345 391
346 if (!hpet_force_user || hpet_address || force_hpet_address) 392 if (hpet_address || force_hpet_address)
393 return;
394
395 if (!hpet_force_user) {
396 hpet_print_force_info();
347 return; 397 return;
398 }
348 399
349 pci_write_config_dword(dev, 0x44, 0xfed00001); 400 pci_write_config_dword(dev, 0x44, 0xfed00001);
350 pci_read_config_dword(dev, 0x44, &val); 401 pci_read_config_dword(dev, 0x44, &val);
@@ -397,6 +448,9 @@ void force_hpet_resume(void)
397 case NVIDIA_FORCE_HPET_RESUME: 448 case NVIDIA_FORCE_HPET_RESUME:
398 nvidia_force_hpet_resume(); 449 nvidia_force_hpet_resume();
399 return; 450 return;
451 case ATI_FORCE_HPET_RESUME:
452 ati_force_hpet_resume();
453 return;
400 default: 454 default:
401 break; 455 break;
402 } 456 }
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index 65b70637ad97..774a5a83c296 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -286,7 +286,6 @@ core_initcall(cpufreq_tsc);
286 286
287/* clock source code */ 287/* clock source code */
288 288
289static unsigned long current_tsc_khz;
290static struct clocksource clocksource_tsc; 289static struct clocksource clocksource_tsc;
291 290
292/* 291/*
@@ -439,9 +438,8 @@ void __init tsc_init(void)
439 438
440 unsynchronized_tsc(); 439 unsynchronized_tsc();
441 check_geode_tsc_reliable(); 440 check_geode_tsc_reliable();
442 current_tsc_khz = tsc_khz; 441 clocksource_tsc.mult = clocksource_khz2mult(tsc_khz,
443 clocksource_tsc.mult = clocksource_khz2mult(current_tsc_khz, 442 clocksource_tsc.shift);
444 clocksource_tsc.shift);
445 /* lower the rating if we already know its unstable: */ 443 /* lower the rating if we already know its unstable: */
446 if (check_tsc_unstable()) { 444 if (check_tsc_unstable()) {
447 clocksource_tsc.rating = 0; 445 clocksource_tsc.rating = 0;
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 1784b8077a12..9898fb01edfd 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -242,7 +242,7 @@ void __init tsc_calibrate(void)
242 if (hpet) { 242 if (hpet) {
243 printk(KERN_INFO "TSC calibrated against HPET\n"); 243 printk(KERN_INFO "TSC calibrated against HPET\n");
244 if (hpet2 < hpet1) 244 if (hpet2 < hpet1)
245 hpet2 += 0x100000000; 245 hpet2 += 0x100000000UL;
246 hpet2 -= hpet1; 246 hpet2 -= hpet1;
247 tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000; 247 tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000;
248 } else { 248 } else {