aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/Makefile_326
-rw-r--r--arch/x86/kernel/Makefile_644
-rw-r--r--arch/x86/kernel/alternative.c1
-rw-r--r--arch/x86/kernel/apic_64.c372
-rw-r--r--arch/x86/kernel/bugs_64.c2
-rw-r--r--arch/x86/kernel/cpu/bugs.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/e_powersaver.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/elanfreq.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/gx-suspmod.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c5
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k6.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k7.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c13
-rw-r--r--arch/x86/kernel/cpu/cpufreq/sc520_freq.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c1
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-smi.c1
-rw-r--r--arch/x86/kernel/cpuid.c2
-rw-r--r--arch/x86/kernel/crash_dump_32.c2
-rw-r--r--arch/x86/kernel/crash_dump_64.c2
-rw-r--r--arch/x86/kernel/geode_32.c4
-rw-r--r--arch/x86/kernel/head64.c2
-rw-r--r--arch/x86/kernel/hpet.c (renamed from arch/x86/kernel/hpet_32.c)250
-rw-r--r--arch/x86/kernel/hpet_64.c493
-rw-r--r--arch/x86/kernel/i387_32.c2
-rw-r--r--arch/x86/kernel/i387_64.c2
-rw-r--r--arch/x86/kernel/i8237.c2
-rw-r--r--arch/x86/kernel/i8253.c (renamed from arch/x86/kernel/i8253_32.c)6
-rw-r--r--arch/x86/kernel/i8259_32.c1
-rw-r--r--arch/x86/kernel/i8259_64.c46
-rw-r--r--arch/x86/kernel/ioport_32.c2
-rw-r--r--arch/x86/kernel/ioport_64.c2
-rw-r--r--arch/x86/kernel/irq_32.c2
-rw-r--r--arch/x86/kernel/irq_64.c2
-rw-r--r--arch/x86/kernel/kprobes_32.c1
-rw-r--r--arch/x86/kernel/kprobes_64.c1
-rw-r--r--arch/x86/kernel/ldt_32.c2
-rw-r--r--arch/x86/kernel/ldt_64.c2
-rw-r--r--arch/x86/kernel/machine_kexec_32.c2
-rw-r--r--arch/x86/kernel/machine_kexec_64.c2
-rw-r--r--arch/x86/kernel/mca_32.c1
-rw-r--r--arch/x86/kernel/mfgpt_32.c362
-rw-r--r--arch/x86/kernel/msr.c2
-rw-r--r--arch/x86/kernel/nmi_32.c5
-rw-r--r--arch/x86/kernel/nmi_64.c4
-rw-r--r--arch/x86/kernel/pci-dma_32.c3
-rw-r--r--arch/x86/kernel/pci-dma_64.c1
-rw-r--r--arch/x86/kernel/process_32.c2
-rw-r--r--arch/x86/kernel/process_64.c6
-rw-r--r--arch/x86/kernel/ptrace_32.c1
-rw-r--r--arch/x86/kernel/ptrace_64.c1
-rw-r--r--arch/x86/kernel/quirks.c205
-rw-r--r--arch/x86/kernel/reboot_32.c4
-rw-r--r--arch/x86/kernel/reboot_fixups_32.c8
-rw-r--r--arch/x86/kernel/scx200_32.c12
-rw-r--r--arch/x86/kernel/setup_32.c2
-rw-r--r--arch/x86/kernel/setup_64.c39
-rw-r--r--arch/x86/kernel/signal_32.c2
-rw-r--r--arch/x86/kernel/signal_64.c2
-rw-r--r--arch/x86/kernel/smpboot_64.c11
-rw-r--r--arch/x86/kernel/stacktrace.c2
-rw-r--r--arch/x86/kernel/summit_32.c2
-rw-r--r--arch/x86/kernel/sys_i386_32.c2
-rw-r--r--arch/x86/kernel/sys_x86_64.c4
-rw-r--r--arch/x86/kernel/sysenter_32.c2
-rw-r--r--arch/x86/kernel/time_32.c5
-rw-r--r--arch/x86/kernel/time_64.c179
-rw-r--r--arch/x86/kernel/topology.c2
-rw-r--r--arch/x86/kernel/traps_32.c2
-rw-r--r--arch/x86/kernel/traps_64.c2
-rw-r--r--arch/x86/kernel/tsc_32.c6
-rw-r--r--arch/x86/kernel/tsc_64.c93
-rw-r--r--arch/x86/kernel/tsc_sync.c2
-rw-r--r--arch/x86/kernel/vm86_32.c2
-rw-r--r--arch/x86/kernel/vsyscall_64.c2
-rw-r--r--arch/x86/lib/copy_user_nocache_64.S1
-rw-r--r--arch/x86/pci/acpi.c194
-rw-r--r--arch/x86/pci/common.c19
-rw-r--r--arch/x86/pci/fixup.c47
-rw-r--r--arch/x86/pci/i386.c13
-rw-r--r--arch/x86/pci/irq.c39
-rw-r--r--arch/x86/pci/pci.h2
85 files changed, 1432 insertions, 1113 deletions
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index c624193740fd..7ff02063b858 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -7,7 +7,7 @@ extra-y := head_32.o init_task_32.o vmlinux.lds
7obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \ 7obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
8 ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \ 8 ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
9 pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\ 9 pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
10 quirks.o i8237.o topology.o alternative.o i8253_32.o tsc_32.o 10 quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o
11 11
12obj-$(CONFIG_STACKTRACE) += stacktrace.o 12obj-$(CONFIG_STACKTRACE) += stacktrace.o
13obj-y += cpu/ 13obj-y += cpu/
@@ -37,9 +37,9 @@ obj-$(CONFIG_EFI) += efi_32.o efi_stub_32.o
37obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o 37obj-$(CONFIG_DOUBLEFAULT) += doublefault_32.o
38obj-$(CONFIG_VM86) += vm86_32.o 38obj-$(CONFIG_VM86) += vm86_32.o
39obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 39obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
40obj-$(CONFIG_HPET_TIMER) += hpet_32.o 40obj-$(CONFIG_HPET_TIMER) += hpet.o
41obj-$(CONFIG_K8_NB) += k8.o 41obj-$(CONFIG_K8_NB) += k8.o
42obj-$(CONFIG_MGEODE_LX) += geode_32.o 42obj-$(CONFIG_MGEODE_LX) += geode_32.o mfgpt_32.o
43 43
44obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o 44obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o
45obj-$(CONFIG_PARAVIRT) += paravirt_32.o 45obj-$(CONFIG_PARAVIRT) += paravirt_32.o
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
index 3ab017a0a3b9..43da66213a47 100644
--- a/arch/x86/kernel/Makefile_64
+++ b/arch/x86/kernel/Makefile_64
@@ -8,8 +8,8 @@ obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
8 ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \ 8 ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
9 x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \ 9 x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
10 setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \ 10 setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \
11 pci-dma_64.o pci-nommu_64.o alternative.o hpet_64.o tsc_64.o bugs_64.o \ 11 pci-dma_64.o pci-nommu_64.o alternative.o hpet.o tsc_64.o bugs_64.o \
12 perfctr-watchdog.o 12 perfctr-watchdog.o i8253.o
13 13
14obj-$(CONFIG_STACKTRACE) += stacktrace.o 14obj-$(CONFIG_STACKTRACE) += stacktrace.o
15obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o 15obj-$(CONFIG_X86_MCE) += mce_64.o therm_throt.o
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index bd72d94e713e..11b03d3c6fda 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -10,6 +10,7 @@
10#include <asm/pgtable.h> 10#include <asm/pgtable.h>
11#include <asm/mce.h> 11#include <asm/mce.h>
12#include <asm/nmi.h> 12#include <asm/nmi.h>
13#include <asm/vsyscall.h>
13 14
14#define MAX_PATCH_LEN (255-1) 15#define MAX_PATCH_LEN (255-1)
15 16
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index 925758dbca0c..09b82093bc75 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -25,6 +25,7 @@
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/clockchips.h>
28 29
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/smp.h> 31#include <asm/smp.h>
@@ -39,12 +40,9 @@
39#include <asm/hpet.h> 40#include <asm/hpet.h>
40#include <asm/apic.h> 41#include <asm/apic.h>
41 42
42int apic_mapped;
43int apic_verbosity; 43int apic_verbosity;
44int apic_runs_main_timer; 44int disable_apic_timer __cpuinitdata;
45int apic_calibrate_pmtmr __initdata; 45static int apic_calibrate_pmtmr __initdata;
46
47int disable_apic_timer __initdata;
48 46
49/* Local APIC timer works in C2? */ 47/* Local APIC timer works in C2? */
50int local_apic_timer_c2_ok; 48int local_apic_timer_c2_ok;
@@ -56,14 +54,78 @@ static struct resource lapic_resource = {
56 .flags = IORESOURCE_MEM | IORESOURCE_BUSY, 54 .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
57}; 55};
58 56
57static unsigned int calibration_result;
58
59static int lapic_next_event(unsigned long delta,
60 struct clock_event_device *evt);
61static void lapic_timer_setup(enum clock_event_mode mode,
62 struct clock_event_device *evt);
63
64static void lapic_timer_broadcast(cpumask_t mask);
65
66static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen);
67
68static struct clock_event_device lapic_clockevent = {
69 .name = "lapic",
70 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
71 | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
72 .shift = 32,
73 .set_mode = lapic_timer_setup,
74 .set_next_event = lapic_next_event,
75 .broadcast = lapic_timer_broadcast,
76 .rating = 100,
77 .irq = -1,
78};
79static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
80
81static int lapic_next_event(unsigned long delta,
82 struct clock_event_device *evt)
83{
84 apic_write(APIC_TMICT, delta);
85 return 0;
86}
87
88static void lapic_timer_setup(enum clock_event_mode mode,
89 struct clock_event_device *evt)
90{
91 unsigned long flags;
92 unsigned int v;
93
94 /* Lapic used as dummy for broadcast ? */
95 if (evt->features & CLOCK_EVT_FEAT_DUMMY)
96 return;
97
98 local_irq_save(flags);
99
100 switch (mode) {
101 case CLOCK_EVT_MODE_PERIODIC:
102 case CLOCK_EVT_MODE_ONESHOT:
103 __setup_APIC_LVTT(calibration_result,
104 mode != CLOCK_EVT_MODE_PERIODIC, 1);
105 break;
106 case CLOCK_EVT_MODE_UNUSED:
107 case CLOCK_EVT_MODE_SHUTDOWN:
108 v = apic_read(APIC_LVTT);
109 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
110 apic_write(APIC_LVTT, v);
111 break;
112 case CLOCK_EVT_MODE_RESUME:
113 /* Nothing to do here */
114 break;
115 }
116
117 local_irq_restore(flags);
118}
119
59/* 120/*
60 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as 121 * Local APIC timer broadcast function
61 * IPIs in place of local APIC timers
62 */ 122 */
63static cpumask_t timer_interrupt_broadcast_ipi_mask; 123static void lapic_timer_broadcast(cpumask_t mask)
64 124{
65/* Using APIC to generate smp_local_timer_interrupt? */ 125#ifdef CONFIG_SMP
66int using_apic_timer __read_mostly = 0; 126 send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
127#endif
128}
67 129
68static void apic_pm_activate(void); 130static void apic_pm_activate(void);
69 131
@@ -184,7 +246,10 @@ void disconnect_bsp_APIC(int virt_wire_setup)
184 apic_write(APIC_SPIV, value); 246 apic_write(APIC_SPIV, value);
185 247
186 if (!virt_wire_setup) { 248 if (!virt_wire_setup) {
187 /* For LVT0 make it edge triggered, active high, external and enabled */ 249 /*
250 * For LVT0 make it edge triggered, active high,
251 * external and enabled
252 */
188 value = apic_read(APIC_LVT0); 253 value = apic_read(APIC_LVT0);
189 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | 254 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
190 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 255 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
@@ -420,10 +485,12 @@ void __cpuinit setup_local_APIC (void)
420 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; 485 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
421 if (!smp_processor_id() && !value) { 486 if (!smp_processor_id() && !value) {
422 value = APIC_DM_EXTINT; 487 value = APIC_DM_EXTINT;
423 apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", smp_processor_id()); 488 apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
489 smp_processor_id());
424 } else { 490 } else {
425 value = APIC_DM_EXTINT | APIC_LVT_MASKED; 491 value = APIC_DM_EXTINT | APIC_LVT_MASKED;
426 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", smp_processor_id()); 492 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
493 smp_processor_id());
427 } 494 }
428 apic_write(APIC_LVT0, value); 495 apic_write(APIC_LVT0, value);
429 496
@@ -706,8 +773,8 @@ void __init init_apic_mappings(void)
706 apic_phys = mp_lapic_addr; 773 apic_phys = mp_lapic_addr;
707 774
708 set_fixmap_nocache(FIX_APIC_BASE, apic_phys); 775 set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
709 apic_mapped = 1; 776 apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
710 apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); 777 APIC_BASE, apic_phys);
711 778
712 /* Put local APIC into the resource map. */ 779 /* Put local APIC into the resource map. */
713 lapic_resource.start = apic_phys; 780 lapic_resource.start = apic_phys;
@@ -730,12 +797,14 @@ void __init init_apic_mappings(void)
730 if (smp_found_config) { 797 if (smp_found_config) {
731 ioapic_phys = mp_ioapics[i].mpc_apicaddr; 798 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
732 } else { 799 } else {
733 ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); 800 ioapic_phys = (unsigned long)
801 alloc_bootmem_pages(PAGE_SIZE);
734 ioapic_phys = __pa(ioapic_phys); 802 ioapic_phys = __pa(ioapic_phys);
735 } 803 }
736 set_fixmap_nocache(idx, ioapic_phys); 804 set_fixmap_nocache(idx, ioapic_phys);
737 apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", 805 apic_printk(APIC_VERBOSE,
738 __fix_to_virt(idx), ioapic_phys); 806 "mapped IOAPIC to %016lx (%016lx)\n",
807 __fix_to_virt(idx), ioapic_phys);
739 idx++; 808 idx++;
740 809
741 if (ioapic_res != NULL) { 810 if (ioapic_res != NULL) {
@@ -758,16 +827,14 @@ void __init init_apic_mappings(void)
758 * P5 APIC double write bug. 827 * P5 APIC double write bug.
759 */ 828 */
760 829
761#define APIC_DIVISOR 16 830static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
762
763static void __setup_APIC_LVTT(unsigned int clocks)
764{ 831{
765 unsigned int lvtt_value, tmp_value; 832 unsigned int lvtt_value, tmp_value;
766 int cpu = smp_processor_id();
767 833
768 lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; 834 lvtt_value = LOCAL_TIMER_VECTOR;
769 835 if (!oneshot)
770 if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) 836 lvtt_value |= APIC_LVT_TIMER_PERIODIC;
837 if (!irqen)
771 lvtt_value |= APIC_LVT_MASKED; 838 lvtt_value |= APIC_LVT_MASKED;
772 839
773 apic_write(APIC_LVTT, lvtt_value); 840 apic_write(APIC_LVTT, lvtt_value);
@@ -780,44 +847,18 @@ static void __setup_APIC_LVTT(unsigned int clocks)
780 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) 847 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
781 | APIC_TDR_DIV_16); 848 | APIC_TDR_DIV_16);
782 849
783 apic_write(APIC_TMICT, clocks/APIC_DIVISOR); 850 if (!oneshot)
851 apic_write(APIC_TMICT, clocks);
784} 852}
785 853
786static void setup_APIC_timer(unsigned int clocks) 854static void setup_APIC_timer(void)
787{ 855{
788 unsigned long flags; 856 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
789 857
790 local_irq_save(flags); 858 memcpy(levt, &lapic_clockevent, sizeof(*levt));
859 levt->cpumask = cpumask_of_cpu(smp_processor_id());
791 860
792 /* wait for irq slice */ 861 clockevents_register_device(levt);
793 if (hpet_address && hpet_use_timer) {
794 u32 trigger = hpet_readl(HPET_T0_CMP);
795 while (hpet_readl(HPET_T0_CMP) == trigger)
796 /* do nothing */ ;
797 } else {
798 int c1, c2;
799 outb_p(0x00, 0x43);
800 c2 = inb_p(0x40);
801 c2 |= inb_p(0x40) << 8;
802 do {
803 c1 = c2;
804 outb_p(0x00, 0x43);
805 c2 = inb_p(0x40);
806 c2 |= inb_p(0x40) << 8;
807 } while (c2 - c1 < 300);
808 }
809 __setup_APIC_LVTT(clocks);
810 /* Turn off PIT interrupt if we use APIC timer as main timer.
811 Only works with the PM timer right now
812 TBD fix it for HPET too. */
813 if ((pmtmr_ioport != 0) &&
814 smp_processor_id() == boot_cpu_id &&
815 apic_runs_main_timer == 1 &&
816 !cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) {
817 stop_timer_interrupt();
818 apic_runs_main_timer++;
819 }
820 local_irq_restore(flags);
821} 862}
822 863
823/* 864/*
@@ -835,17 +876,22 @@ static void setup_APIC_timer(unsigned int clocks)
835 876
836#define TICK_COUNT 100000000 877#define TICK_COUNT 100000000
837 878
838static int __init calibrate_APIC_clock(void) 879static void __init calibrate_APIC_clock(void)
839{ 880{
840 unsigned apic, apic_start; 881 unsigned apic, apic_start;
841 unsigned long tsc, tsc_start; 882 unsigned long tsc, tsc_start;
842 int result; 883 int result;
884
885 local_irq_disable();
886
843 /* 887 /*
844 * Put whatever arbitrary (but long enough) timeout 888 * Put whatever arbitrary (but long enough) timeout
845 * value into the APIC clock, we just want to get the 889 * value into the APIC clock, we just want to get the
846 * counter running for calibration. 890 * counter running for calibration.
891 *
892 * No interrupt enable !
847 */ 893 */
848 __setup_APIC_LVTT(4000000000); 894 __setup_APIC_LVTT(250000000, 0, 0);
849 895
850 apic_start = apic_read(APIC_TMCCT); 896 apic_start = apic_read(APIC_TMCCT);
851#ifdef CONFIG_X86_PM_TIMER 897#ifdef CONFIG_X86_PM_TIMER
@@ -867,123 +913,88 @@ static int __init calibrate_APIC_clock(void)
867 result = (apic_start - apic) * 1000L * tsc_khz / 913 result = (apic_start - apic) * 1000L * tsc_khz /
868 (tsc - tsc_start); 914 (tsc - tsc_start);
869 } 915 }
870 printk("result %d\n", result);
871 916
917 local_irq_enable();
918
919 printk(KERN_DEBUG "APIC timer calibration result %d\n", result);
872 920
873 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", 921 printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
874 result / 1000 / 1000, result / 1000 % 1000); 922 result / 1000 / 1000, result / 1000 % 1000);
875 923
876 return result * APIC_DIVISOR / HZ; 924 /* Calculate the scaled math multiplication factor */
877} 925 lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC, 32);
926 lapic_clockevent.max_delta_ns =
927 clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
928 lapic_clockevent.min_delta_ns =
929 clockevent_delta2ns(0xF, &lapic_clockevent);
878 930
879static unsigned int calibration_result; 931 calibration_result = result / HZ;
932}
880 933
881void __init setup_boot_APIC_clock (void) 934void __init setup_boot_APIC_clock (void)
882{ 935{
936 /*
937 * The local apic timer can be disabled via the kernel commandline.
938 * Register the lapic timer as a dummy clock event source on SMP
939 * systems, so the broadcast mechanism is used. On UP systems simply
940 * ignore it.
941 */
883 if (disable_apic_timer) { 942 if (disable_apic_timer) {
884 printk(KERN_INFO "Disabling APIC timer\n"); 943 printk(KERN_INFO "Disabling APIC timer\n");
944 /* No broadcast on UP ! */
945 if (num_possible_cpus() > 1)
946 setup_APIC_timer();
885 return; 947 return;
886 } 948 }
887 949
888 printk(KERN_INFO "Using local APIC timer interrupts.\n"); 950 printk(KERN_INFO "Using local APIC timer interrupts.\n");
889 using_apic_timer = 1; 951 calibrate_APIC_clock();
890
891 local_irq_disable();
892 952
893 calibration_result = calibrate_APIC_clock();
894 /* 953 /*
895 * Now set up the timer for real. 954 * If nmi_watchdog is set to IO_APIC, we need the
955 * PIT/HPET going. Otherwise register lapic as a dummy
956 * device.
896 */ 957 */
897 setup_APIC_timer(calibration_result); 958 if (nmi_watchdog != NMI_IO_APIC)
898 959 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
899 local_irq_enable(); 960 else
900} 961 printk(KERN_WARNING "APIC timer registered as dummy,"
901 962 " due to nmi_watchdog=1!\n");
902void __cpuinit setup_secondary_APIC_clock(void)
903{
904 local_irq_disable(); /* FIXME: Do we need this? --RR */
905 setup_APIC_timer(calibration_result);
906 local_irq_enable();
907}
908
909void disable_APIC_timer(void)
910{
911 if (using_apic_timer) {
912 unsigned long v;
913 963
914 v = apic_read(APIC_LVTT); 964 setup_APIC_timer();
915 /*
916 * When an illegal vector value (0-15) is written to an LVT
917 * entry and delivery mode is Fixed, the APIC may signal an
918 * illegal vector error, with out regard to whether the mask
919 * bit is set or whether an interrupt is actually seen on input.
920 *
921 * Boot sequence might call this function when the LVTT has
922 * '0' vector value. So make sure vector field is set to
923 * valid value.
924 */
925 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
926 apic_write(APIC_LVTT, v);
927 }
928} 965}
929 966
930void enable_APIC_timer(void) 967/*
968 * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the
969 * C1E flag only in the secondary CPU, so when we detect the wreckage
970 * we already have enabled the boot CPU local apic timer. Check, if
971 * disable_apic_timer is set and the DUMMY flag is cleared. If yes,
972 * set the DUMMY flag again and force the broadcast mode in the
973 * clockevents layer.
974 */
975void __cpuinit check_boot_apic_timer_broadcast(void)
931{ 976{
932 int cpu = smp_processor_id(); 977 struct clock_event_device *levt = &per_cpu(lapic_events, boot_cpu_id);
933 978
934 if (using_apic_timer && 979 if (!disable_apic_timer ||
935 !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) { 980 (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY))
936 unsigned long v; 981 return;
937 982
938 v = apic_read(APIC_LVTT); 983 printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n");
939 apic_write(APIC_LVTT, v & ~APIC_LVT_MASKED); 984 lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY;
940 } 985 levt->features |= CLOCK_EVT_FEAT_DUMMY;
941}
942 986
943void switch_APIC_timer_to_ipi(void *cpumask) 987 local_irq_enable();
944{ 988 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, &boot_cpu_id);
945 cpumask_t mask = *(cpumask_t *)cpumask; 989 local_irq_disable();
946 int cpu = smp_processor_id();
947
948 if (cpu_isset(cpu, mask) &&
949 !cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
950 disable_APIC_timer();
951 cpu_set(cpu, timer_interrupt_broadcast_ipi_mask);
952 }
953} 990}
954EXPORT_SYMBOL(switch_APIC_timer_to_ipi);
955 991
956void smp_send_timer_broadcast_ipi(void) 992void __cpuinit setup_secondary_APIC_clock(void)
957{ 993{
958 int cpu = smp_processor_id(); 994 check_boot_apic_timer_broadcast();
959 cpumask_t mask; 995 setup_APIC_timer();
960
961 cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask);
962
963 if (cpu_isset(cpu, mask)) {
964 cpu_clear(cpu, mask);
965 add_pda(apic_timer_irqs, 1);
966 smp_local_timer_interrupt();
967 }
968
969 if (!cpus_empty(mask)) {
970 send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
971 }
972} 996}
973 997
974void switch_ipi_to_APIC_timer(void *cpumask)
975{
976 cpumask_t mask = *(cpumask_t *)cpumask;
977 int cpu = smp_processor_id();
978
979 if (cpu_isset(cpu, mask) &&
980 cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) {
981 cpu_clear(cpu, timer_interrupt_broadcast_ipi_mask);
982 enable_APIC_timer();
983 }
984}
985EXPORT_SYMBOL(switch_ipi_to_APIC_timer);
986
987int setup_profiling_timer(unsigned int multiplier) 998int setup_profiling_timer(unsigned int multiplier)
988{ 999{
989 return -EINVAL; 1000 return -EINVAL;
@@ -997,8 +1008,6 @@ void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
997 apic_write(reg, v); 1008 apic_write(reg, v);
998} 1009}
999 1010
1000#undef APIC_DIVISOR
1001
1002/* 1011/*
1003 * Local timer interrupt handler. It does both profiling and 1012 * Local timer interrupt handler. It does both profiling and
1004 * process statistics/rescheduling. 1013 * process statistics/rescheduling.
@@ -1011,22 +1020,34 @@ void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
1011 1020
1012void smp_local_timer_interrupt(void) 1021void smp_local_timer_interrupt(void)
1013{ 1022{
1014 profile_tick(CPU_PROFILING); 1023 int cpu = smp_processor_id();
1015#ifdef CONFIG_SMP 1024 struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
1016 update_process_times(user_mode(get_irq_regs())); 1025
1017#endif
1018 if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id)
1019 main_timer_handler();
1020 /* 1026 /*
1021 * We take the 'long' return path, and there every subsystem 1027 * Normally we should not be here till LAPIC has been initialized but
1022 * grabs the appropriate locks (kernel lock/ irq lock). 1028 * in some cases like kdump, its possible that there is a pending LAPIC
1029 * timer interrupt from previous kernel's context and is delivered in
1030 * new kernel the moment interrupts are enabled.
1023 * 1031 *
1024 * We might want to decouple profiling from the 'long path', 1032 * Interrupts are enabled early and LAPIC is setup much later, hence
1025 * and do the profiling totally in assembly. 1033 * its possible that when we get here evt->event_handler is NULL.
1026 * 1034 * Check for event_handler being NULL and discard the interrupt as
1027 * Currently this isn't too much of an issue (performance wise), 1035 * spurious.
1028 * we can take more than 100K local irqs per second on a 100 MHz P5. 1036 */
1037 if (!evt->event_handler) {
1038 printk(KERN_WARNING
1039 "Spurious LAPIC timer interrupt on cpu %d\n", cpu);
1040 /* Switch it off */
1041 lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
1042 return;
1043 }
1044
1045 /*
1046 * the NMI deadlock-detector uses this.
1029 */ 1047 */
1048 add_pda(apic_timer_irqs, 1);
1049
1050 evt->event_handler(evt);
1030} 1051}
1031 1052
1032/* 1053/*
@@ -1042,11 +1063,6 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
1042 struct pt_regs *old_regs = set_irq_regs(regs); 1063 struct pt_regs *old_regs = set_irq_regs(regs);
1043 1064
1044 /* 1065 /*
1045 * the NMI deadlock-detector uses this.
1046 */
1047 add_pda(apic_timer_irqs, 1);
1048
1049 /*
1050 * NOTE! We'd better ACK the irq immediately, 1066 * NOTE! We'd better ACK the irq immediately,
1051 * because timer handling can be slow. 1067 * because timer handling can be slow.
1052 */ 1068 */
@@ -1225,29 +1241,13 @@ static __init int setup_noapictimer(char *str)
1225 disable_apic_timer = 1; 1241 disable_apic_timer = 1;
1226 return 1; 1242 return 1;
1227} 1243}
1228 1244__setup("noapictimer", setup_noapictimer);
1229static __init int setup_apicmaintimer(char *str)
1230{
1231 apic_runs_main_timer = 1;
1232 nohpet = 1;
1233 return 1;
1234}
1235__setup("apicmaintimer", setup_apicmaintimer);
1236
1237static __init int setup_noapicmaintimer(char *str)
1238{
1239 apic_runs_main_timer = -1;
1240 return 1;
1241}
1242__setup("noapicmaintimer", setup_noapicmaintimer);
1243 1245
1244static __init int setup_apicpmtimer(char *s) 1246static __init int setup_apicpmtimer(char *s)
1245{ 1247{
1246 apic_calibrate_pmtmr = 1; 1248 apic_calibrate_pmtmr = 1;
1247 notsc_setup(NULL); 1249 notsc_setup(NULL);
1248 return setup_apicmaintimer(NULL); 1250 return 0;
1249} 1251}
1250__setup("apicpmtimer", setup_apicpmtimer); 1252__setup("apicpmtimer", setup_apicpmtimer);
1251 1253
1252__setup("noapictimer", setup_noapictimer);
1253
diff --git a/arch/x86/kernel/bugs_64.c b/arch/x86/kernel/bugs_64.c
index 4e5e9d364d63..9a189cef6404 100644
--- a/arch/x86/kernel/bugs_64.c
+++ b/arch/x86/kernel/bugs_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/x86_64/kernel/bugs.c
3 *
4 * Copyright (C) 1994 Linus Torvalds 2 * Copyright (C) 1994 Linus Torvalds
5 * Copyright (C) 2000 SuSE 3 * Copyright (C) 2000 SuSE
6 */ 4 */
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 59266f03d1cd..205fd5ba57f7 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/i386/cpu/bugs.c
3 *
4 * Copyright (C) 1994 Linus Torvalds 2 * Copyright (C) 1994 Linus Torvalds
5 * 3 *
6 * Cyrix stuff, June 1998 by: 4 * Cyrix stuff, June 1998 by:
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index b6434a7ef8b2..ffd01e5dcb52 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -646,7 +646,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
646 policy->cpuinfo.transition_latency = 646 policy->cpuinfo.transition_latency =
647 perf->states[i].transition_latency * 1000; 647 perf->states[i].transition_latency * 1000;
648 } 648 }
649 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
650 649
651 data->max_freq = perf->states[0].core_frequency * 1000; 650 data->max_freq = perf->states[0].core_frequency * 1000;
652 /* table init */ 651 /* table init */
diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 66acd5039918..32f0bda3fc95 100644
--- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -363,7 +363,6 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
363 policy->cur = nforce2_get(policy->cpu); 363 policy->cur = nforce2_get(policy->cpu);
364 policy->min = policy->cpuinfo.min_freq; 364 policy->min = policy->cpuinfo.min_freq;
365 policy->max = policy->cpuinfo.max_freq; 365 policy->max = policy->cpuinfo.max_freq;
366 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
367 366
368 return 0; 367 return 0;
369} 368}
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index f43d98e11cc7..c11baaf9f2b4 100644
--- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -253,7 +253,6 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
253 f_table[k].frequency = CPUFREQ_TABLE_END; 253 f_table[k].frequency = CPUFREQ_TABLE_END;
254 } 254 }
255 255
256 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
257 policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ 256 policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */
258 policy->cur = fsb * current_multiplier; 257 policy->cur = fsb * current_multiplier;
259 258
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
index f317276afa7a..1e7ae7dafcf6 100644
--- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
@@ -219,7 +219,6 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
219 } 219 }
220 220
221 /* cpuinfo and default policy values */ 221 /* cpuinfo and default policy values */
222 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
223 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 222 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
224 policy->cur = elanfreq_get_cpu_frequency(0); 223 policy->cur = elanfreq_get_cpu_frequency(0);
225 224
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
index 461dabc4e495..ed2bda127c44 100644
--- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
@@ -420,7 +420,6 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
420 policy->min = maxfreq / POLICY_MIN_DIV; 420 policy->min = maxfreq / POLICY_MIN_DIV;
421 policy->max = maxfreq; 421 policy->max = maxfreq;
422 policy->cur = curfreq; 422 policy->cur = curfreq;
423 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
424 policy->cpuinfo.min_freq = maxfreq / max_duration; 423 policy->cpuinfo.min_freq = maxfreq / max_duration;
425 policy->cpuinfo.max_freq = maxfreq; 424 policy->cpuinfo.max_freq = maxfreq;
426 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 425 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index f0cce3c2dc3a..5045f5d583c8 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -710,6 +710,10 @@ static int enable_arbiter_disable(void)
710 reg = 0x78; 710 reg = 0x78;
711 dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, 711 dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
712 NULL); 712 NULL);
713 /* Find PM133/VT8605 host bridge */
714 if (dev == NULL)
715 dev = pci_get_device(PCI_VENDOR_ID_VIA,
716 PCI_DEVICE_ID_VIA_8605_0, NULL);
713 /* Find CLE266 host bridge */ 717 /* Find CLE266 host bridge */
714 if (dev == NULL) { 718 if (dev == NULL) {
715 reg = 0x76; 719 reg = 0x76;
@@ -918,7 +922,6 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
918 if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0)) 922 if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0))
919 longhaul_setup_voltagescaling(); 923 longhaul_setup_voltagescaling();
920 924
921 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
922 policy->cpuinfo.transition_latency = 200000; /* nsec */ 925 policy->cpuinfo.transition_latency = 200000; /* nsec */
923 policy->cur = calc_speed(longhaul_get_cpu_mult()); 926 policy->cur = calc_speed(longhaul_get_cpu_mult());
924 927
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 4c76b511e194..8eb414b906d2 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -229,7 +229,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
229 cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); 229 cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
230 230
231 /* cpuinfo and default policy values */ 231 /* cpuinfo and default policy values */
232 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
233 policy->cpuinfo.transition_latency = 1000000; /* assumed */ 232 policy->cpuinfo.transition_latency = 1000000; /* assumed */
234 policy->cur = stock_freq; 233 policy->cur = stock_freq;
235 234
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index f89524051e4a..6d0285339317 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -160,7 +160,6 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
160 } 160 }
161 161
162 /* cpuinfo and default policy values */ 162 /* cpuinfo and default policy values */
163 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
164 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 163 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
165 policy->cur = busfreq * max_multiplier; 164 policy->cur = busfreq * max_multiplier;
166 165
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index ca3e1d341889..7decd6a50ffa 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -637,8 +637,6 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
637 printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", 637 printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
638 minimum_speed/1000, maximum_speed/1000); 638 minimum_speed/1000, maximum_speed/1000);
639 639
640 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
641
642 policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency); 640 policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency);
643 641
644 policy->cur = powernow_get(0); 642 policy->cur = powernow_get(0);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 34ed53a06730..b273b69cfddf 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -76,7 +76,10 @@ static u32 find_khz_freq_from_fid(u32 fid)
76/* Return a frequency in MHz, given an input fid and did */ 76/* Return a frequency in MHz, given an input fid and did */
77static u32 find_freq_from_fiddid(u32 fid, u32 did) 77static u32 find_freq_from_fiddid(u32 fid, u32 did)
78{ 78{
79 return 100 * (fid + 0x10) >> did; 79 if (current_cpu_data.x86 == 0x10)
80 return 100 * (fid + 0x10) >> did;
81 else
82 return 100 * (fid + 0x8) >> did;
80} 83}
81 84
82static u32 find_khz_freq_from_fiddid(u32 fid, u32 did) 85static u32 find_khz_freq_from_fiddid(u32 fid, u32 did)
@@ -1208,7 +1211,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1208 /* run on any CPU again */ 1211 /* run on any CPU again */
1209 set_cpus_allowed(current, oldmask); 1212 set_cpus_allowed(current, oldmask);
1210 1213
1211 pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
1212 if (cpu_family == CPU_HW_PSTATE) 1214 if (cpu_family == CPU_HW_PSTATE)
1213 pol->cpus = cpumask_of_cpu(pol->cpu); 1215 pol->cpus = cpumask_of_cpu(pol->cpu);
1214 else 1216 else
@@ -1325,21 +1327,16 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
1325static int __cpuinit powernowk8_init(void) 1327static int __cpuinit powernowk8_init(void)
1326{ 1328{
1327 unsigned int i, supported_cpus = 0; 1329 unsigned int i, supported_cpus = 0;
1328 unsigned int booted_cores = 1;
1329 1330
1330 for_each_online_cpu(i) { 1331 for_each_online_cpu(i) {
1331 if (check_supported_cpu(i)) 1332 if (check_supported_cpu(i))
1332 supported_cpus++; 1333 supported_cpus++;
1333 } 1334 }
1334 1335
1335#ifdef CONFIG_SMP
1336 booted_cores = cpu_data[0].booted_cores;
1337#endif
1338
1339 if (supported_cpus == num_online_cpus()) { 1336 if (supported_cpus == num_online_cpus()) {
1340 printk(KERN_INFO PFX "Found %d %s " 1337 printk(KERN_INFO PFX "Found %d %s "
1341 "processors (%d cpu cores) (" VERSION ")\n", 1338 "processors (%d cpu cores) (" VERSION ")\n",
1342 supported_cpus/booted_cores, 1339 num_online_nodes(),
1343 boot_cpu_data.x86_model_id, supported_cpus); 1340 boot_cpu_data.x86_model_id, supported_cpus);
1344 return cpufreq_register_driver(&cpufreq_amd64_driver); 1341 return cpufreq_register_driver(&cpufreq_amd64_driver);
1345 } 1342 }
diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
index b8fb4b521c62..d9f3e90a7ae0 100644
--- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
+++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
@@ -111,7 +111,6 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
111 return -ENODEV; 111 return -ENODEV;
112 112
113 /* cpuinfo and default policy values */ 113 /* cpuinfo and default policy values */
114 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
115 policy->cpuinfo.transition_latency = 1000000; /* 1ms */ 114 policy->cpuinfo.transition_latency = 1000000; /* 1ms */
116 policy->cur = sc520_freq_get_cpu_frequency(0); 115 policy->cur = sc520_freq_get_cpu_frequency(0);
117 116
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index 6c5dc2c85aeb..811d47438546 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -393,7 +393,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
393 393
394 freq = get_cur_freq(policy->cpu); 394 freq = get_cur_freq(policy->cpu);
395 395
396 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
397 policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */ 396 policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */
398 policy->cur = freq; 397 policy->cur = freq;
399 398
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index a5b2346faf1f..36685e8f7be1 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -348,7 +348,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
348 (speed / 1000)); 348 (speed / 1000));
349 349
350 /* cpuinfo and default policy values */ 350 /* cpuinfo and default policy values */
351 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
352 policy->cur = speed; 351 policy->cur = speed;
353 352
354 result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); 353 result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
index e1c509aa3054..f2b5a621d27b 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
@@ -290,7 +290,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
290 (speed / 1000)); 290 (speed / 1000));
291 291
292 /* cpuinfo and default policy values */ 292 /* cpuinfo and default policy values */
293 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
294 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 293 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
295 policy->cur = speed; 294 policy->cur = speed;
296 295
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 5c2faa10e9fa..f4548c93ccf5 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -11,8 +11,6 @@
11 * ----------------------------------------------------------------------- */ 11 * ----------------------------------------------------------------------- */
12 12
13/* 13/*
14 * cpuid.c
15 *
16 * x86 CPUID access device 14 * x86 CPUID access device
17 * 15 *
18 * This device is accessed by lseek() to the appropriate CPUID level 16 * This device is accessed by lseek() to the appropriate CPUID level
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index 3f532df488bc..32e75d0731a9 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * kernel/crash_dump.c - Memory preserving reboot related code. 2 * Memory preserving reboot related code.
3 * 3 *
4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) 4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
5 * Copyright (C) IBM Corporation, 2004. All rights reserved 5 * Copyright (C) IBM Corporation, 2004. All rights reserved
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index 942deac4d43a..15e6c6bc4a46 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * kernel/crash_dump.c - Memory preserving reboot related code. 2 * Memory preserving reboot related code.
3 * 3 *
4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) 4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
5 * Copyright (C) IBM Corporation, 2004. All rights reserved 5 * Copyright (C) IBM Corporation, 2004. All rights reserved
diff --git a/arch/x86/kernel/geode_32.c b/arch/x86/kernel/geode_32.c
index 41e8aec4c61d..f12d8c5d9809 100644
--- a/arch/x86/kernel/geode_32.c
+++ b/arch/x86/kernel/geode_32.c
@@ -145,10 +145,14 @@ EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
145 145
146static int __init geode_southbridge_init(void) 146static int __init geode_southbridge_init(void)
147{ 147{
148 int timers;
149
148 if (!is_geode()) 150 if (!is_geode())
149 return -ENODEV; 151 return -ENODEV;
150 152
151 init_lbars(); 153 init_lbars();
154 timers = geode_mfgpt_detect();
155 printk(KERN_INFO "geode: %d MFGPT timers available.\n", timers);
152 return 0; 156 return 0;
153} 157}
154 158
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 6c34bdd22e26..8561f626edad 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/head64.c -- prepare to run common code 2 * prepare to run common code
3 * 3 *
4 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE 4 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
5 */ 5 */
diff --git a/arch/x86/kernel/hpet_32.c b/arch/x86/kernel/hpet.c
index 533d4932bc79..f8367074da0d 100644
--- a/arch/x86/kernel/hpet_32.c
+++ b/arch/x86/kernel/hpet.c
@@ -1,5 +1,6 @@
1#include <linux/clocksource.h> 1#include <linux/clocksource.h>
2#include <linux/clockchips.h> 2#include <linux/clockchips.h>
3#include <linux/delay.h>
3#include <linux/errno.h> 4#include <linux/errno.h>
4#include <linux/hpet.h> 5#include <linux/hpet.h>
5#include <linux/init.h> 6#include <linux/init.h>
@@ -7,11 +8,11 @@
7#include <linux/pm.h> 8#include <linux/pm.h>
8#include <linux/delay.h> 9#include <linux/delay.h>
9 10
11#include <asm/fixmap.h>
10#include <asm/hpet.h> 12#include <asm/hpet.h>
13#include <asm/i8253.h>
11#include <asm/io.h> 14#include <asm/io.h>
12 15
13extern struct clock_event_device *global_clock_event;
14
15#define HPET_MASK CLOCKSOURCE_MASK(32) 16#define HPET_MASK CLOCKSOURCE_MASK(32)
16#define HPET_SHIFT 22 17#define HPET_SHIFT 22
17 18
@@ -22,9 +23,9 @@ extern struct clock_event_device *global_clock_event;
22 * 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
23 */ 24 */
24unsigned long hpet_address; 25unsigned long hpet_address;
25static void __iomem * hpet_virt_address; 26static void __iomem *hpet_virt_address;
26 27
27static inline unsigned long hpet_readl(unsigned long a) 28unsigned long hpet_readl(unsigned long a)
28{ 29{
29 return readl(hpet_virt_address + a); 30 return readl(hpet_virt_address + a);
30} 31}
@@ -34,6 +35,36 @@ static inline void hpet_writel(unsigned long d, unsigned long a)
34 writel(d, hpet_virt_address + a); 35 writel(d, hpet_virt_address + a);
35} 36}
36 37
38#ifdef CONFIG_X86_64
39
40#include <asm/pgtable.h>
41
42static inline void hpet_set_mapping(void)
43{
44 set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
45 __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE);
46 hpet_virt_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
47}
48
49static inline void hpet_clear_mapping(void)
50{
51 hpet_virt_address = NULL;
52}
53
54#else
55
56static inline void hpet_set_mapping(void)
57{
58 hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
59}
60
61static inline void hpet_clear_mapping(void)
62{
63 iounmap(hpet_virt_address);
64 hpet_virt_address = NULL;
65}
66#endif
67
37/* 68/*
38 * HPET command line enable / disable 69 * HPET command line enable / disable
39 */ 70 */
@@ -49,6 +80,13 @@ static int __init hpet_setup(char* str)
49} 80}
50__setup("hpet=", hpet_setup); 81__setup("hpet=", hpet_setup);
51 82
83static int __init disable_hpet(char *str)
84{
85 boot_hpet_disable = 1;
86 return 1;
87}
88__setup("nohpet", disable_hpet);
89
52static inline int is_hpet_capable(void) 90static inline int is_hpet_capable(void)
53{ 91{
54 return (!boot_hpet_disable && hpet_address); 92 return (!boot_hpet_disable && hpet_address);
@@ -83,7 +121,7 @@ static void hpet_reserve_platform_timers(unsigned long id)
83 121
84 memset(&hd, 0, sizeof (hd)); 122 memset(&hd, 0, sizeof (hd));
85 hd.hd_phys_address = hpet_address; 123 hd.hd_phys_address = hpet_address;
86 hd.hd_address = hpet_virt_address; 124 hd.hd_address = hpet;
87 hd.hd_nirqs = nrtimers; 125 hd.hd_nirqs = nrtimers;
88 hd.hd_flags = HPET_DATA_PLATFORM; 126 hd.hd_flags = HPET_DATA_PLATFORM;
89 hpet_reserve_timer(&hd, 0); 127 hpet_reserve_timer(&hd, 0);
@@ -111,9 +149,9 @@ static void hpet_reserve_platform_timers(unsigned long id) { }
111 */ 149 */
112static unsigned long hpet_period; 150static unsigned long hpet_period;
113 151
114static void hpet_set_mode(enum clock_event_mode mode, 152static void hpet_legacy_set_mode(enum clock_event_mode mode,
115 struct clock_event_device *evt); 153 struct clock_event_device *evt);
116static int hpet_next_event(unsigned long delta, 154static int hpet_legacy_next_event(unsigned long delta,
117 struct clock_event_device *evt); 155 struct clock_event_device *evt);
118 156
119/* 157/*
@@ -122,10 +160,11 @@ static int hpet_next_event(unsigned long delta,
122static struct clock_event_device hpet_clockevent = { 160static struct clock_event_device hpet_clockevent = {
123 .name = "hpet", 161 .name = "hpet",
124 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 162 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
125 .set_mode = hpet_set_mode, 163 .set_mode = hpet_legacy_set_mode,
126 .set_next_event = hpet_next_event, 164 .set_next_event = hpet_legacy_next_event,
127 .shift = 32, 165 .shift = 32,
128 .irq = 0, 166 .irq = 0,
167 .rating = 50,
129}; 168};
130 169
131static void hpet_start_counter(void) 170static void hpet_start_counter(void)
@@ -140,7 +179,18 @@ static void hpet_start_counter(void)
140 hpet_writel(cfg, HPET_CFG); 179 hpet_writel(cfg, HPET_CFG);
141} 180}
142 181
143static void hpet_enable_int(void) 182static void hpet_resume_device(void)
183{
184 force_hpet_resume();
185}
186
187static void hpet_restart_counter(void)
188{
189 hpet_resume_device();
190 hpet_start_counter();
191}
192
193static void hpet_enable_legacy_int(void)
144{ 194{
145 unsigned long cfg = hpet_readl(HPET_CFG); 195 unsigned long cfg = hpet_readl(HPET_CFG);
146 196
@@ -149,7 +199,39 @@ static void hpet_enable_int(void)
149 hpet_legacy_int_enabled = 1; 199 hpet_legacy_int_enabled = 1;
150} 200}
151 201
152static void hpet_set_mode(enum clock_event_mode mode, 202static void hpet_legacy_clockevent_register(void)
203{
204 uint64_t hpet_freq;
205
206 /* Start HPET legacy interrupts */
207 hpet_enable_legacy_int();
208
209 /*
210 * The period is a femto seconds value. We need to calculate the
211 * scaled math multiplication factor for nanosecond to hpet tick
212 * conversion.
213 */
214 hpet_freq = 1000000000000000ULL;
215 do_div(hpet_freq, hpet_period);
216 hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
217 NSEC_PER_SEC, 32);
218 /* Calculate the min / max delta */
219 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
220 &hpet_clockevent);
221 hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
222 &hpet_clockevent);
223
224 /*
225 * Start hpet with the boot cpu mask and make it
226 * global after the IO_APIC has been initialized.
227 */
228 hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
229 clockevents_register_device(&hpet_clockevent);
230 global_clock_event = &hpet_clockevent;
231 printk(KERN_DEBUG "hpet clockevent registered\n");
232}
233
234static void hpet_legacy_set_mode(enum clock_event_mode mode,
153 struct clock_event_device *evt) 235 struct clock_event_device *evt)
154{ 236{
155 unsigned long cfg, cmp, now; 237 unsigned long cfg, cmp, now;
@@ -190,12 +272,12 @@ static void hpet_set_mode(enum clock_event_mode mode,
190 break; 272 break;
191 273
192 case CLOCK_EVT_MODE_RESUME: 274 case CLOCK_EVT_MODE_RESUME:
193 hpet_enable_int(); 275 hpet_enable_legacy_int();
194 break; 276 break;
195 } 277 }
196} 278}
197 279
198static int hpet_next_event(unsigned long delta, 280static int hpet_legacy_next_event(unsigned long delta,
199 struct clock_event_device *evt) 281 struct clock_event_device *evt)
200{ 282{
201 unsigned long cnt; 283 unsigned long cnt;
@@ -215,6 +297,13 @@ static cycle_t read_hpet(void)
215 return (cycle_t)hpet_readl(HPET_COUNTER); 297 return (cycle_t)hpet_readl(HPET_COUNTER);
216} 298}
217 299
300#ifdef CONFIG_X86_64
301static cycle_t __vsyscall_fn vread_hpet(void)
302{
303 return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
304}
305#endif
306
218static struct clocksource clocksource_hpet = { 307static struct clocksource clocksource_hpet = {
219 .name = "hpet", 308 .name = "hpet",
220 .rating = 250, 309 .rating = 250,
@@ -222,61 +311,17 @@ static struct clocksource clocksource_hpet = {
222 .mask = HPET_MASK, 311 .mask = HPET_MASK,
223 .shift = HPET_SHIFT, 312 .shift = HPET_SHIFT,
224 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 313 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
225 .resume = hpet_start_counter, 314 .resume = hpet_restart_counter,
315#ifdef CONFIG_X86_64
316 .vread = vread_hpet,
317#endif
226}; 318};
227 319
228/* 320static int hpet_clocksource_register(void)
229 * Try to setup the HPET timer
230 */
231int __init hpet_enable(void)
232{ 321{
233 unsigned long id;
234 uint64_t hpet_freq;
235 u64 tmp, start, now; 322 u64 tmp, start, now;
236 cycle_t t1; 323 cycle_t t1;
237 324
238 if (!is_hpet_capable())
239 return 0;
240
241 hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
242
243 /*
244 * Read the period and check for a sane value:
245 */
246 hpet_period = hpet_readl(HPET_PERIOD);
247 if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
248 goto out_nohpet;
249
250 /*
251 * The period is a femto seconds value. We need to calculate the
252 * scaled math multiplication factor for nanosecond to hpet tick
253 * conversion.
254 */
255 hpet_freq = 1000000000000000ULL;
256 do_div(hpet_freq, hpet_period);
257 hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
258 NSEC_PER_SEC, 32);
259 /* Calculate the min / max delta */
260 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
261 &hpet_clockevent);
262 hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
263 &hpet_clockevent);
264
265 /*
266 * Read the HPET ID register to retrieve the IRQ routing
267 * information and the number of channels
268 */
269 id = hpet_readl(HPET_ID);
270
271#ifdef CONFIG_HPET_EMULATE_RTC
272 /*
273 * The legacy routing mode needs at least two channels, tick timer
274 * and the rtc emulation channel.
275 */
276 if (!(id & HPET_ID_NUMBER))
277 goto out_nohpet;
278#endif
279
280 /* Start the counter */ 325 /* Start the counter */
281 hpet_start_counter(); 326 hpet_start_counter();
282 327
@@ -298,7 +343,7 @@ int __init hpet_enable(void)
298 if (t1 == read_hpet()) { 343 if (t1 == read_hpet()) {
299 printk(KERN_WARNING 344 printk(KERN_WARNING
300 "HPET counter not counting. HPET disabled\n"); 345 "HPET counter not counting. HPET disabled\n");
301 goto out_nohpet; 346 return -ENODEV;
302 } 347 }
303 348
304 /* Initialize and register HPET clocksource 349 /* Initialize and register HPET clocksource
@@ -319,27 +364,84 @@ int __init hpet_enable(void)
319 364
320 clocksource_register(&clocksource_hpet); 365 clocksource_register(&clocksource_hpet);
321 366
367 return 0;
368}
369
370/*
371 * Try to setup the HPET timer
372 */
373int __init hpet_enable(void)
374{
375 unsigned long id;
376
377 if (!is_hpet_capable())
378 return 0;
379
380 hpet_set_mapping();
381
382 /*
383 * Read the period and check for a sane value:
384 */
385 hpet_period = hpet_readl(HPET_PERIOD);
386 if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
387 goto out_nohpet;
388
389 /*
390 * Read the HPET ID register to retrieve the IRQ routing
391 * information and the number of channels
392 */
393 id = hpet_readl(HPET_ID);
394
395#ifdef CONFIG_HPET_EMULATE_RTC
396 /*
397 * The legacy routing mode needs at least two channels, tick timer
398 * and the rtc emulation channel.
399 */
400 if (!(id & HPET_ID_NUMBER))
401 goto out_nohpet;
402#endif
403
404 if (hpet_clocksource_register())
405 goto out_nohpet;
406
322 if (id & HPET_ID_LEGSUP) { 407 if (id & HPET_ID_LEGSUP) {
323 hpet_enable_int(); 408 hpet_legacy_clockevent_register();
324 hpet_reserve_platform_timers(id);
325 /*
326 * Start hpet with the boot cpu mask and make it
327 * global after the IO_APIC has been initialized.
328 */
329 hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
330 clockevents_register_device(&hpet_clockevent);
331 global_clock_event = &hpet_clockevent;
332 return 1; 409 return 1;
333 } 410 }
334 return 0; 411 return 0;
335 412
336out_nohpet: 413out_nohpet:
337 iounmap(hpet_virt_address); 414 hpet_clear_mapping();
338 hpet_virt_address = NULL;
339 boot_hpet_disable = 1; 415 boot_hpet_disable = 1;
340 return 0; 416 return 0;
341} 417}
342 418
419/*
420 * Needs to be late, as the reserve_timer code calls kalloc !
421 *
422 * Not a problem on i386 as hpet_enable is called from late_time_init,
423 * but on x86_64 it is necessary !
424 */
425static __init int hpet_late_init(void)
426{
427 if (boot_hpet_disable)
428 return -ENODEV;
429
430 if (!hpet_address) {
431 if (!force_hpet_address)
432 return -ENODEV;
433
434 hpet_address = force_hpet_address;
435 hpet_enable();
436 if (!hpet_virt_address)
437 return -ENODEV;
438 }
439
440 hpet_reserve_platform_timers(hpet_readl(HPET_ID));
441
442 return 0;
443}
444fs_initcall(hpet_late_init);
343 445
344#ifdef CONFIG_HPET_EMULATE_RTC 446#ifdef CONFIG_HPET_EMULATE_RTC
345 447
diff --git a/arch/x86/kernel/hpet_64.c b/arch/x86/kernel/hpet_64.c
deleted file mode 100644
index e2d1b912e154..000000000000
--- a/arch/x86/kernel/hpet_64.c
+++ /dev/null
@@ -1,493 +0,0 @@
1#include <linux/kernel.h>
2#include <linux/sched.h>
3#include <linux/init.h>
4#include <linux/mc146818rtc.h>
5#include <linux/time.h>
6#include <linux/clocksource.h>
7#include <linux/ioport.h>
8#include <linux/acpi.h>
9#include <linux/hpet.h>
10#include <asm/pgtable.h>
11#include <asm/vsyscall.h>
12#include <asm/timex.h>
13#include <asm/hpet.h>
14
15#define HPET_MASK 0xFFFFFFFF
16#define HPET_SHIFT 22
17
18/* FSEC = 10^-15 NSEC = 10^-9 */
19#define FSEC_PER_NSEC 1000000
20
21int nohpet __initdata;
22
23unsigned long hpet_address;
24unsigned long hpet_period; /* fsecs / HPET clock */
25unsigned long hpet_tick; /* HPET clocks / interrupt */
26
27int hpet_use_timer; /* Use counter of hpet for time keeping,
28 * otherwise PIT
29 */
30
31#ifdef CONFIG_HPET
32static __init int late_hpet_init(void)
33{
34 struct hpet_data hd;
35 unsigned int ntimer;
36
37 if (!hpet_address)
38 return 0;
39
40 memset(&hd, 0, sizeof(hd));
41
42 ntimer = hpet_readl(HPET_ID);
43 ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
44 ntimer++;
45
46 /*
47 * Register with driver.
48 * Timer0 and Timer1 is used by platform.
49 */
50 hd.hd_phys_address = hpet_address;
51 hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
52 hd.hd_nirqs = ntimer;
53 hd.hd_flags = HPET_DATA_PLATFORM;
54 hpet_reserve_timer(&hd, 0);
55#ifdef CONFIG_HPET_EMULATE_RTC
56 hpet_reserve_timer(&hd, 1);
57#endif
58 hd.hd_irq[0] = HPET_LEGACY_8254;
59 hd.hd_irq[1] = HPET_LEGACY_RTC;
60 if (ntimer > 2) {
61 struct hpet *hpet;
62 struct hpet_timer *timer;
63 int i;
64
65 hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
66 timer = &hpet->hpet_timers[2];
67 for (i = 2; i < ntimer; timer++, i++)
68 hd.hd_irq[i] = (timer->hpet_config &
69 Tn_INT_ROUTE_CNF_MASK) >>
70 Tn_INT_ROUTE_CNF_SHIFT;
71
72 }
73
74 hpet_alloc(&hd);
75 return 0;
76}
77fs_initcall(late_hpet_init);
78#endif
79
80int hpet_timer_stop_set_go(unsigned long tick)
81{
82 unsigned int cfg;
83
84/*
85 * Stop the timers and reset the main counter.
86 */
87
88 cfg = hpet_readl(HPET_CFG);
89 cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
90 hpet_writel(cfg, HPET_CFG);
91 hpet_writel(0, HPET_COUNTER);
92 hpet_writel(0, HPET_COUNTER + 4);
93
94/*
95 * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
96 * and period also hpet_tick.
97 */
98 if (hpet_use_timer) {
99 hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
100 HPET_TN_32BIT, HPET_T0_CFG);
101 hpet_writel(hpet_tick, HPET_T0_CMP); /* next interrupt */
102 hpet_writel(hpet_tick, HPET_T0_CMP); /* period */
103 cfg |= HPET_CFG_LEGACY;
104 }
105/*
106 * Go!
107 */
108
109 cfg |= HPET_CFG_ENABLE;
110 hpet_writel(cfg, HPET_CFG);
111
112 return 0;
113}
114
115static cycle_t read_hpet(void)
116{
117 return (cycle_t)hpet_readl(HPET_COUNTER);
118}
119
120static cycle_t __vsyscall_fn vread_hpet(void)
121{
122 return readl((void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
123}
124
125struct clocksource clocksource_hpet = {
126 .name = "hpet",
127 .rating = 250,
128 .read = read_hpet,
129 .mask = (cycle_t)HPET_MASK,
130 .mult = 0, /* set below */
131 .shift = HPET_SHIFT,
132 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
133 .vread = vread_hpet,
134};
135
136int __init hpet_arch_init(void)
137{
138 unsigned int id;
139 u64 tmp;
140
141 if (!hpet_address)
142 return -1;
143 set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
144 __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE);
145
146/*
147 * Read the period, compute tick and quotient.
148 */
149
150 id = hpet_readl(HPET_ID);
151
152 if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
153 return -1;
154
155 hpet_period = hpet_readl(HPET_PERIOD);
156 if (hpet_period < 100000 || hpet_period > 100000000)
157 return -1;
158
159 hpet_tick = (FSEC_PER_TICK + hpet_period / 2) / hpet_period;
160
161 hpet_use_timer = (id & HPET_ID_LEGSUP);
162
163 /*
164 * hpet period is in femto seconds per cycle
165 * so we need to convert this to ns/cyc units
166 * aproximated by mult/2^shift
167 *
168 * fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
169 * fsec/cyc * 1ns/1000000fsec * 2^shift = mult
170 * fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
171 * (fsec/cyc << shift)/1000000 = mult
172 * (hpet_period << shift)/FSEC_PER_NSEC = mult
173 */
174 tmp = (u64)hpet_period << HPET_SHIFT;
175 do_div(tmp, FSEC_PER_NSEC);
176 clocksource_hpet.mult = (u32)tmp;
177 clocksource_register(&clocksource_hpet);
178
179 return hpet_timer_stop_set_go(hpet_tick);
180}
181
182int hpet_reenable(void)
183{
184 return hpet_timer_stop_set_go(hpet_tick);
185}
186
187/*
188 * calibrate_tsc() calibrates the processor TSC in a very simple way, comparing
189 * it to the HPET timer of known frequency.
190 */
191
192#define TICK_COUNT 100000000
193#define SMI_THRESHOLD 50000
194#define MAX_TRIES 5
195
196/*
197 * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none
198 * occurs between the reads of the hpet & TSC.
199 */
200static void __init read_hpet_tsc(int *hpet, int *tsc)
201{
202 int tsc1, tsc2, hpet1, i;
203
204 for (i = 0; i < MAX_TRIES; i++) {
205 tsc1 = get_cycles_sync();
206 hpet1 = hpet_readl(HPET_COUNTER);
207 tsc2 = get_cycles_sync();
208 if ((tsc2 - tsc1) < SMI_THRESHOLD)
209 break;
210 }
211 *hpet = hpet1;
212 *tsc = tsc2;
213}
214
215unsigned int __init hpet_calibrate_tsc(void)
216{
217 int tsc_start, hpet_start;
218 int tsc_now, hpet_now;
219 unsigned long flags;
220
221 local_irq_save(flags);
222
223 read_hpet_tsc(&hpet_start, &tsc_start);
224
225 do {
226 local_irq_disable();
227 read_hpet_tsc(&hpet_now, &tsc_now);
228 local_irq_restore(flags);
229 } while ((tsc_now - tsc_start) < TICK_COUNT &&
230 (hpet_now - hpet_start) < TICK_COUNT);
231
232 return (tsc_now - tsc_start) * 1000000000L
233 / ((hpet_now - hpet_start) * hpet_period / 1000);
234}
235
236#ifdef CONFIG_HPET_EMULATE_RTC
237/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
238 * is enabled, we support RTC interrupt functionality in software.
239 * RTC has 3 kinds of interrupts:
240 * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
241 * is updated
242 * 2) Alarm Interrupt - generate an interrupt at a specific time of day
243 * 3) Periodic Interrupt - generate periodic interrupt, with frequencies
244 * 2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
245 * (1) and (2) above are implemented using polling at a frequency of
246 * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
247 * overhead. (DEFAULT_RTC_INT_FREQ)
248 * For (3), we use interrupts at 64Hz or user specified periodic
249 * frequency, whichever is higher.
250 */
251#include <linux/rtc.h>
252
253#define DEFAULT_RTC_INT_FREQ 64
254#define RTC_NUM_INTS 1
255
256static unsigned long UIE_on;
257static unsigned long prev_update_sec;
258
259static unsigned long AIE_on;
260static struct rtc_time alarm_time;
261
262static unsigned long PIE_on;
263static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
264static unsigned long PIE_count;
265
266static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
267static unsigned int hpet_t1_cmp; /* cached comparator register */
268
269int is_hpet_enabled(void)
270{
271 return hpet_address != 0;
272}
273
274/*
275 * Timer 1 for RTC, we do not use periodic interrupt feature,
276 * even if HPET supports periodic interrupts on Timer 1.
277 * The reason being, to set up a periodic interrupt in HPET, we need to
278 * stop the main counter. And if we do that everytime someone diables/enables
279 * RTC, we will have adverse effect on main kernel timer running on Timer 0.
280 * So, for the time being, simulate the periodic interrupt in software.
281 *
282 * hpet_rtc_timer_init() is called for the first time and during subsequent
283 * interuppts reinit happens through hpet_rtc_timer_reinit().
284 */
285int hpet_rtc_timer_init(void)
286{
287 unsigned int cfg, cnt;
288 unsigned long flags;
289
290 if (!is_hpet_enabled())
291 return 0;
292 /*
293 * Set the counter 1 and enable the interrupts.
294 */
295 if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
296 hpet_rtc_int_freq = PIE_freq;
297 else
298 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
299
300 local_irq_save(flags);
301
302 cnt = hpet_readl(HPET_COUNTER);
303 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
304 hpet_writel(cnt, HPET_T1_CMP);
305 hpet_t1_cmp = cnt;
306
307 cfg = hpet_readl(HPET_T1_CFG);
308 cfg &= ~HPET_TN_PERIODIC;
309 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
310 hpet_writel(cfg, HPET_T1_CFG);
311
312 local_irq_restore(flags);
313
314 return 1;
315}
316
317static void hpet_rtc_timer_reinit(void)
318{
319 unsigned int cfg, cnt, ticks_per_int, lost_ints;
320
321 if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
322 cfg = hpet_readl(HPET_T1_CFG);
323 cfg &= ~HPET_TN_ENABLE;
324 hpet_writel(cfg, HPET_T1_CFG);
325 return;
326 }
327
328 if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
329 hpet_rtc_int_freq = PIE_freq;
330 else
331 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
332
333 /* It is more accurate to use the comparator value than current count.*/
334 ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq;
335 hpet_t1_cmp += ticks_per_int;
336 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
337
338 /*
339 * If the interrupt handler was delayed too long, the write above tries
340 * to schedule the next interrupt in the past and the hardware would
341 * not interrupt until the counter had wrapped around.
342 * So we have to check that the comparator wasn't set to a past time.
343 */
344 cnt = hpet_readl(HPET_COUNTER);
345 if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) {
346 lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1;
347 /* Make sure that, even with the time needed to execute
348 * this code, the next scheduled interrupt has been moved
349 * back to the future: */
350 lost_ints++;
351
352 hpet_t1_cmp += lost_ints * ticks_per_int;
353 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
354
355 if (PIE_on)
356 PIE_count += lost_ints;
357
358 if (printk_ratelimit())
359 printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n",
360 hpet_rtc_int_freq);
361 }
362}
363
364/*
365 * The functions below are called from rtc driver.
366 * Return 0 if HPET is not being used.
367 * Otherwise do the necessary changes and return 1.
368 */
369int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
370{
371 if (!is_hpet_enabled())
372 return 0;
373
374 if (bit_mask & RTC_UIE)
375 UIE_on = 0;
376 if (bit_mask & RTC_PIE)
377 PIE_on = 0;
378 if (bit_mask & RTC_AIE)
379 AIE_on = 0;
380
381 return 1;
382}
383
384int hpet_set_rtc_irq_bit(unsigned long bit_mask)
385{
386 int timer_init_reqd = 0;
387
388 if (!is_hpet_enabled())
389 return 0;
390
391 if (!(PIE_on | AIE_on | UIE_on))
392 timer_init_reqd = 1;
393
394 if (bit_mask & RTC_UIE) {
395 UIE_on = 1;
396 }
397 if (bit_mask & RTC_PIE) {
398 PIE_on = 1;
399 PIE_count = 0;
400 }
401 if (bit_mask & RTC_AIE) {
402 AIE_on = 1;
403 }
404
405 if (timer_init_reqd)
406 hpet_rtc_timer_init();
407
408 return 1;
409}
410
411int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
412{
413 if (!is_hpet_enabled())
414 return 0;
415
416 alarm_time.tm_hour = hrs;
417 alarm_time.tm_min = min;
418 alarm_time.tm_sec = sec;
419
420 return 1;
421}
422
423int hpet_set_periodic_freq(unsigned long freq)
424{
425 if (!is_hpet_enabled())
426 return 0;
427
428 PIE_freq = freq;
429 PIE_count = 0;
430
431 return 1;
432}
433
434int hpet_rtc_dropped_irq(void)
435{
436 if (!is_hpet_enabled())
437 return 0;
438
439 return 1;
440}
441
442irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
443{
444 struct rtc_time curr_time;
445 unsigned long rtc_int_flag = 0;
446 int call_rtc_interrupt = 0;
447
448 hpet_rtc_timer_reinit();
449
450 if (UIE_on | AIE_on) {
451 rtc_get_rtc_time(&curr_time);
452 }
453 if (UIE_on) {
454 if (curr_time.tm_sec != prev_update_sec) {
455 /* Set update int info, call real rtc int routine */
456 call_rtc_interrupt = 1;
457 rtc_int_flag = RTC_UF;
458 prev_update_sec = curr_time.tm_sec;
459 }
460 }
461 if (PIE_on) {
462 PIE_count++;
463 if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
464 /* Set periodic int info, call real rtc int routine */
465 call_rtc_interrupt = 1;
466 rtc_int_flag |= RTC_PF;
467 PIE_count = 0;
468 }
469 }
470 if (AIE_on) {
471 if ((curr_time.tm_sec == alarm_time.tm_sec) &&
472 (curr_time.tm_min == alarm_time.tm_min) &&
473 (curr_time.tm_hour == alarm_time.tm_hour)) {
474 /* Set alarm int info, call real rtc int routine */
475 call_rtc_interrupt = 1;
476 rtc_int_flag |= RTC_AF;
477 }
478 }
479 if (call_rtc_interrupt) {
480 rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
481 rtc_interrupt(rtc_int_flag, dev_id);
482 }
483 return IRQ_HANDLED;
484}
485#endif
486
487static int __init nohpet_setup(char *s)
488{
489 nohpet = 1;
490 return 1;
491}
492
493__setup("nohpet", nohpet_setup);
diff --git a/arch/x86/kernel/i387_32.c b/arch/x86/kernel/i387_32.c
index 665847281ed2..7d2e12f6c78b 100644
--- a/arch/x86/kernel/i387_32.c
+++ b/arch/x86/kernel/i387_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/i387.c
3 *
4 * Copyright (C) 1994 Linus Torvalds 2 * Copyright (C) 1994 Linus Torvalds
5 * 3 *
6 * Pentium III FXSR, SSE support 4 * Pentium III FXSR, SSE support
diff --git a/arch/x86/kernel/i387_64.c b/arch/x86/kernel/i387_64.c
index 1d58c13bc6bc..56c1f1147109 100644
--- a/arch/x86/kernel/i387_64.c
+++ b/arch/x86/kernel/i387_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/i387.c
3 *
4 * Copyright (C) 1994 Linus Torvalds 2 * Copyright (C) 1994 Linus Torvalds
5 * Copyright (C) 2002 Andi Kleen, SuSE Labs 3 * Copyright (C) 2002 Andi Kleen, SuSE Labs
6 * 4 *
diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c
index 6f508e8d7c57..29313832df0c 100644
--- a/arch/x86/kernel/i8237.c
+++ b/arch/x86/kernel/i8237.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * i8237.c: 8237A DMA controller suspend functions. 2 * 8237A DMA controller suspend functions.
3 * 3 *
4 * Written by Pierre Ossman, 2005. 4 * Written by Pierre Ossman, 2005.
5 * 5 *
diff --git a/arch/x86/kernel/i8253_32.c b/arch/x86/kernel/i8253.c
index 6d839f2f1b1a..5cc8841ca2c6 100644
--- a/arch/x86/kernel/i8253_32.c
+++ b/arch/x86/kernel/i8253.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * i8253.c 8253/PIT functions 2 * 8253/PIT functions
3 * 3 *
4 */ 4 */
5#include <linux/clockchips.h> 5#include <linux/clockchips.h>
@@ -13,7 +13,6 @@
13#include <asm/delay.h> 13#include <asm/delay.h>
14#include <asm/i8253.h> 14#include <asm/i8253.h>
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/timer.h>
17 16
18DEFINE_SPINLOCK(i8253_lock); 17DEFINE_SPINLOCK(i8253_lock);
19EXPORT_SYMBOL(i8253_lock); 18EXPORT_SYMBOL(i8253_lock);
@@ -120,6 +119,7 @@ void __init setup_pit_timer(void)
120 global_clock_event = &pit_clockevent; 119 global_clock_event = &pit_clockevent;
121} 120}
122 121
122#ifndef CONFIG_X86_64
123/* 123/*
124 * Since the PIT overflows every tick, its not very useful 124 * Since the PIT overflows every tick, its not very useful
125 * to just read by itself. So use jiffies to emulate a free 125 * to just read by itself. So use jiffies to emulate a free
@@ -204,3 +204,5 @@ static int __init init_pit_clocksource(void)
204 return clocksource_register(&clocksource_pit); 204 return clocksource_register(&clocksource_pit);
205} 205}
206arch_initcall(init_pit_clocksource); 206arch_initcall(init_pit_clocksource);
207
208#endif
diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
index 0499cbe9871a..679bb33acbf1 100644
--- a/arch/x86/kernel/i8259_32.c
+++ b/arch/x86/kernel/i8259_32.c
@@ -10,7 +10,6 @@
10#include <linux/sysdev.h> 10#include <linux/sysdev.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12 12
13#include <asm/8253pit.h>
14#include <asm/atomic.h> 13#include <asm/atomic.h>
15#include <asm/system.h> 14#include <asm/system.h>
16#include <asm/io.h> 15#include <asm/io.h>
diff --git a/arch/x86/kernel/i8259_64.c b/arch/x86/kernel/i8259_64.c
index 948cae646099..eb72976cc13c 100644
--- a/arch/x86/kernel/i8259_64.c
+++ b/arch/x86/kernel/i8259_64.c
@@ -444,46 +444,6 @@ void __init init_ISA_irqs (void)
444 } 444 }
445} 445}
446 446
447static void setup_timer_hardware(void)
448{
449 outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
450 udelay(10);
451 outb_p(LATCH & 0xff , 0x40); /* LSB */
452 udelay(10);
453 outb(LATCH >> 8 , 0x40); /* MSB */
454}
455
456static int timer_resume(struct sys_device *dev)
457{
458 setup_timer_hardware();
459 return 0;
460}
461
462void i8254_timer_resume(void)
463{
464 setup_timer_hardware();
465}
466
467static struct sysdev_class timer_sysclass = {
468 set_kset_name("timer_pit"),
469 .resume = timer_resume,
470};
471
472static struct sys_device device_timer = {
473 .id = 0,
474 .cls = &timer_sysclass,
475};
476
477static int __init init_timer_sysfs(void)
478{
479 int error = sysdev_class_register(&timer_sysclass);
480 if (!error)
481 error = sysdev_register(&device_timer);
482 return error;
483}
484
485device_initcall(init_timer_sysfs);
486
487void __init init_IRQ(void) 447void __init init_IRQ(void)
488{ 448{
489 int i; 449 int i;
@@ -533,12 +493,6 @@ void __init init_IRQ(void)
533 set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); 493 set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
534 set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); 494 set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
535 495
536 /*
537 * Set the clock to HZ Hz, we already have a valid
538 * vector now:
539 */
540 setup_timer_hardware();
541
542 if (!acpi_ioapic) 496 if (!acpi_ioapic)
543 setup_irq(2, &irq2); 497 setup_irq(2, &irq2);
544} 498}
diff --git a/arch/x86/kernel/ioport_32.c b/arch/x86/kernel/ioport_32.c
index 3d310a946d76..4ed48dc8df1e 100644
--- a/arch/x86/kernel/ioport_32.c
+++ b/arch/x86/kernel/ioport_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/ioport.c
3 *
4 * This contains the io-permission bitmap code - written by obz, with changes 2 * This contains the io-permission bitmap code - written by obz, with changes
5 * by Linus. 3 * by Linus.
6 */ 4 */
diff --git a/arch/x86/kernel/ioport_64.c b/arch/x86/kernel/ioport_64.c
index 653efa30b0f4..5f62fad64dab 100644
--- a/arch/x86/kernel/ioport_64.c
+++ b/arch/x86/kernel/ioport_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/ioport.c
3 *
4 * This contains the io-permission bitmap code - written by obz, with changes 2 * This contains the io-permission bitmap code - written by obz, with changes
5 * by Linus. 3 * by Linus.
6 */ 4 */
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 4f681bcdb1fc..e173b763f148 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/irq.c
3 *
4 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 2 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
5 * 3 *
6 * This file contains the lowest level x86-specific interrupt 4 * This file contains the lowest level x86-specific interrupt
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index bd11e42b22bf..865669efc540 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/irq.c
3 *
4 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 2 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
5 * 3 *
6 * This file contains the lowest level x86_64-specific interrupt 4 * This file contains the lowest level x86_64-specific interrupt
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index 448a50b1324c..c2d03e96ae9f 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Kernel Probes (KProbes) 2 * Kernel Probes (KProbes)
3 * arch/i386/kernel/kprobes.c
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index a30e004682e2..1df17a0ec0c9 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Kernel Probes (KProbes) 2 * Kernel Probes (KProbes)
3 * arch/x86_64/kernel/kprobes.c
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
diff --git a/arch/x86/kernel/ldt_32.c b/arch/x86/kernel/ldt_32.c
index e0b2d17f4f10..a8b18421863a 100644
--- a/arch/x86/kernel/ldt_32.c
+++ b/arch/x86/kernel/ldt_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/ldt.c
3 *
4 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds 2 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
5 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> 3 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
6 */ 4 */
diff --git a/arch/x86/kernel/ldt_64.c b/arch/x86/kernel/ldt_64.c
index bc9ffd5c19cc..3796523d616a 100644
--- a/arch/x86/kernel/ldt_64.c
+++ b/arch/x86/kernel/ldt_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/ldt.c
3 *
4 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds 2 * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
5 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> 3 * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
6 * Copyright (C) 2002 Andi Kleen 4 * Copyright (C) 2002 Andi Kleen
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 91966bafb3dc..deda9a221cf2 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel 2 * handle transition of Linux booting another kernel
3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> 3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
4 * 4 *
5 * This source code is licensed under the GNU General Public License, 5 * This source code is licensed under the GNU General Public License,
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index c3a554703672..cd1899a2f0c5 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel 2 * handle transition of Linux booting another kernel
3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> 3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
4 * 4 *
5 * This source code is licensed under the GNU General Public License, 5 * This source code is licensed under the GNU General Public License,
diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c
index b83672b89527..9482033ed0fe 100644
--- a/arch/x86/kernel/mca_32.c
+++ b/arch/x86/kernel/mca_32.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/mca.c
3 * Written by Martin Kolinek, February 1996 2 * Written by Martin Kolinek, February 1996
4 * 3 *
5 * Changes: 4 * Changes:
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c
new file mode 100644
index 000000000000..0ab680f2d9db
--- /dev/null
+++ b/arch/x86/kernel/mfgpt_32.c
@@ -0,0 +1,362 @@
1/*
2 * Driver/API for AMD Geode Multi-Function General Purpose Timers (MFGPT)
3 *
4 * Copyright (C) 2006, Advanced Micro Devices, Inc.
5 * Copyright (C) 2007, Andres Salomon <dilinger@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU General Public License
9 * as published by the Free Software Foundation.
10 *
11 * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
12 */
13
14/*
15 * We are using the 32Khz input clock - its the only one that has the
16 * ranges we find desirable. The following table lists the suitable
17 * divisors and the associated hz, minimum interval
18 * and the maximum interval:
19 *
20 * Divisor Hz Min Delta (S) Max Delta (S)
21 * 1 32000 .0005 2.048
22 * 2 16000 .001 4.096
23 * 4 8000 .002 8.192
24 * 8 4000 .004 16.384
25 * 16 2000 .008 32.768
26 * 32 1000 .016 65.536
27 * 64 500 .032 131.072
28 * 128 250 .064 262.144
29 * 256 125 .128 524.288
30 */
31
32#include <linux/kernel.h>
33#include <linux/interrupt.h>
34#include <linux/module.h>
35#include <asm/geode.h>
36
37#define F_AVAIL 0x01
38
39static struct mfgpt_timer_t {
40 int flags;
41 struct module *owner;
42} mfgpt_timers[MFGPT_MAX_TIMERS];
43
44/* Selected from the table above */
45
46#define MFGPT_DIVISOR 16
47#define MFGPT_SCALE 4 /* divisor = 2^(scale) */
48#define MFGPT_HZ (32000 / MFGPT_DIVISOR)
49#define MFGPT_PERIODIC (MFGPT_HZ / HZ)
50
51#ifdef CONFIG_GEODE_MFGPT_TIMER
52static int __init mfgpt_timer_setup(void);
53#else
54#define mfgpt_timer_setup() (0)
55#endif
56
57/* Allow for disabling of MFGPTs */
58static int disable;
59static int __init mfgpt_disable(char *s)
60{
61 disable = 1;
62 return 1;
63}
64__setup("nomfgpt", mfgpt_disable);
65
66/*
67 * Check whether any MFGPTs are available for the kernel to use. In most
68 * cases, firmware that uses AMD's VSA code will claim all timers during
69 * bootup; we certainly don't want to take them if they're already in use.
70 * In other cases (such as with VSAless OpenFirmware), the system firmware
71 * leaves timers available for us to use.
72 */
73int __init geode_mfgpt_detect(void)
74{
75 int count = 0, i;
76 u16 val;
77
78 if (disable) {
79 printk(KERN_INFO "geode-mfgpt: Skipping MFGPT setup\n");
80 return 0;
81 }
82
83 for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
84 val = geode_mfgpt_read(i, MFGPT_REG_SETUP);
85 if (!(val & MFGPT_SETUP_SETUP)) {
86 mfgpt_timers[i].flags = F_AVAIL;
87 count++;
88 }
89 }
90
91 /* set up clock event device, if desired */
92 i = mfgpt_timer_setup();
93
94 return count;
95}
96
97int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable)
98{
99 u32 msr, mask, value, dummy;
100 int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
101
102 if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
103 return -EIO;
104
105 /*
106 * The register maps for these are described in sections 6.17.1.x of
107 * the AMD Geode CS5536 Companion Device Data Book.
108 */
109 switch (event) {
110 case MFGPT_EVENT_RESET:
111 /*
112 * XXX: According to the docs, we cannot reset timers above
113 * 6; that is, resets for 7 and 8 will be ignored. Is this
114 * a problem? -dilinger
115 */
116 msr = MFGPT_NR_MSR;
117 mask = 1 << (timer + 24);
118 break;
119
120 case MFGPT_EVENT_NMI:
121 msr = MFGPT_NR_MSR;
122 mask = 1 << (timer + shift);
123 break;
124
125 case MFGPT_EVENT_IRQ:
126 msr = MFGPT_IRQ_MSR;
127 mask = 1 << (timer + shift);
128 break;
129
130 default:
131 return -EIO;
132 }
133
134 rdmsr(msr, value, dummy);
135
136 if (enable)
137 value |= mask;
138 else
139 value &= ~mask;
140
141 wrmsr(msr, value, dummy);
142 return 0;
143}
144
145int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable)
146{
147 u32 val, dummy;
148 int offset;
149
150 if (timer < 0 || timer >= MFGPT_MAX_TIMERS)
151 return -EIO;
152
153 if (geode_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
154 return -EIO;
155
156 rdmsr(MSR_PIC_ZSEL_LOW, val, dummy);
157
158 offset = (timer % 4) * 4;
159
160 val &= ~((0xF << offset) | (0xF << (offset + 16)));
161
162 if (enable) {
163 val |= (irq & 0x0F) << (offset);
164 val |= (irq & 0x0F) << (offset + 16);
165 }
166
167 wrmsr(MSR_PIC_ZSEL_LOW, val, dummy);
168 return 0;
169}
170
171static int mfgpt_get(int timer, struct module *owner)
172{
173 mfgpt_timers[timer].flags &= ~F_AVAIL;
174 mfgpt_timers[timer].owner = owner;
175 printk(KERN_INFO "geode-mfgpt: Registered timer %d\n", timer);
176 return timer;
177}
178
179int geode_mfgpt_alloc_timer(int timer, int domain, struct module *owner)
180{
181 int i;
182
183 if (!geode_get_dev_base(GEODE_DEV_MFGPT))
184 return -ENODEV;
185 if (timer >= MFGPT_MAX_TIMERS)
186 return -EIO;
187
188 if (timer < 0) {
189 /* Try to find an available timer */
190 for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
191 if (mfgpt_timers[i].flags & F_AVAIL)
192 return mfgpt_get(i, owner);
193
194 if (i == 5 && domain == MFGPT_DOMAIN_WORKING)
195 break;
196 }
197 } else {
198 /* If they requested a specific timer, try to honor that */
199 if (mfgpt_timers[timer].flags & F_AVAIL)
200 return mfgpt_get(timer, owner);
201 }
202
203 /* No timers available - too bad */
204 return -1;
205}
206
207
208#ifdef CONFIG_GEODE_MFGPT_TIMER
209
210/*
211 * The MFPGT timers on the CS5536 provide us with suitable timers to use
212 * as clock event sources - not as good as a HPET or APIC, but certainly
213 * better then the PIT. This isn't a general purpose MFGPT driver, but
214 * a simplified one designed specifically to act as a clock event source.
215 * For full details about the MFGPT, please consult the CS5536 data sheet.
216 */
217
218#include <linux/clocksource.h>
219#include <linux/clockchips.h>
220
221static unsigned int mfgpt_tick_mode = CLOCK_EVT_MODE_SHUTDOWN;
222static u16 mfgpt_event_clock;
223
224static int irq = 7;
225static int __init mfgpt_setup(char *str)
226{
227 get_option(&str, &irq);
228 return 1;
229}
230__setup("mfgpt_irq=", mfgpt_setup);
231
232static inline void mfgpt_disable_timer(u16 clock)
233{
234 u16 val = geode_mfgpt_read(clock, MFGPT_REG_SETUP);
235 geode_mfgpt_write(clock, MFGPT_REG_SETUP, val & ~MFGPT_SETUP_CNTEN);
236}
237
238static int mfgpt_next_event(unsigned long, struct clock_event_device *);
239static void mfgpt_set_mode(enum clock_event_mode, struct clock_event_device *);
240
241static struct clock_event_device mfgpt_clockevent = {
242 .name = "mfgpt-timer",
243 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
244 .set_mode = mfgpt_set_mode,
245 .set_next_event = mfgpt_next_event,
246 .rating = 250,
247 .cpumask = CPU_MASK_ALL,
248 .shift = 32
249};
250
251static inline void mfgpt_start_timer(u16 clock, u16 delta)
252{
253 geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_CMP2, (u16) delta);
254 geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
255
256 geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
257 MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
258}
259
260static void mfgpt_set_mode(enum clock_event_mode mode,
261 struct clock_event_device *evt)
262{
263 mfgpt_disable_timer(mfgpt_event_clock);
264
265 if (mode == CLOCK_EVT_MODE_PERIODIC)
266 mfgpt_start_timer(mfgpt_event_clock, MFGPT_PERIODIC);
267
268 mfgpt_tick_mode = mode;
269}
270
271static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt)
272{
273 mfgpt_start_timer(mfgpt_event_clock, delta);
274 return 0;
275}
276
277/* Assume (foolishly?), that this interrupt was due to our tick */
278
279static irqreturn_t mfgpt_tick(int irq, void *dev_id)
280{
281 if (mfgpt_tick_mode == CLOCK_EVT_MODE_SHUTDOWN)
282 return IRQ_HANDLED;
283
284 /* Turn off the clock */
285 mfgpt_disable_timer(mfgpt_event_clock);
286
287 /* Clear the counter */
288 geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_COUNTER, 0);
289
290 /* Restart the clock in periodic mode */
291
292 if (mfgpt_tick_mode == CLOCK_EVT_MODE_PERIODIC) {
293 geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP,
294 MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2);
295 }
296
297 mfgpt_clockevent.event_handler(&mfgpt_clockevent);
298 return IRQ_HANDLED;
299}
300
301static struct irqaction mfgptirq = {
302 .handler = mfgpt_tick,
303 .flags = IRQF_DISABLED | IRQF_NOBALANCING,
304 .mask = CPU_MASK_NONE,
305 .name = "mfgpt-timer"
306};
307
308static int __init mfgpt_timer_setup(void)
309{
310 int timer, ret;
311 u16 val;
312
313 timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING,
314 THIS_MODULE);
315 if (timer < 0) {
316 printk(KERN_ERR
317 "mfgpt-timer: Could not allocate a MFPGT timer\n");
318 return -ENODEV;
319 }
320
321 mfgpt_event_clock = timer;
322 /* Set the clock scale and enable the event mode for CMP2 */
323 val = MFGPT_SCALE | (3 << 8);
324
325 geode_mfgpt_write(mfgpt_event_clock, MFGPT_REG_SETUP, val);
326
327 /* Set up the IRQ on the MFGPT side */
328 if (geode_mfgpt_setup_irq(mfgpt_event_clock, MFGPT_CMP2, irq)) {
329 printk(KERN_ERR "mfgpt-timer: Could not set up IRQ %d\n", irq);
330 return -EIO;
331 }
332
333 /* And register it with the kernel */
334 ret = setup_irq(irq, &mfgptirq);
335
336 if (ret) {
337 printk(KERN_ERR
338 "mfgpt-timer: Unable to set up the interrupt.\n");
339 goto err;
340 }
341
342 /* Set up the clock event */
343 mfgpt_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, 32);
344 mfgpt_clockevent.min_delta_ns = clockevent_delta2ns(0xF,
345 &mfgpt_clockevent);
346 mfgpt_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE,
347 &mfgpt_clockevent);
348
349 printk(KERN_INFO
350 "mfgpt-timer: registering the MFGT timer as a clock event.\n");
351 clockevents_register_device(&mfgpt_clockevent);
352
353 return 0;
354
355err:
356 geode_mfgpt_release_irq(mfgpt_event_clock, MFGPT_CMP2, irq);
357 printk(KERN_ERR
358 "mfgpt-timer: Unable to set up the MFGPT clock source\n");
359 return -EIO;
360}
361
362#endif
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 0c1069b8d638..c044de310b69 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -11,8 +11,6 @@
11 * ----------------------------------------------------------------------- */ 11 * ----------------------------------------------------------------------- */
12 12
13/* 13/*
14 * msr.c
15 *
16 * x86 MSR access device 14 * x86 MSR access device
17 * 15 *
18 * This device is accessed by lseek() to the appropriate register number 16 * This device is accessed by lseek() to the appropriate register number
diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c
index c7227e2180f8..f803ed0ed1c4 100644
--- a/arch/x86/kernel/nmi_32.c
+++ b/arch/x86/kernel/nmi_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/nmi.c
3 *
4 * NMI watchdog support on APIC systems 2 * NMI watchdog support on APIC systems
5 * 3 *
6 * Started by Ingo Molnar <mingo@redhat.com> 4 * Started by Ingo Molnar <mingo@redhat.com>
@@ -353,7 +351,8 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
353 * Take the local apic timer and PIT/HPET into account. We don't 351 * Take the local apic timer and PIT/HPET into account. We don't
354 * know which one is active, when we have highres/dyntick on 352 * know which one is active, when we have highres/dyntick on
355 */ 353 */
356 sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_cpu(cpu).irqs[0]; 354 sum = per_cpu(irq_stat, cpu).apic_timer_irqs +
355 per_cpu(irq_stat, cpu).irq0_irqs;
357 356
358 /* if the none of the timers isn't firing, this cpu isn't doing much */ 357 /* if the none of the timers isn't firing, this cpu isn't doing much */
359 if (!touched && last_irq_sums[cpu] == sum) { 358 if (!touched && last_irq_sums[cpu] == sum) {
diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c
index 0ec6d2ddb931..a576fd740062 100644
--- a/arch/x86/kernel/nmi_64.c
+++ b/arch/x86/kernel/nmi_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/nmi.c
3 *
4 * NMI watchdog support on APIC systems 2 * NMI watchdog support on APIC systems
5 * 3 *
6 * Started by Ingo Molnar <mingo@redhat.com> 4 * Started by Ingo Molnar <mingo@redhat.com>
@@ -329,7 +327,7 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
329 touched = 1; 327 touched = 1;
330 } 328 }
331 329
332 sum = read_pda(apic_timer_irqs); 330 sum = read_pda(apic_timer_irqs) + read_pda(irq0_irqs);
333 if (__get_cpu_var(nmi_touch)) { 331 if (__get_cpu_var(nmi_touch)) {
334 __get_cpu_var(nmi_touch) = 0; 332 __get_cpu_var(nmi_touch) = 0;
335 touched = 1; 333 touched = 1;
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 048f09b62553..0aae2f3847a5 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -63,7 +63,8 @@ void dma_free_coherent(struct device *dev, size_t size,
63{ 63{
64 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; 64 struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
65 int order = get_order(size); 65 int order = get_order(size);
66 66
67 WARN_ON(irqs_disabled()); /* for portability */
67 if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { 68 if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
68 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; 69 int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
69 70
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c
index 29711445c818..9576a2eb375e 100644
--- a/arch/x86/kernel/pci-dma_64.c
+++ b/arch/x86/kernel/pci-dma_64.c
@@ -167,6 +167,7 @@ EXPORT_SYMBOL(dma_alloc_coherent);
167void dma_free_coherent(struct device *dev, size_t size, 167void dma_free_coherent(struct device *dev, size_t size,
168 void *vaddr, dma_addr_t bus) 168 void *vaddr, dma_addr_t bus)
169{ 169{
170 WARN_ON(irqs_disabled()); /* for portability */
170 if (dma_ops->unmap_single) 171 if (dma_ops->unmap_single)
171 dma_ops->unmap_single(dev, bus, size, 0); 172 dma_ops->unmap_single(dev, bus, size, 0);
172 free_pages((unsigned long)vaddr, get_order(size)); 173 free_pages((unsigned long)vaddr, get_order(size));
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 84664710b784..097aeafce5ff 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/process.c
3 *
4 * Copyright (C) 1995 Linus Torvalds 2 * Copyright (C) 1995 Linus Torvalds
5 * 3 *
6 * Pentium III FXSR, SSE support 4 * Pentium III FXSR, SSE support
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 98956555450b..7352d4b377e6 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86-64/kernel/process.c
3 *
4 * Copyright (C) 1995 Linus Torvalds 2 * Copyright (C) 1995 Linus Torvalds
5 * 3 *
6 * Pentium III FXSR, SSE support 4 * Pentium III FXSR, SSE support
@@ -38,6 +36,7 @@
38#include <linux/notifier.h> 36#include <linux/notifier.h>
39#include <linux/kprobes.h> 37#include <linux/kprobes.h>
40#include <linux/kdebug.h> 38#include <linux/kdebug.h>
39#include <linux/tick.h>
41 40
42#include <asm/uaccess.h> 41#include <asm/uaccess.h>
43#include <asm/pgtable.h> 42#include <asm/pgtable.h>
@@ -208,6 +207,8 @@ void cpu_idle (void)
208 if (__get_cpu_var(cpu_idle_state)) 207 if (__get_cpu_var(cpu_idle_state))
209 __get_cpu_var(cpu_idle_state) = 0; 208 __get_cpu_var(cpu_idle_state) = 0;
210 209
210 tick_nohz_stop_sched_tick();
211
211 rmb(); 212 rmb();
212 idle = pm_idle; 213 idle = pm_idle;
213 if (!idle) 214 if (!idle)
@@ -228,6 +229,7 @@ void cpu_idle (void)
228 __exit_idle(); 229 __exit_idle();
229 } 230 }
230 231
232 tick_nohz_restart_sched_tick();
231 preempt_enable_no_resched(); 233 preempt_enable_no_resched();
232 schedule(); 234 schedule();
233 preempt_disable(); 235 preempt_disable();
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 7c1b92522e95..0cecd7513c97 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -1,4 +1,3 @@
1/* ptrace.c */
2/* By Ross Biro 1/23/92 */ 1/* By Ross Biro 1/23/92 */
3/* 2/*
4 * Pentium III FXSR, SSE support 3 * Pentium III FXSR, SSE support
diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c
index eea3702427b4..c0cac42df3b6 100644
--- a/arch/x86/kernel/ptrace_64.c
+++ b/arch/x86/kernel/ptrace_64.c
@@ -1,4 +1,3 @@
1/* ptrace.c */
2/* By Ross Biro 1/23/92 */ 1/* By Ross Biro 1/23/92 */
3/* 2/*
4 * Pentium III FXSR, SSE support 3 * Pentium III FXSR, SSE support
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 6722469c2633..d769e204f942 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -4,6 +4,8 @@
4#include <linux/pci.h> 4#include <linux/pci.h>
5#include <linux/irq.h> 5#include <linux/irq.h>
6 6
7#include <asm/hpet.h>
8
7#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) 9#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI)
8 10
9static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) 11static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
@@ -47,3 +49,206 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quir
47DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); 49DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
48DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); 50DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance);
49#endif 51#endif
52
53#if defined(CONFIG_HPET_TIMER)
54unsigned long force_hpet_address;
55
56static enum {
57 NONE_FORCE_HPET_RESUME,
58 OLD_ICH_FORCE_HPET_RESUME,
59 ICH_FORCE_HPET_RESUME
60} force_hpet_resume_type;
61
62static void __iomem *rcba_base;
63
64static void ich_force_hpet_resume(void)
65{
66 u32 val;
67
68 if (!force_hpet_address)
69 return;
70
71 if (rcba_base == NULL)
72 BUG();
73
74 /* read the Function Disable register, dword mode only */
75 val = readl(rcba_base + 0x3404);
76 if (!(val & 0x80)) {
77 /* HPET disabled in HPTC. Trying to enable */
78 writel(val | 0x80, rcba_base + 0x3404);
79 }
80
81 val = readl(rcba_base + 0x3404);
82 if (!(val & 0x80))
83 BUG();
84 else
85 printk(KERN_DEBUG "Force enabled HPET at resume\n");
86
87 return;
88}
89
90static void ich_force_enable_hpet(struct pci_dev *dev)
91{
92 u32 val;
93 u32 uninitialized_var(rcba);
94 int err = 0;
95
96 if (hpet_address || force_hpet_address)
97 return;
98
99 pci_read_config_dword(dev, 0xF0, &rcba);
100 rcba &= 0xFFFFC000;
101 if (rcba == 0) {
102 printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n");
103 return;
104 }
105
106 /* use bits 31:14, 16 kB aligned */
107 rcba_base = ioremap_nocache(rcba, 0x4000);
108 if (rcba_base == NULL) {
109 printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n");
110 return;
111 }
112
113 /* read the Function Disable register, dword mode only */
114 val = readl(rcba_base + 0x3404);
115
116 if (val & 0x80) {
117 /* HPET is enabled in HPTC. Just not reported by BIOS */
118 val = val & 0x3;
119 force_hpet_address = 0xFED00000 | (val << 12);
120 printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
121 force_hpet_address);
122 iounmap(rcba_base);
123 return;
124 }
125
126 /* HPET disabled in HPTC. Trying to enable */
127 writel(val | 0x80, rcba_base + 0x3404);
128
129 val = readl(rcba_base + 0x3404);
130 if (!(val & 0x80)) {
131 err = 1;
132 } else {
133 val = val & 0x3;
134 force_hpet_address = 0xFED00000 | (val << 12);
135 }
136
137 if (err) {
138 force_hpet_address = 0;
139 iounmap(rcba_base);
140 printk(KERN_DEBUG "Failed to force enable HPET\n");
141 } else {
142 force_hpet_resume_type = ICH_FORCE_HPET_RESUME;
143 printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
144 force_hpet_address);
145 }
146}
147
148DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
149 ich_force_enable_hpet);
150DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
151 ich_force_enable_hpet);
152DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
153 ich_force_enable_hpet);
154DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
155 ich_force_enable_hpet);
156DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
157 ich_force_enable_hpet);
158DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
159 ich_force_enable_hpet);
160
161
162static struct pci_dev *cached_dev;
163
164static void old_ich_force_hpet_resume(void)
165{
166 u32 val;
167 u32 uninitialized_var(gen_cntl);
168
169 if (!force_hpet_address || !cached_dev)
170 return;
171
172 pci_read_config_dword(cached_dev, 0xD0, &gen_cntl);
173 gen_cntl &= (~(0x7 << 15));
174 gen_cntl |= (0x4 << 15);
175
176 pci_write_config_dword(cached_dev, 0xD0, gen_cntl);
177 pci_read_config_dword(cached_dev, 0xD0, &gen_cntl);
178 val = gen_cntl >> 15;
179 val &= 0x7;
180 if (val == 0x4)
181 printk(KERN_DEBUG "Force enabled HPET at resume\n");
182 else
183 BUG();
184}
185
186static void old_ich_force_enable_hpet(struct pci_dev *dev)
187{
188 u32 val;
189 u32 uninitialized_var(gen_cntl);
190
191 if (hpet_address || force_hpet_address)
192 return;
193
194 pci_read_config_dword(dev, 0xD0, &gen_cntl);
195 /*
196 * Bit 17 is HPET enable bit.
197 * Bit 16:15 control the HPET base address.
198 */
199 val = gen_cntl >> 15;
200 val &= 0x7;
201 if (val & 0x4) {
202 val &= 0x3;
203 force_hpet_address = 0xFED00000 | (val << 12);
204 printk(KERN_DEBUG "HPET at base address 0x%lx\n",
205 force_hpet_address);
206 return;
207 }
208
209 /*
210 * HPET is disabled. Trying enabling at FED00000 and check
211 * whether it sticks
212 */
213 gen_cntl &= (~(0x7 << 15));
214 gen_cntl |= (0x4 << 15);
215 pci_write_config_dword(dev, 0xD0, gen_cntl);
216
217 pci_read_config_dword(dev, 0xD0, &gen_cntl);
218
219 val = gen_cntl >> 15;
220 val &= 0x7;
221 if (val & 0x4) {
222 /* HPET is enabled in HPTC. Just not reported by BIOS */
223 val &= 0x3;
224 force_hpet_address = 0xFED00000 | (val << 12);
225 printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
226 force_hpet_address);
227 cached_dev = dev;
228 force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME;
229 return;
230 }
231
232 printk(KERN_DEBUG "Failed to force enable HPET\n");
233}
234
235DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
236 old_ich_force_enable_hpet);
237DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
238 old_ich_force_enable_hpet);
239
240void force_hpet_resume(void)
241{
242 switch (force_hpet_resume_type) {
243 case ICH_FORCE_HPET_RESUME:
244 return ich_force_hpet_resume();
245
246 case OLD_ICH_FORCE_HPET_RESUME:
247 return old_ich_force_hpet_resume();
248
249 default:
250 break;
251 }
252}
253
254#endif
diff --git a/arch/x86/kernel/reboot_32.c b/arch/x86/kernel/reboot_32.c
index b37ed226830a..9e2269d00918 100644
--- a/arch/x86/kernel/reboot_32.c
+++ b/arch/x86/kernel/reboot_32.c
@@ -1,7 +1,3 @@
1/*
2 * linux/arch/i386/kernel/reboot.c
3 */
4
5#include <linux/mm.h> 1#include <linux/mm.h>
6#include <linux/module.h> 2#include <linux/module.h>
7#include <linux/delay.h> 3#include <linux/delay.h>
diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
index 03e1cce58f49..8b30b26ad069 100644
--- a/arch/x86/kernel/reboot_fixups_32.c
+++ b/arch/x86/kernel/reboot_fixups_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/reboot_fixups.c
3 *
4 * This is a good place to put board specific reboot fixups. 2 * This is a good place to put board specific reboot fixups.
5 * 3 *
6 * List of supported fixups: 4 * List of supported fixups:
@@ -11,6 +9,7 @@
11 9
12#include <asm/delay.h> 10#include <asm/delay.h>
13#include <linux/pci.h> 11#include <linux/pci.h>
12#include <linux/interrupt.h>
14#include <asm/reboot_fixups.h> 13#include <asm/reboot_fixups.h>
15#include <asm/msr.h> 14#include <asm/msr.h>
16 15
@@ -56,6 +55,11 @@ void mach_reboot_fixups(void)
56 struct pci_dev *dev; 55 struct pci_dev *dev;
57 int i; 56 int i;
58 57
58 /* we can be called from sysrq-B code. In such a case it is
59 * prohibited to dig PCI */
60 if (in_interrupt())
61 return;
62
59 for (i=0; i < ARRAY_SIZE(fixups_table); i++) { 63 for (i=0; i < ARRAY_SIZE(fixups_table); i++) {
60 cur = &(fixups_table[i]); 64 cur = &(fixups_table[i]);
61 dev = pci_get_device(cur->vendor, cur->device, NULL); 65 dev = pci_get_device(cur->vendor, cur->device, NULL);
diff --git a/arch/x86/kernel/scx200_32.c b/arch/x86/kernel/scx200_32.c
index c7d3df23f589..87bc159d29df 100644
--- a/arch/x86/kernel/scx200_32.c
+++ b/arch/x86/kernel/scx200_32.c
@@ -1,8 +1,8 @@
1/* linux/arch/i386/kernel/scx200.c 1/*
2 2 * Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> 3 *
4 4 * National Semiconductor SCx200 support.
5 National Semiconductor SCx200 support. */ 5 */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/errno.h> 8#include <linux/errno.h>
@@ -24,7 +24,7 @@ MODULE_DESCRIPTION("NatSemi SCx200 Driver");
24MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
25 25
26unsigned scx200_gpio_base = 0; 26unsigned scx200_gpio_base = 0;
27long scx200_gpio_shadow[2]; 27unsigned long scx200_gpio_shadow[2];
28 28
29unsigned scx200_cb_base = 0; 29unsigned scx200_cb_base = 0;
30 30
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index d474cd639bcb..c8e1bc38d421 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds 2 * Copyright (C) 1995 Linus Torvalds
5 * 3 *
6 * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 4 * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index af838f6b0b7f..b7da90e79c78 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -1,10 +1,5 @@
1/* 1/*
2 * linux/arch/x86-64/kernel/setup.c
3 *
4 * Copyright (C) 1995 Linus Torvalds 2 * Copyright (C) 1995 Linus Torvalds
5 *
6 * Nov 2001 Dave Jones <davej@suse.de>
7 * Forked from i386 setup code.
8 */ 3 */
9 4
10/* 5/*
@@ -546,6 +541,37 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
546#endif 541#endif
547} 542}
548 543
544#define ENABLE_C1E_MASK 0x18000000
545#define CPUID_PROCESSOR_SIGNATURE 1
546#define CPUID_XFAM 0x0ff00000
547#define CPUID_XFAM_K8 0x00000000
548#define CPUID_XFAM_10H 0x00100000
549#define CPUID_XFAM_11H 0x00200000
550#define CPUID_XMOD 0x000f0000
551#define CPUID_XMOD_REV_F 0x00040000
552
553/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
554static __cpuinit int amd_apic_timer_broken(void)
555{
556 u32 lo, hi;
557 u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
558 switch (eax & CPUID_XFAM) {
559 case CPUID_XFAM_K8:
560 if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
561 break;
562 case CPUID_XFAM_10H:
563 case CPUID_XFAM_11H:
564 rdmsr(MSR_K8_ENABLE_C1E, lo, hi);
565 if (lo & ENABLE_C1E_MASK)
566 return 1;
567 break;
568 default:
569 /* err on the side of caution */
570 return 1;
571 }
572 return 0;
573}
574
549static void __cpuinit init_amd(struct cpuinfo_x86 *c) 575static void __cpuinit init_amd(struct cpuinfo_x86 *c)
550{ 576{
551 unsigned level; 577 unsigned level;
@@ -617,6 +643,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
617 /* Family 10 doesn't support C states in MWAIT so don't use it */ 643 /* Family 10 doesn't support C states in MWAIT so don't use it */
618 if (c->x86 == 0x10 && !force_mwait) 644 if (c->x86 == 0x10 && !force_mwait)
619 clear_bit(X86_FEATURE_MWAIT, &c->x86_capability); 645 clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);
646
647 if (amd_apic_timer_broken())
648 disable_apic_timer = 1;
620} 649}
621 650
622static void __cpuinit detect_ht(struct cpuinfo_x86 *c) 651static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index c03570f7fe8e..d01d51fcce2a 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 2 * Copyright (C) 1991, 1992 Linus Torvalds
5 * 3 *
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson 4 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 739175b01e06..683802bec419 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 2 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs 3 * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs
6 * 4 *
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index 32f50783edc8..720a7d1f8862 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -223,8 +223,6 @@ void __cpuinit smp_callin(void)
223 local_irq_disable(); 223 local_irq_disable();
224 Dprintk("Stack at about %p\n",&cpuid); 224 Dprintk("Stack at about %p\n",&cpuid);
225 225
226 disable_APIC_timer();
227
228 /* 226 /*
229 * Save our processor parameters 227 * Save our processor parameters
230 */ 228 */
@@ -337,19 +335,12 @@ void __cpuinit start_secondary(void)
337 */ 335 */
338 check_tsc_sync_target(); 336 check_tsc_sync_target();
339 337
340 Dprintk("cpu %d: setting up apic clock\n", smp_processor_id());
341 setup_secondary_APIC_clock();
342
343 Dprintk("cpu %d: enabling apic timer\n", smp_processor_id());
344
345 if (nmi_watchdog == NMI_IO_APIC) { 338 if (nmi_watchdog == NMI_IO_APIC) {
346 disable_8259A_irq(0); 339 disable_8259A_irq(0);
347 enable_NMI_through_LVT0(NULL); 340 enable_NMI_through_LVT0(NULL);
348 enable_8259A_irq(0); 341 enable_8259A_irq(0);
349 } 342 }
350 343
351 enable_APIC_timer();
352
353 /* 344 /*
354 * The sibling maps must be set before turing the online map on for 345 * The sibling maps must be set before turing the online map on for
355 * this cpu 346 * this cpu
@@ -378,6 +369,8 @@ void __cpuinit start_secondary(void)
378 369
379 unlock_ipi_call_lock(); 370 unlock_ipi_call_lock();
380 371
372 setup_secondary_APIC_clock();
373
381 cpu_idle(); 374 cpu_idle();
382} 375}
383 376
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c
index cb9109113584..413e527cdeb9 100644
--- a/arch/x86/kernel/stacktrace.c
+++ b/arch/x86/kernel/stacktrace.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * arch/x86_64/kernel/stacktrace.c
3 *
4 * Stack trace management functions 2 * Stack trace management functions
5 * 3 *
6 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> 4 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c
index d0e01a3acf35..91c7acc8d999 100644
--- a/arch/x86/kernel/summit_32.c
+++ b/arch/x86/kernel/summit_32.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/i386/kernel/summit.c - IBM Summit-Specific Code 2 * IBM Summit-Specific Code
3 * 3 *
4 * Written By: Matthew Dobson, IBM Corporation 4 * Written By: Matthew Dobson, IBM Corporation
5 * 5 *
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
index 42147304de88..f8bae9ba0324 100644
--- a/arch/x86/kernel/sys_i386_32.c
+++ b/arch/x86/kernel/sys_i386_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/sys_i386.c
3 *
4 * This file contains various random system calls that 2 * This file contains various random system calls that
5 * have a non-standard calling sequence on the Linux/i386 3 * have a non-standard calling sequence on the Linux/i386
6 * platform. 4 * platform.
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 4770b7a2052c..907942ee6e76 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -1,7 +1,3 @@
1/*
2 * linux/arch/x86_64/kernel/sys_x86_64.c
3 */
4
5#include <linux/errno.h> 1#include <linux/errno.h>
6#include <linux/sched.h> 2#include <linux/sched.h>
7#include <linux/syscalls.h> 3#include <linux/syscalls.h>
diff --git a/arch/x86/kernel/sysenter_32.c b/arch/x86/kernel/sysenter_32.c
index 4eb2e408764f..5a2d951e2608 100644
--- a/arch/x86/kernel/sysenter_32.c
+++ b/arch/x86/kernel/sysenter_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/sysenter.c
3 *
4 * (C) Copyright 2002 Linus Torvalds 2 * (C) Copyright 2002 Linus Torvalds
5 * Portions based on the vdso-randomization code from exec-shield: 3 * Portions based on the vdso-randomization code from exec-shield:
6 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar 4 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
index 19a6c678d02e..8a322c96bc23 100644
--- a/arch/x86/kernel/time_32.c
+++ b/arch/x86/kernel/time_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/kernel/time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 2 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 * 3 *
6 * This file contains the PC-specific time handling details: 4 * This file contains the PC-specific time handling details:
@@ -157,6 +155,9 @@ EXPORT_SYMBOL(profile_pc);
157 */ 155 */
158irqreturn_t timer_interrupt(int irq, void *dev_id) 156irqreturn_t timer_interrupt(int irq, void *dev_id)
159{ 157{
158 /* Keep nmi watchdog up to date */
159 per_cpu(irq_stat, smp_processor_id()).irq0_irqs++;
160
160#ifdef CONFIG_X86_IO_APIC 161#ifdef CONFIG_X86_IO_APIC
161 if (timer_ack) { 162 if (timer_ack) {
162 /* 163 /*
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
index 6d48a4e826d9..c821edc32216 100644
--- a/arch/x86/kernel/time_64.c
+++ b/arch/x86/kernel/time_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86-64/kernel/time.c
3 *
4 * "High Precision Event Timer" based timekeeping. 2 * "High Precision Event Timer" based timekeeping.
5 * 3 *
6 * Copyright (c) 1991,1992,1995 Linus Torvalds 4 * Copyright (c) 1991,1992,1995 Linus Torvalds
@@ -28,11 +26,12 @@
28#include <linux/cpu.h> 26#include <linux/cpu.h>
29#include <linux/kallsyms.h> 27#include <linux/kallsyms.h>
30#include <linux/acpi.h> 28#include <linux/acpi.h>
29#include <linux/clockchips.h>
30
31#ifdef CONFIG_ACPI 31#ifdef CONFIG_ACPI
32#include <acpi/achware.h> /* for PM timer frequency */ 32#include <acpi/achware.h> /* for PM timer frequency */
33#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
34#endif 34#endif
35#include <asm/8253pit.h>
36#include <asm/i8253.h> 35#include <asm/i8253.h>
37#include <asm/pgtable.h> 36#include <asm/pgtable.h>
38#include <asm/vsyscall.h> 37#include <asm/vsyscall.h>
@@ -47,12 +46,8 @@
47#include <asm/nmi.h> 46#include <asm/nmi.h>
48#include <asm/vgtod.h> 47#include <asm/vgtod.h>
49 48
50static char *timename = NULL;
51
52DEFINE_SPINLOCK(rtc_lock); 49DEFINE_SPINLOCK(rtc_lock);
53EXPORT_SYMBOL(rtc_lock); 50EXPORT_SYMBOL(rtc_lock);
54DEFINE_SPINLOCK(i8253_lock);
55EXPORT_SYMBOL(i8253_lock);
56 51
57volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; 52volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
58 53
@@ -153,45 +148,12 @@ int update_persistent_clock(struct timespec now)
153 return set_rtc_mmss(now.tv_sec); 148 return set_rtc_mmss(now.tv_sec);
154} 149}
155 150
156void main_timer_handler(void) 151static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
157{ 152{
158/* 153 add_pda(irq0_irqs, 1);
159 * Here we are in the timer irq handler. We have irqs locally disabled (so we
160 * don't need spin_lock_irqsave()) but we don't know if the timer_bh is running
161 * on the other CPU, so we need a lock. We also need to lock the vsyscall
162 * variables, because both do_timer() and us change them -arca+vojtech
163 */
164
165 write_seqlock(&xtime_lock);
166
167/*
168 * Do the timer stuff.
169 */
170 154
171 do_timer(1); 155 global_clock_event->event_handler(global_clock_event);
172#ifndef CONFIG_SMP
173 update_process_times(user_mode(get_irq_regs()));
174#endif
175
176/*
177 * In the SMP case we use the local APIC timer interrupt to do the profiling,
178 * except when we simulate SMP mode on a uniprocessor system, in that case we
179 * have to call the local interrupt handler.
180 */
181
182 if (!using_apic_timer)
183 smp_local_timer_interrupt();
184 156
185 write_sequnlock(&xtime_lock);
186}
187
188static irqreturn_t timer_interrupt(int irq, void *dev_id)
189{
190 if (apic_runs_main_timer > 1)
191 return IRQ_HANDLED;
192 main_timer_handler();
193 if (using_apic_timer)
194 smp_send_timer_broadcast_ipi();
195 return IRQ_HANDLED; 157 return IRQ_HANDLED;
196} 158}
197 159
@@ -292,97 +254,21 @@ static unsigned int __init tsc_calibrate_cpu_khz(void)
292 return pmc_now * tsc_khz / (tsc_now - tsc_start); 254 return pmc_now * tsc_khz / (tsc_now - tsc_start);
293} 255}
294 256
295/*
296 * pit_calibrate_tsc() uses the speaker output (channel 2) of
297 * the PIT. This is better than using the timer interrupt output,
298 * because we can read the value of the speaker with just one inb(),
299 * where we need three i/o operations for the interrupt channel.
300 * We count how many ticks the TSC does in 50 ms.
301 */
302
303static unsigned int __init pit_calibrate_tsc(void)
304{
305 unsigned long start, end;
306 unsigned long flags;
307
308 spin_lock_irqsave(&i8253_lock, flags);
309
310 outb((inb(0x61) & ~0x02) | 0x01, 0x61);
311
312 outb(0xb0, 0x43);
313 outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
314 outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42);
315 start = get_cycles_sync();
316 while ((inb(0x61) & 0x20) == 0);
317 end = get_cycles_sync();
318
319 spin_unlock_irqrestore(&i8253_lock, flags);
320
321 return (end - start) / 50;
322}
323
324#define PIT_MODE 0x43
325#define PIT_CH0 0x40
326
327static void __pit_init(int val, u8 mode)
328{
329 unsigned long flags;
330
331 spin_lock_irqsave(&i8253_lock, flags);
332 outb_p(mode, PIT_MODE);
333 outb_p(val & 0xff, PIT_CH0); /* LSB */
334 outb_p(val >> 8, PIT_CH0); /* MSB */
335 spin_unlock_irqrestore(&i8253_lock, flags);
336}
337
338void __init pit_init(void)
339{
340 __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
341}
342
343void pit_stop_interrupt(void)
344{
345 __pit_init(0, 0x30); /* mode 0 */
346}
347
348void stop_timer_interrupt(void)
349{
350 char *name;
351 if (hpet_address) {
352 name = "HPET";
353 hpet_timer_stop_set_go(0);
354 } else {
355 name = "PIT";
356 pit_stop_interrupt();
357 }
358 printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
359}
360
361static struct irqaction irq0 = { 257static struct irqaction irq0 = {
362 .handler = timer_interrupt, 258 .handler = timer_event_interrupt,
363 .flags = IRQF_DISABLED | IRQF_IRQPOLL, 259 .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING,
364 .mask = CPU_MASK_NONE, 260 .mask = CPU_MASK_NONE,
365 .name = "timer" 261 .name = "timer"
366}; 262};
367 263
368void __init time_init(void) 264void __init time_init(void)
369{ 265{
370 if (nohpet) 266 if (!hpet_enable())
371 hpet_address = 0; 267 setup_pit_timer();
372 268
373 if (hpet_arch_init()) 269 setup_irq(0, &irq0);
374 hpet_address = 0;
375 270
376 if (hpet_use_timer) { 271 tsc_calibrate();
377 /* set tick_nsec to use the proper rate for HPET */
378 tick_nsec = TICK_NSEC_HPET;
379 tsc_khz = hpet_calibrate_tsc();
380 timename = "HPET";
381 } else {
382 pit_init();
383 tsc_khz = pit_calibrate_tsc();
384 timename = "PIT";
385 }
386 272
387 cpu_khz = tsc_khz; 273 cpu_khz = tsc_khz;
388 if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && 274 if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) &&
@@ -398,50 +284,7 @@ void __init time_init(void)
398 else 284 else
399 vgetcpu_mode = VGETCPU_LSL; 285 vgetcpu_mode = VGETCPU_LSL;
400 286
401 set_cyc2ns_scale(tsc_khz);
402 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", 287 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
403 cpu_khz / 1000, cpu_khz % 1000); 288 cpu_khz / 1000, cpu_khz % 1000);
404 init_tsc_clocksource(); 289 init_tsc_clocksource();
405
406 setup_irq(0, &irq0);
407}
408
409/*
410 * sysfs support for the timer.
411 */
412
413static int timer_suspend(struct sys_device *dev, pm_message_t state)
414{
415 return 0;
416}
417
418static int timer_resume(struct sys_device *dev)
419{
420 if (hpet_address)
421 hpet_reenable();
422 else
423 i8254_timer_resume();
424 return 0;
425} 290}
426
427static struct sysdev_class timer_sysclass = {
428 .resume = timer_resume,
429 .suspend = timer_suspend,
430 set_kset_name("timer"),
431};
432
433/* XXX this sysfs stuff should probably go elsewhere later -john */
434static struct sys_device device_timer = {
435 .id = 0,
436 .cls = &timer_sysclass,
437};
438
439static int time_init_device(void)
440{
441 int error = sysdev_class_register(&timer_sysclass);
442 if (!error)
443 error = sysdev_register(&device_timer);
444 return error;
445}
446
447device_initcall(time_init_device);
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 45782356a618..c25f23eb397c 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/i386/kernel/topology.c - Populate sysfs with topology information 2 * Populate sysfs with topology information
3 * 3 *
4 * Written by: Matthew Dobson, IBM Corporation 4 * Written by: Matthew Dobson, IBM Corporation
5 * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL 5 * Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 47b0bef335bd..05c27ecaf2a7 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/i386/traps.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 2 * Copyright (C) 1991, 1992 Linus Torvalds
5 * 3 *
6 * Pentium III FXSR, SSE support 4 * Pentium III FXSR, SSE support
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 03888420775d..bc7116acf8ff 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86-64/traps.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds 2 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 3 * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
6 * 4 *
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index 3ed0ae8c918d..b85ad754f70e 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -1,9 +1,3 @@
1/*
2 * This code largely moved from arch/i386/kernel/timer/timer_tsc.c
3 * which was originally moved from arch/i386/kernel/time.c.
4 * See comments there for proper credits.
5 */
6
7#include <linux/sched.h> 1#include <linux/sched.h>
8#include <linux/clocksource.h> 2#include <linux/clocksource.h>
9#include <linux/workqueue.h> 3#include <linux/workqueue.h>
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 2a59bde663f2..9f22e542c374 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -6,7 +6,9 @@
6#include <linux/time.h> 6#include <linux/time.h>
7#include <linux/acpi.h> 7#include <linux/acpi.h>
8#include <linux/cpufreq.h> 8#include <linux/cpufreq.h>
9#include <linux/acpi_pmtmr.h>
9 10
11#include <asm/hpet.h>
10#include <asm/timex.h> 12#include <asm/timex.h>
11 13
12static int notsc __initdata = 0; 14static int notsc __initdata = 0;
@@ -18,7 +20,7 @@ EXPORT_SYMBOL(tsc_khz);
18 20
19static unsigned int cyc2ns_scale __read_mostly; 21static unsigned int cyc2ns_scale __read_mostly;
20 22
21void set_cyc2ns_scale(unsigned long khz) 23static inline void set_cyc2ns_scale(unsigned long khz)
22{ 24{
23 cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / khz; 25 cyc2ns_scale = (NSEC_PER_MSEC << NS_SCALE) / khz;
24} 26}
@@ -118,6 +120,95 @@ core_initcall(cpufreq_tsc);
118 120
119#endif 121#endif
120 122
123#define MAX_RETRIES 5
124#define SMI_TRESHOLD 50000
125
126/*
127 * Read TSC and the reference counters. Take care of SMI disturbance
128 */
129static unsigned long __init tsc_read_refs(unsigned long *pm,
130 unsigned long *hpet)
131{
132 unsigned long t1, t2;
133 int i;
134
135 for (i = 0; i < MAX_RETRIES; i++) {
136 t1 = get_cycles_sync();
137 if (hpet)
138 *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF;
139 else
140 *pm = acpi_pm_read_early();
141 t2 = get_cycles_sync();
142 if ((t2 - t1) < SMI_TRESHOLD)
143 return t2;
144 }
145 return ULONG_MAX;
146}
147
148/**
149 * tsc_calibrate - calibrate the tsc on boot
150 */
151void __init tsc_calibrate(void)
152{
153 unsigned long flags, tsc1, tsc2, tr1, tr2, pm1, pm2, hpet1, hpet2;
154 int hpet = is_hpet_enabled();
155
156 local_irq_save(flags);
157
158 tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL);
159
160 outb((inb(0x61) & ~0x02) | 0x01, 0x61);
161
162 outb(0xb0, 0x43);
163 outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
164 outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42);
165 tr1 = get_cycles_sync();
166 while ((inb(0x61) & 0x20) == 0);
167 tr2 = get_cycles_sync();
168
169 tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL);
170
171 local_irq_restore(flags);
172
173 /*
174 * Preset the result with the raw and inaccurate PIT
175 * calibration value
176 */
177 tsc_khz = (tr2 - tr1) / 50;
178
179 /* hpet or pmtimer available ? */
180 if (!hpet && !pm1 && !pm2) {
181 printk(KERN_INFO "TSC calibrated against PIT\n");
182 return;
183 }
184
185 /* Check, whether the sampling was disturbed by an SMI */
186 if (tsc1 == ULONG_MAX || tsc2 == ULONG_MAX) {
187 printk(KERN_WARNING "TSC calibration disturbed by SMI, "
188 "using PIT calibration result\n");
189 return;
190 }
191
192 tsc2 = (tsc2 - tsc1) * 1000000L;
193
194 if (hpet) {
195 printk(KERN_INFO "TSC calibrated against HPET\n");
196 if (hpet2 < hpet1)
197 hpet2 += 0x100000000;
198 hpet2 -= hpet1;
199 tsc1 = (hpet2 * hpet_readl(HPET_PERIOD)) / 1000000;
200 } else {
201 printk(KERN_INFO "TSC calibrated against PM_TIMER\n");
202 if (pm2 < pm1)
203 pm2 += ACPI_PM_OVRRUN;
204 pm2 -= pm1;
205 tsc1 = (pm2 * 1000000000) / PMTMR_TICKS_PER_SEC;
206 }
207
208 tsc_khz = tsc2 / tsc1;
209 set_cyc2ns_scale(tsc_khz);
210}
211
121/* 212/*
122 * Make an educated guess if the TSC is trustworthy and synchronized 213 * Make an educated guess if the TSC is trustworthy and synchronized
123 * over all CPUs. 214 * over all CPUs.
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 355f5f506c81..9125efe66a06 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/x86_64/kernel/tsc_sync.c: check TSC synchronization. 2 * check TSC synchronization.
3 * 3 *
4 * Copyright (C) 2006, Red Hat, Inc., Ingo Molnar 4 * Copyright (C) 2006, Red Hat, Inc., Ingo Molnar
5 * 5 *
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index f2dcd1d27c0a..157e4bedd3c5 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/kernel/vm86.c
3 *
4 * Copyright (C) 1994 Linus Torvalds 2 * Copyright (C) 1994 Linus Torvalds
5 * 3 *
6 * 29 dec 2001 - Fixed oopses caused by unchecked access to the vm86 4 * 29 dec 2001 - Fixed oopses caused by unchecked access to the vm86
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 06c34949bfdc..93847d848157 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/x86_64/kernel/vsyscall.c
3 *
4 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE 2 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
5 * Copyright 2003 Andi Kleen, SuSE Labs. 3 * Copyright 2003 Andi Kleen, SuSE Labs.
6 * 4 *
diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S
index 4620efb12f13..5196762b3b0e 100644
--- a/arch/x86/lib/copy_user_nocache_64.S
+++ b/arch/x86/lib/copy_user_nocache_64.S
@@ -117,6 +117,7 @@ ENTRY(__copy_user_nocache)
117 popq %rbx 117 popq %rbx
118 CFI_ADJUST_CFA_OFFSET -8 118 CFI_ADJUST_CFA_OFFSET -8
119 CFI_RESTORE rbx 119 CFI_RESTORE rbx
120 sfence
120 ret 121 ret
121 CFI_RESTORE_STATE 122 CFI_RESTORE_STATE
122 123
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index bc8a44bddaa7..2d88f7c6d6ac 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -2,15 +2,199 @@
2#include <linux/acpi.h> 2#include <linux/acpi.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/irq.h> 4#include <linux/irq.h>
5#include <linux/dmi.h>
5#include <asm/numa.h> 6#include <asm/numa.h>
6#include "pci.h" 7#include "pci.h"
7 8
9static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
10{
11 pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
12 printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
13 return 0;
14}
15
16static struct dmi_system_id acpi_pciprobe_dmi_table[] = {
17/*
18 * Systems where PCI IO resource ISA alignment can be skipped
19 * when the ISA enable bit in the bridge control is not set
20 */
21 {
22 .callback = can_skip_ioresource_align,
23 .ident = "IBM System x3800",
24 .matches = {
25 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
26 DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
27 },
28 },
29 {
30 .callback = can_skip_ioresource_align,
31 .ident = "IBM System x3850",
32 .matches = {
33 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
34 DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
35 },
36 },
37 {
38 .callback = can_skip_ioresource_align,
39 .ident = "IBM System x3950",
40 .matches = {
41 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
42 DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
43 },
44 },
45 {}
46};
47
48struct pci_root_info {
49 char *name;
50 unsigned int res_num;
51 struct resource *res;
52 struct pci_bus *bus;
53 int busnum;
54};
55
56static acpi_status
57resource_to_addr(struct acpi_resource *resource,
58 struct acpi_resource_address64 *addr)
59{
60 acpi_status status;
61
62 status = acpi_resource_to_address64(resource, addr);
63 if (ACPI_SUCCESS(status) &&
64 (addr->resource_type == ACPI_MEMORY_RANGE ||
65 addr->resource_type == ACPI_IO_RANGE) &&
66 addr->address_length > 0 &&
67 addr->producer_consumer == ACPI_PRODUCER) {
68 return AE_OK;
69 }
70 return AE_ERROR;
71}
72
73static acpi_status
74count_resource(struct acpi_resource *acpi_res, void *data)
75{
76 struct pci_root_info *info = data;
77 struct acpi_resource_address64 addr;
78 acpi_status status;
79
80 status = resource_to_addr(acpi_res, &addr);
81 if (ACPI_SUCCESS(status))
82 info->res_num++;
83 return AE_OK;
84}
85
86static acpi_status
87setup_resource(struct acpi_resource *acpi_res, void *data)
88{
89 struct pci_root_info *info = data;
90 struct resource *res;
91 struct acpi_resource_address64 addr;
92 acpi_status status;
93 unsigned long flags;
94 struct resource *root;
95
96 status = resource_to_addr(acpi_res, &addr);
97 if (!ACPI_SUCCESS(status))
98 return AE_OK;
99
100 if (addr.resource_type == ACPI_MEMORY_RANGE) {
101 root = &iomem_resource;
102 flags = IORESOURCE_MEM;
103 if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
104 flags |= IORESOURCE_PREFETCH;
105 } else if (addr.resource_type == ACPI_IO_RANGE) {
106 root = &ioport_resource;
107 flags = IORESOURCE_IO;
108 } else
109 return AE_OK;
110
111 res = &info->res[info->res_num];
112 res->name = info->name;
113 res->flags = flags;
114 res->start = addr.minimum + addr.translation_offset;
115 res->end = res->start + addr.address_length - 1;
116 res->child = NULL;
117
118 if (insert_resource(root, res)) {
119 printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx "
120 "from %s for %s\n", (unsigned long) res->start,
121 (unsigned long) res->end, root->name, info->name);
122 } else {
123 info->bus->resource[info->res_num] = res;
124 info->res_num++;
125 }
126 return AE_OK;
127}
128
129static void
130adjust_transparent_bridge_resources(struct pci_bus *bus)
131{
132 struct pci_dev *dev;
133
134 list_for_each_entry(dev, &bus->devices, bus_list) {
135 int i;
136 u16 class = dev->class >> 8;
137
138 if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) {
139 for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
140 dev->subordinate->resource[i] =
141 dev->bus->resource[i - 3];
142 }
143 }
144}
145
146static void
147get_current_resources(struct acpi_device *device, int busnum,
148 struct pci_bus *bus)
149{
150 struct pci_root_info info;
151 size_t size;
152
153 info.bus = bus;
154 info.res_num = 0;
155 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
156 &info);
157 if (!info.res_num)
158 return;
159
160 size = sizeof(*info.res) * info.res_num;
161 info.res = kmalloc(size, GFP_KERNEL);
162 if (!info.res)
163 goto res_alloc_fail;
164
165 info.name = kmalloc(12, GFP_KERNEL);
166 if (!info.name)
167 goto name_alloc_fail;
168 sprintf(info.name, "PCI Bus #%02x", busnum);
169
170 info.res_num = 0;
171 acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
172 &info);
173 if (info.res_num)
174 adjust_transparent_bridge_resources(bus);
175
176 return;
177
178name_alloc_fail:
179 kfree(info.res);
180res_alloc_fail:
181 return;
182}
183
8struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) 184struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
9{ 185{
10 struct pci_bus *bus; 186 struct pci_bus *bus;
11 struct pci_sysdata *sd; 187 struct pci_sysdata *sd;
12 int pxm; 188 int pxm;
13 189
190 dmi_check_system(acpi_pciprobe_dmi_table);
191
192 if (domain && !pci_domains_supported) {
193 printk(KERN_WARNING "PCI: Multiple domains not supported "
194 "(dom %d, bus %d)\n", domain, busnum);
195 return NULL;
196 }
197
14 /* Allocate per-root-bus (not per bus) arch-specific data. 198 /* Allocate per-root-bus (not per bus) arch-specific data.
15 * TODO: leak; this memory is never freed. 199 * TODO: leak; this memory is never freed.
16 * It's arguable whether it's worth the trouble to care. 200 * It's arguable whether it's worth the trouble to care.
@@ -21,12 +205,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
21 return NULL; 205 return NULL;
22 } 206 }
23 207
24 if (domain != 0) { 208 sd->domain = domain;
25 printk(KERN_WARNING "PCI: Multiple domains not supported\n");
26 kfree(sd);
27 return NULL;
28 }
29
30 sd->node = -1; 209 sd->node = -1;
31 210
32 pxm = acpi_get_pxm(device->handle); 211 pxm = acpi_get_pxm(device->handle);
@@ -47,6 +226,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
47 } 226 }
48 } 227 }
49#endif 228#endif
229
230 if (bus && (pci_probe & PCI_USE__CRS))
231 get_current_resources(device, busnum, bus);
50 232
51 return bus; 233 return bus;
52} 234}
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 07d5223442bf..2d71bbc411d2 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -29,12 +29,14 @@ struct pci_raw_ops *raw_pci_ops;
29 29
30static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) 30static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
31{ 31{
32 return raw_pci_ops->read(0, bus->number, devfn, where, size, value); 32 return raw_pci_ops->read(pci_domain_nr(bus), bus->number,
33 devfn, where, size, value);
33} 34}
34 35
35static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 36static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
36{ 37{
37 return raw_pci_ops->write(0, bus->number, devfn, where, size, value); 38 return raw_pci_ops->write(pci_domain_nr(bus), bus->number,
39 devfn, where, size, value);
38} 40}
39 41
40struct pci_ops pci_root_ops = { 42struct pci_ops pci_root_ops = {
@@ -287,6 +289,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
287 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), 289 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
288 }, 290 },
289 }, 291 },
292#ifdef __i386__
293 {
294 .callback = assign_all_busses,
295 .ident = "Compaq EVO N800c",
296 .matches = {
297 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
298 DMI_MATCH(DMI_PRODUCT_NAME, "EVO N800c"),
299 },
300 },
301#endif
290 {} 302 {}
291}; 303};
292 304
@@ -426,6 +438,9 @@ char * __devinit pcibios_setup(char *str)
426 } else if (!strcmp(str, "assign-busses")) { 438 } else if (!strcmp(str, "assign-busses")) {
427 pci_probe |= PCI_ASSIGN_ALL_BUSSES; 439 pci_probe |= PCI_ASSIGN_ALL_BUSSES;
428 return NULL; 440 return NULL;
441 } else if (!strcmp(str, "use_crs")) {
442 pci_probe |= PCI_USE__CRS;
443 return NULL;
429 } else if (!strcmp(str, "routeirq")) { 444 } else if (!strcmp(str, "routeirq")) {
430 pci_routeirq = 1; 445 pci_routeirq = 1;
431 return NULL; 446 return NULL;
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index c82cbf4c7226..6cff66dd0c91 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -353,6 +353,53 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
353} 353}
354DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); 354DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
355 355
356
357static struct dmi_system_id __devinitdata msi_k8t_dmi_table[] = {
358 {
359 .ident = "MSI-K8T-Neo2Fir",
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
362 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
363 },
364 },
365 {}
366};
367
368/*
369 * The AMD-Athlon64 board MSI "K8T Neo2-FIR" disables the onboard sound
370 * card if a PCI-soundcard is added.
371 *
372 * The BIOS only gives options "DISABLED" and "AUTO". This code sets
373 * the corresponding register-value to enable the soundcard.
374 *
375 * The soundcard is only enabled, if the mainborad is identified
376 * via DMI-tables and the soundcard is detected to be off.
377 */
378static void __devinit pci_fixup_msi_k8t_onboard_sound(struct pci_dev *dev)
379{
380 unsigned char val;
381 if (!dmi_check_system(msi_k8t_dmi_table))
382 return; /* only applies to MSI K8T Neo2-FIR */
383
384 pci_read_config_byte(dev, 0x50, &val);
385 if (val & 0x40) {
386 pci_write_config_byte(dev, 0x50, val & (~0x40));
387
388 /* verify the change for status output */
389 pci_read_config_byte(dev, 0x50, &val);
390 if (val & 0x40)
391 printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, "
392 "can't enable onboard soundcard!\n");
393 else
394 printk(KERN_INFO "PCI: Detected MSI K8T Neo2-FIR, "
395 "enabled onboard soundcard.\n");
396 }
397}
398DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
399 pci_fixup_msi_k8t_onboard_sound);
400DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
401 pci_fixup_msi_k8t_onboard_sound);
402
356/* 403/*
357 * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. 404 * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
358 * 405 *
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index bcd2f94b732c..42ba0e2da1a0 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -33,6 +33,15 @@
33 33
34#include "pci.h" 34#include "pci.h"
35 35
36static int
37skip_isa_ioresource_align(struct pci_dev *dev) {
38
39 if ((pci_probe & PCI_CAN_SKIP_ISA_ALIGN) &&
40 !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
41 return 1;
42 return 0;
43}
44
36/* 45/*
37 * We need to avoid collisions with `mirrored' VGA ports 46 * We need to avoid collisions with `mirrored' VGA ports
38 * and other strange ISA hardware, so we always want the 47 * and other strange ISA hardware, so we always want the
@@ -50,9 +59,13 @@ void
50pcibios_align_resource(void *data, struct resource *res, 59pcibios_align_resource(void *data, struct resource *res,
51 resource_size_t size, resource_size_t align) 60 resource_size_t size, resource_size_t align)
52{ 61{
62 struct pci_dev *dev = data;
63
53 if (res->flags & IORESOURCE_IO) { 64 if (res->flags & IORESOURCE_IO) {
54 resource_size_t start = res->start; 65 resource_size_t start = res->start;
55 66
67 if (skip_isa_ioresource_align(dev))
68 return;
56 if (start & 0x300) { 69 if (start & 0x300) {
57 start = (start + 0x3ff) & ~0x3ff; 70 start = (start + 0x3ff) & ~0x3ff;
58 res->start = start; 71 res->start = start;
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index d98c6b096f8e..c52150fdf82b 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -492,6 +492,26 @@ static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq
492 return 1; 492 return 1;
493} 493}
494 494
495/*
496 * PicoPower PT86C523
497 */
498static int pirq_pico_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
499{
500 outb(0x10 + ((pirq - 1) >> 1), 0x24);
501 return ((pirq - 1) & 1) ? (inb(0x26) >> 4) : (inb(0x26) & 0xf);
502}
503
504static int pirq_pico_set(struct pci_dev *router, struct pci_dev *dev, int pirq,
505 int irq)
506{
507 unsigned int x;
508 outb(0x10 + ((pirq - 1) >> 1), 0x24);
509 x = inb(0x26);
510 x = ((pirq - 1) & 1) ? ((x & 0x0f) | (irq << 4)) : ((x & 0xf0) | (irq));
511 outb(x, 0x26);
512 return 1;
513}
514
495#ifdef CONFIG_PCI_BIOS 515#ifdef CONFIG_PCI_BIOS
496 516
497static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) 517static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
@@ -721,6 +741,24 @@ static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router,
721 return 1; 741 return 1;
722} 742}
723 743
744static __init int pico_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
745{
746 switch (device) {
747 case PCI_DEVICE_ID_PICOPOWER_PT86C523:
748 r->name = "PicoPower PT86C523";
749 r->get = pirq_pico_get;
750 r->set = pirq_pico_set;
751 return 1;
752
753 case PCI_DEVICE_ID_PICOPOWER_PT86C523BBP:
754 r->name = "PicoPower PT86C523 rev. BB+";
755 r->get = pirq_pico_get;
756 r->set = pirq_pico_set;
757 return 1;
758 }
759 return 0;
760}
761
724static __initdata struct irq_router_handler pirq_routers[] = { 762static __initdata struct irq_router_handler pirq_routers[] = {
725 { PCI_VENDOR_ID_INTEL, intel_router_probe }, 763 { PCI_VENDOR_ID_INTEL, intel_router_probe },
726 { PCI_VENDOR_ID_AL, ali_router_probe }, 764 { PCI_VENDOR_ID_AL, ali_router_probe },
@@ -732,6 +770,7 @@ static __initdata struct irq_router_handler pirq_routers[] = {
732 { PCI_VENDOR_ID_VLSI, vlsi_router_probe }, 770 { PCI_VENDOR_ID_VLSI, vlsi_router_probe },
733 { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe }, 771 { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe },
734 { PCI_VENDOR_ID_AMD, amd_router_probe }, 772 { PCI_VENDOR_ID_AMD, amd_router_probe },
773 { PCI_VENDOR_ID_PICOPOWER, pico_router_probe },
735 /* Someone with docs needs to add the ATI Radeon IGP */ 774 /* Someone with docs needs to add the ATI Radeon IGP */
736 { 0, NULL } 775 { 0, NULL }
737}; 776};
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index 8c66f275756f..ac56d3916c50 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -26,6 +26,8 @@
26#define PCI_ASSIGN_ROMS 0x1000 26#define PCI_ASSIGN_ROMS 0x1000
27#define PCI_BIOS_IRQ_SCAN 0x2000 27#define PCI_BIOS_IRQ_SCAN 0x2000
28#define PCI_ASSIGN_ALL_BUSSES 0x4000 28#define PCI_ASSIGN_ALL_BUSSES 0x4000
29#define PCI_CAN_SKIP_ISA_ALIGN 0x8000
30#define PCI_USE__CRS 0x10000
29 31
30extern unsigned int pci_probe; 32extern unsigned int pci_probe;
31extern unsigned long pirq_table_addr; 33extern unsigned long pirq_table_addr;