aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-18 19:16:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-18 19:16:18 -0500
commit5c6b4e84cbc59996bb14f88d997870751d675f3f (patch)
treea86092c3ead87cd1fffba7fb808e02bcaeb9f3a2 /arch
parentddddefa99db4ae54a63dcd737d224bc3cc0f2d8a (diff)
parent0d2f096b8785b67c38afcf6e1fbb9674af2e05ca (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: random: Fix handing of arch_get_random_long in get_random_bytes() x86: Call stop_machine_text_poke() on all CPUs x86, ioapic: Only print ioapic debug information for IRQs belonging to an ioapic chip x86/mrst: Avoid reporting wrong nmi status x86/mrst: Add support for Penwell clock calibration x86/apic: Allow use of lapic timer early calibration result x86/apic: Do not clear nr_irqs_gsi if no legacy irqs x86/platform: Add a wallclock_init func to x86_platforms ops x86/mce: Make mce_chrdev_ops 'static const'
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/apic.h1
-rw-r--r--arch/x86/include/asm/mach_traps.h2
-rw-r--r--arch/x86/include/asm/mce.h5
-rw-r--r--arch/x86/include/asm/mrst.h7
-rw-r--r--arch/x86/include/asm/x86_init.h3
-rw-r--r--arch/x86/kernel/alternative.c2
-rw-r--r--arch/x86/kernel/apic/apic.c33
-rw-r--r--arch/x86/kernel/apic/io_apic.c9
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-inject.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c25
-rw-r--r--arch/x86/kernel/nmi.c3
-rw-r--r--arch/x86/kernel/setup.c2
-rw-r--r--arch/x86/kernel/x86_init.c4
-rw-r--r--arch/x86/platform/mrst/mrst.c46
14 files changed, 121 insertions, 23 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 9b7273cb2193..1a6c09af048f 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -49,6 +49,7 @@ extern unsigned int apic_verbosity;
49extern int local_apic_timer_c2_ok; 49extern int local_apic_timer_c2_ok;
50 50
51extern int disable_apic; 51extern int disable_apic;
52extern unsigned int lapic_timer_frequency;
52 53
53#ifdef CONFIG_SMP 54#ifdef CONFIG_SMP
54extern void __inquire_remote_apic(int apicid); 55extern void __inquire_remote_apic(int apicid);
diff --git a/arch/x86/include/asm/mach_traps.h b/arch/x86/include/asm/mach_traps.h
index 72a8b52e7dfd..a01e7ec7d237 100644
--- a/arch/x86/include/asm/mach_traps.h
+++ b/arch/x86/include/asm/mach_traps.h
@@ -17,7 +17,7 @@
17#define NMI_REASON_CLEAR_IOCHK 0x08 17#define NMI_REASON_CLEAR_IOCHK 0x08
18#define NMI_REASON_CLEAR_MASK 0x0f 18#define NMI_REASON_CLEAR_MASK 0x0f
19 19
20static inline unsigned char get_nmi_reason(void) 20static inline unsigned char default_get_nmi_reason(void)
21{ 21{
22 return inb(NMI_REASON_PORT); 22 return inb(NMI_REASON_PORT);
23} 23}
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index c9321f34e55b..0e8ae57d3656 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -201,7 +201,10 @@ int mce_notify_irq(void);
201void mce_notify_process(void); 201void mce_notify_process(void);
202 202
203DECLARE_PER_CPU(struct mce, injectm); 203DECLARE_PER_CPU(struct mce, injectm);
204extern struct file_operations mce_chrdev_ops; 204
205extern void register_mce_write_callback(ssize_t (*)(struct file *filp,
206 const char __user *ubuf,
207 size_t usize, loff_t *off));
205 208
206/* 209/*
207 * Exception handler 210 * Exception handler
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index 719f00b28ff5..e6283129c821 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -44,6 +44,13 @@ enum mrst_timer_options {
44 44
45extern enum mrst_timer_options mrst_timer_options; 45extern enum mrst_timer_options mrst_timer_options;
46 46
47/*
48 * Penwell uses spread spectrum clock, so the freq number is not exactly
49 * the same as reported by MSR based on SDM.
50 */
51#define PENWELL_FSB_FREQ_83SKU 83200
52#define PENWELL_FSB_FREQ_100SKU 99840
53
47#define SFI_MTMR_MAX_NUM 8 54#define SFI_MTMR_MAX_NUM 8
48#define SFI_MRTC_MAX 8 55#define SFI_MRTC_MAX 8
49 56
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index d3d859035af9..1971e652d24b 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -152,6 +152,7 @@ struct x86_cpuinit_ops {
152/** 152/**
153 * struct x86_platform_ops - platform specific runtime functions 153 * struct x86_platform_ops - platform specific runtime functions
154 * @calibrate_tsc: calibrate TSC 154 * @calibrate_tsc: calibrate TSC
155 * @wallclock_init: init the wallclock device
155 * @get_wallclock: get time from HW clock like RTC etc. 156 * @get_wallclock: get time from HW clock like RTC etc.
156 * @set_wallclock: set time back to HW clock 157 * @set_wallclock: set time back to HW clock
157 * @is_untracked_pat_range exclude from PAT logic 158 * @is_untracked_pat_range exclude from PAT logic
@@ -160,11 +161,13 @@ struct x86_cpuinit_ops {
160 */ 161 */
161struct x86_platform_ops { 162struct x86_platform_ops {
162 unsigned long (*calibrate_tsc)(void); 163 unsigned long (*calibrate_tsc)(void);
164 void (*wallclock_init)(void);
163 unsigned long (*get_wallclock)(void); 165 unsigned long (*get_wallclock)(void);
164 int (*set_wallclock)(unsigned long nowtime); 166 int (*set_wallclock)(unsigned long nowtime);
165 void (*iommu_shutdown)(void); 167 void (*iommu_shutdown)(void);
166 bool (*is_untracked_pat_range)(u64 start, u64 end); 168 bool (*is_untracked_pat_range)(u64 start, u64 end);
167 void (*nmi_init)(void); 169 void (*nmi_init)(void);
170 unsigned char (*get_nmi_reason)(void);
168 int (*i8042_detect)(void); 171 int (*i8042_detect)(void);
169}; 172};
170 173
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index c63822816249..1f84794f0759 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -738,5 +738,5 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n)
738 738
739 atomic_set(&stop_machine_first, 1); 739 atomic_set(&stop_machine_first, 1);
740 wrote_text = 0; 740 wrote_text = 0;
741 __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); 741 __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask);
742} 742}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index a2fd72e0ab35..f98d84caf94c 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -186,7 +186,7 @@ static struct resource lapic_resource = {
186 .flags = IORESOURCE_MEM | IORESOURCE_BUSY, 186 .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
187}; 187};
188 188
189static unsigned int calibration_result; 189unsigned int lapic_timer_frequency = 0;
190 190
191static void apic_pm_activate(void); 191static void apic_pm_activate(void);
192 192
@@ -454,7 +454,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
454 switch (mode) { 454 switch (mode) {
455 case CLOCK_EVT_MODE_PERIODIC: 455 case CLOCK_EVT_MODE_PERIODIC:
456 case CLOCK_EVT_MODE_ONESHOT: 456 case CLOCK_EVT_MODE_ONESHOT:
457 __setup_APIC_LVTT(calibration_result, 457 __setup_APIC_LVTT(lapic_timer_frequency,
458 mode != CLOCK_EVT_MODE_PERIODIC, 1); 458 mode != CLOCK_EVT_MODE_PERIODIC, 1);
459 break; 459 break;
460 case CLOCK_EVT_MODE_UNUSED: 460 case CLOCK_EVT_MODE_UNUSED:
@@ -638,6 +638,25 @@ static int __init calibrate_APIC_clock(void)
638 long delta, deltatsc; 638 long delta, deltatsc;
639 int pm_referenced = 0; 639 int pm_referenced = 0;
640 640
641 /**
642 * check if lapic timer has already been calibrated by platform
643 * specific routine, such as tsc calibration code. if so, we just fill
644 * in the clockevent structure and return.
645 */
646
647 if (lapic_timer_frequency) {
648 apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n",
649 lapic_timer_frequency);
650 lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR,
651 TICK_NSEC, lapic_clockevent.shift);
652 lapic_clockevent.max_delta_ns =
653 clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
654 lapic_clockevent.min_delta_ns =
655 clockevent_delta2ns(0xF, &lapic_clockevent);
656 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
657 return 0;
658 }
659
641 local_irq_disable(); 660 local_irq_disable();
642 661
643 /* Replace the global interrupt handler */ 662 /* Replace the global interrupt handler */
@@ -679,12 +698,12 @@ static int __init calibrate_APIC_clock(void)
679 lapic_clockevent.min_delta_ns = 698 lapic_clockevent.min_delta_ns =
680 clockevent_delta2ns(0xF, &lapic_clockevent); 699 clockevent_delta2ns(0xF, &lapic_clockevent);
681 700
682 calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; 701 lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
683 702
684 apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta); 703 apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta);
685 apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult); 704 apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult);
686 apic_printk(APIC_VERBOSE, "..... calibration result: %u\n", 705 apic_printk(APIC_VERBOSE, "..... calibration result: %u\n",
687 calibration_result); 706 lapic_timer_frequency);
688 707
689 if (cpu_has_tsc) { 708 if (cpu_has_tsc) {
690 apic_printk(APIC_VERBOSE, "..... CPU clock speed is " 709 apic_printk(APIC_VERBOSE, "..... CPU clock speed is "
@@ -695,13 +714,13 @@ static int __init calibrate_APIC_clock(void)
695 714
696 apic_printk(APIC_VERBOSE, "..... host bus clock speed is " 715 apic_printk(APIC_VERBOSE, "..... host bus clock speed is "
697 "%u.%04u MHz.\n", 716 "%u.%04u MHz.\n",
698 calibration_result / (1000000 / HZ), 717 lapic_timer_frequency / (1000000 / HZ),
699 calibration_result % (1000000 / HZ)); 718 lapic_timer_frequency % (1000000 / HZ));
700 719
701 /* 720 /*
702 * Do a sanity check on the APIC calibration result 721 * Do a sanity check on the APIC calibration result
703 */ 722 */
704 if (calibration_result < (1000000 / HZ)) { 723 if (lapic_timer_frequency < (1000000 / HZ)) {
705 local_irq_enable(); 724 local_irq_enable();
706 pr_warning("APIC frequency too slow, disabling apic timer\n"); 725 pr_warning("APIC frequency too slow, disabling apic timer\n");
707 return -1; 726 return -1;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 3c31fa98af6d..6d939d7847e2 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -193,10 +193,8 @@ int __init arch_early_irq_init(void)
193 struct irq_cfg *cfg; 193 struct irq_cfg *cfg;
194 int count, node, i; 194 int count, node, i;
195 195
196 if (!legacy_pic->nr_legacy_irqs) { 196 if (!legacy_pic->nr_legacy_irqs)
197 nr_irqs_gsi = 0;
198 io_apic_irqs = ~0UL; 197 io_apic_irqs = ~0UL;
199 }
200 198
201 for (i = 0; i < nr_ioapics; i++) { 199 for (i = 0; i < nr_ioapics; i++) {
202 ioapics[i].saved_registers = 200 ioapics[i].saved_registers =
@@ -1696,6 +1694,7 @@ __apicdebuginit(void) print_IO_APICs(void)
1696 int ioapic_idx; 1694 int ioapic_idx;
1697 struct irq_cfg *cfg; 1695 struct irq_cfg *cfg;
1698 unsigned int irq; 1696 unsigned int irq;
1697 struct irq_chip *chip;
1699 1698
1700 printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); 1699 printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
1701 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) 1700 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++)
@@ -1716,6 +1715,10 @@ __apicdebuginit(void) print_IO_APICs(void)
1716 for_each_active_irq(irq) { 1715 for_each_active_irq(irq) {
1717 struct irq_pin_list *entry; 1716 struct irq_pin_list *entry;
1718 1717
1718 chip = irq_get_chip(irq);
1719 if (chip != &ioapic_chip)
1720 continue;
1721
1719 cfg = irq_get_chip_data(irq); 1722 cfg = irq_get_chip_data(irq);
1720 if (!cfg) 1723 if (!cfg)
1721 continue; 1724 continue;
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 6199232161cf..319882ef848d 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -208,7 +208,7 @@ static int inject_init(void)
208 if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) 208 if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL))
209 return -ENOMEM; 209 return -ENOMEM;
210 printk(KERN_INFO "Machine check injector initialized\n"); 210 printk(KERN_INFO "Machine check injector initialized\n");
211 mce_chrdev_ops.write = mce_write; 211 register_mce_write_callback(mce_write);
212 register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, 212 register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0,
213 "mce_notify"); 213 "mce_notify");
214 return 0; 214 return 0;
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 362056aefeb4..2af127d4c3d1 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1634,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd,
1634 } 1634 }
1635} 1635}
1636 1636
1637/* Modified in mce-inject.c, so not static or const */ 1637static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf,
1638struct file_operations mce_chrdev_ops = { 1638 size_t usize, loff_t *off);
1639
1640void register_mce_write_callback(ssize_t (*fn)(struct file *filp,
1641 const char __user *ubuf,
1642 size_t usize, loff_t *off))
1643{
1644 mce_write = fn;
1645}
1646EXPORT_SYMBOL_GPL(register_mce_write_callback);
1647
1648ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
1649 size_t usize, loff_t *off)
1650{
1651 if (mce_write)
1652 return mce_write(filp, ubuf, usize, off);
1653 else
1654 return -EINVAL;
1655}
1656
1657static const struct file_operations mce_chrdev_ops = {
1639 .open = mce_chrdev_open, 1658 .open = mce_chrdev_open,
1640 .release = mce_chrdev_release, 1659 .release = mce_chrdev_release,
1641 .read = mce_chrdev_read, 1660 .read = mce_chrdev_read,
1661 .write = mce_chrdev_write,
1642 .poll = mce_chrdev_poll, 1662 .poll = mce_chrdev_poll,
1643 .unlocked_ioctl = mce_chrdev_ioctl, 1663 .unlocked_ioctl = mce_chrdev_ioctl,
1644 .llseek = no_llseek, 1664 .llseek = no_llseek,
1645}; 1665};
1646EXPORT_SYMBOL_GPL(mce_chrdev_ops);
1647 1666
1648static struct miscdevice mce_chrdev_device = { 1667static struct miscdevice mce_chrdev_device = {
1649 MISC_MCELOG_MINOR, 1668 MISC_MCELOG_MINOR,
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index b9c8628974af..e88f37b58ddd 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -29,6 +29,7 @@
29#include <asm/traps.h> 29#include <asm/traps.h>
30#include <asm/mach_traps.h> 30#include <asm/mach_traps.h>
31#include <asm/nmi.h> 31#include <asm/nmi.h>
32#include <asm/x86_init.h>
32 33
33#define NMI_MAX_NAMELEN 16 34#define NMI_MAX_NAMELEN 16
34struct nmiaction { 35struct nmiaction {
@@ -348,7 +349,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
348 349
349 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */ 350 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
350 raw_spin_lock(&nmi_reason_lock); 351 raw_spin_lock(&nmi_reason_lock);
351 reason = get_nmi_reason(); 352 reason = x86_platform.get_nmi_reason();
352 353
353 if (reason & NMI_REASON_MASK) { 354 if (reason & NMI_REASON_MASK) {
354 if (reason & NMI_REASON_SERR) 355 if (reason & NMI_REASON_SERR)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index afaf38447ef5..cf0ef986cb6d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1045,6 +1045,8 @@ void __init setup_arch(char **cmdline_p)
1045 1045
1046 x86_init.timers.wallclock_init(); 1046 x86_init.timers.wallclock_init();
1047 1047
1048 x86_platform.wallclock_init();
1049
1048 mcheck_init(); 1050 mcheck_init();
1049 1051
1050 arch_init_ideal_nops(); 1052 arch_init_ideal_nops();
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 6f164bd5e14d..c1d6cd549397 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -21,12 +21,14 @@
21#include <asm/pat.h> 21#include <asm/pat.h>
22#include <asm/tsc.h> 22#include <asm/tsc.h>
23#include <asm/iommu.h> 23#include <asm/iommu.h>
24#include <asm/mach_traps.h>
24 25
25void __cpuinit x86_init_noop(void) { } 26void __cpuinit x86_init_noop(void) { }
26void __init x86_init_uint_noop(unsigned int unused) { } 27void __init x86_init_uint_noop(unsigned int unused) { }
27void __init x86_init_pgd_noop(pgd_t *unused) { } 28void __init x86_init_pgd_noop(pgd_t *unused) { }
28int __init iommu_init_noop(void) { return 0; } 29int __init iommu_init_noop(void) { return 0; }
29void iommu_shutdown_noop(void) { } 30void iommu_shutdown_noop(void) { }
31void wallclock_init_noop(void) { }
30 32
31/* 33/*
32 * The platform setup functions are preset with the default functions 34 * The platform setup functions are preset with the default functions
@@ -97,11 +99,13 @@ static int default_i8042_detect(void) { return 1; };
97 99
98struct x86_platform_ops x86_platform = { 100struct x86_platform_ops x86_platform = {
99 .calibrate_tsc = native_calibrate_tsc, 101 .calibrate_tsc = native_calibrate_tsc,
102 .wallclock_init = wallclock_init_noop,
100 .get_wallclock = mach_get_cmos_time, 103 .get_wallclock = mach_get_cmos_time,
101 .set_wallclock = mach_set_rtc_mmss, 104 .set_wallclock = mach_set_rtc_mmss,
102 .iommu_shutdown = iommu_shutdown_noop, 105 .iommu_shutdown = iommu_shutdown_noop,
103 .is_untracked_pat_range = is_ISA_range, 106 .is_untracked_pat_range = is_ISA_range,
104 .nmi_init = default_nmi_init, 107 .nmi_init = default_nmi_init,
108 .get_nmi_reason = default_get_nmi_reason,
105 .i8042_detect = default_i8042_detect 109 .i8042_detect = default_i8042_detect
106}; 110};
107 111
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
index 541020df0da6..b1489a06a49d 100644
--- a/arch/x86/platform/mrst/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
@@ -187,11 +187,34 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
187static unsigned long __init mrst_calibrate_tsc(void) 187static unsigned long __init mrst_calibrate_tsc(void)
188{ 188{
189 unsigned long flags, fast_calibrate; 189 unsigned long flags, fast_calibrate;
190 190 if (__mrst_cpu_chip == MRST_CPU_CHIP_PENWELL) {
191 local_irq_save(flags); 191 u32 lo, hi, ratio, fsb;
192 fast_calibrate = apbt_quick_calibrate(); 192
193 local_irq_restore(flags); 193 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
194 194 pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi);
195 ratio = (hi >> 8) & 0x1f;
196 pr_debug("ratio is %d\n", ratio);
197 if (!ratio) {
198 pr_err("read a zero ratio, should be incorrect!\n");
199 pr_err("force tsc ratio to 16 ...\n");
200 ratio = 16;
201 }
202 rdmsr(MSR_FSB_FREQ, lo, hi);
203 if ((lo & 0x7) == 0x7)
204 fsb = PENWELL_FSB_FREQ_83SKU;
205 else
206 fsb = PENWELL_FSB_FREQ_100SKU;
207 fast_calibrate = ratio * fsb;
208 pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
209 lapic_timer_frequency = fsb * 1000 / HZ;
210 /* mark tsc clocksource as reliable */
211 set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
212 } else {
213 local_irq_save(flags);
214 fast_calibrate = apbt_quick_calibrate();
215 local_irq_restore(flags);
216 }
217
195 if (fast_calibrate) 218 if (fast_calibrate)
196 return fast_calibrate; 219 return fast_calibrate;
197 220
@@ -254,6 +277,17 @@ static void mrst_reboot(void)
254} 277}
255 278
256/* 279/*
280 * Moorestown does not have external NMI source nor port 0x61 to report
281 * NMI status. The possible NMI sources are from pmu as a result of NMI
282 * watchdog or lock debug. Reading io port 0x61 results in 0xff which
283 * misled NMI handler.
284 */
285static unsigned char mrst_get_nmi_reason(void)
286{
287 return 0;
288}
289
290/*
257 * Moorestown specific x86_init function overrides and early setup 291 * Moorestown specific x86_init function overrides and early setup
258 * calls. 292 * calls.
259 */ 293 */
@@ -274,6 +308,8 @@ void __init x86_mrst_early_setup(void)
274 x86_platform.calibrate_tsc = mrst_calibrate_tsc; 308 x86_platform.calibrate_tsc = mrst_calibrate_tsc;
275 x86_platform.i8042_detect = mrst_i8042_detect; 309 x86_platform.i8042_detect = mrst_i8042_detect;
276 x86_init.timers.wallclock_init = mrst_rtc_init; 310 x86_init.timers.wallclock_init = mrst_rtc_init;
311 x86_platform.get_nmi_reason = mrst_get_nmi_reason;
312
277 x86_init.pci.init = pci_mrst_init; 313 x86_init.pci.init = pci_mrst_init;
278 x86_init.pci.fixup_irqs = x86_init_noop; 314 x86_init.pci.fixup_irqs = x86_init_noop;
279 315