aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 19:51:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 19:51:56 -0400
commita99a7d1436f9375662f35ccac8f1a1e1b0302a11 (patch)
tree0b3f411f6b1c4256063cf1d53773110f5a5f7482
parentbdc7ccfc0631797636837b10df7f87bc1e2e4ae3 (diff)
parentded7c1ee9799fe0ca725b459f151402e3ca4d12b (diff)
Merge branch 'timers-cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: mips: Fix i8253 clockevent fallout i8253: Cleanup outb/inb magic arm: Footbridge: Use common i8253 clockevent mips: Use common i8253 clockevent x86: Use common i8253 clockevent i8253: Create common clockevent implementation i8253: Export i8253_lock unconditionally pcpskr: MIPS: Make config dependencies finer grained pcspkr: Cleanup Kconfig dependencies i8253: Move remaining content and delete asm/i8253.h i8253: Consolidate definitions of PIT_LATCH x86: i8253: Consolidate definitions of global_clock_event i8253: Alpha, PowerPC: Remove unused asm/8253pit.h alpha: i8253: Cleanup remaining users of i8253pit.h i8253: Remove I8253_LOCK config i8253: Make pcsp sound driver use the shared i8253_lock i8253: Make pcspkr input driver use the shared i8253_lock i8253: Consolidate all kernel definitions of i8253_lock i8253: Unify all kernel declarations of i8253_lock i8253: Create linux/i8253.h and use it in all 8253 related files
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/alpha/include/asm/8253pit.h3
-rw-r--r--arch/alpha/kernel/sys_ruffian.c1
-rw-r--r--arch/alpha/kernel/time.c1
-rw-r--r--arch/arm/include/asm/i8253.h15
-rw-r--r--arch/arm/mach-footbridge/Kconfig1
-rw-r--r--arch/arm/mach-footbridge/isa-timer.c59
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/cobalt/time.c2
-rw-r--r--arch/mips/include/asm/i8253.h24
-rw-r--r--arch/mips/jazz/irq.c2
-rw-r--r--arch/mips/kernel/i8253.c102
-rw-r--r--arch/mips/mti-malta/malta-time.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c2
-rw-r--r--arch/mips/sni/time.c2
-rw-r--r--arch/powerpc/include/asm/8253pit.h3
-rw-r--r--arch/powerpc/platforms/amigaone/Kconfig2
-rw-r--r--arch/powerpc/platforms/chrp/Kconfig1
-rw-r--r--arch/powerpc/platforms/prep/Kconfig1
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig1
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/apb_timer.h1
-rw-r--r--arch/x86/include/asm/i8253.h20
-rw-r--r--arch/x86/include/asm/time.h6
-rw-r--r--arch/x86/kernel/apb_timer.c1
-rw-r--r--arch/x86/kernel/apic/apic.c3
-rw-r--r--arch/x86/kernel/apm_32.c8
-rw-r--r--arch/x86/kernel/hpet.c3
-rw-r--r--arch/x86/kernel/i8253.c99
-rw-r--r--arch/x86/kernel/time.c2
-rw-r--r--drivers/block/hd.c2
-rw-r--r--drivers/clocksource/Kconfig9
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/i8253.c114
-rw-r--r--drivers/input/gameport/gameport.c2
-rw-r--r--drivers/input/joystick/analog.c2
-rw-r--r--drivers/input/misc/pcspkr.c9
-rw-r--r--include/linux/i8253.h29
-rw-r--r--init/Kconfig7
-rw-r--r--sound/drivers/pcsp/pcsp.h8
40 files changed, 199 insertions, 359 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 60219bf94198..ca2da8da6e9c 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -6,6 +6,7 @@ config ALPHA
6 select HAVE_OPROFILE 6 select HAVE_OPROFILE
7 select HAVE_SYSCALL_WRAPPERS 7 select HAVE_SYSCALL_WRAPPERS
8 select HAVE_IRQ_WORK 8 select HAVE_IRQ_WORK
9 select HAVE_PCSPKR_PLATFORM
9 select HAVE_PERF_EVENTS 10 select HAVE_PERF_EVENTS
10 select HAVE_DMA_ATTRS 11 select HAVE_DMA_ATTRS
11 select HAVE_GENERIC_HARDIRQS 12 select HAVE_GENERIC_HARDIRQS
diff --git a/arch/alpha/include/asm/8253pit.h b/arch/alpha/include/asm/8253pit.h
deleted file mode 100644
index a71c9c1455a7..000000000000
--- a/arch/alpha/include/asm/8253pit.h
+++ /dev/null
@@ -1,3 +0,0 @@
1/*
2 * 8253/8254 Programmable Interval Timer
3 */
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
index 8de1046fe91e..f33648e4e8cf 100644
--- a/arch/alpha/kernel/sys_ruffian.c
+++ b/arch/alpha/kernel/sys_ruffian.c
@@ -26,7 +26,6 @@
26#include <asm/pgtable.h> 26#include <asm/pgtable.h>
27#include <asm/core_cia.h> 27#include <asm/core_cia.h>
28#include <asm/tlbflush.h> 28#include <asm/tlbflush.h>
29#include <asm/8253pit.h>
30 29
31#include "proto.h" 30#include "proto.h"
32#include "irq_impl.h" 31#include "irq_impl.h"
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index f20d1b5396b8..e336694ca042 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -46,7 +46,6 @@
46#include <asm/uaccess.h> 46#include <asm/uaccess.h>
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/hwrpb.h> 48#include <asm/hwrpb.h>
49#include <asm/8253pit.h>
50#include <asm/rtc.h> 49#include <asm/rtc.h>
51 50
52#include <linux/mc146818rtc.h> 51#include <linux/mc146818rtc.h>
diff --git a/arch/arm/include/asm/i8253.h b/arch/arm/include/asm/i8253.h
deleted file mode 100644
index 70656b69d5ce..000000000000
--- a/arch/arm/include/asm/i8253.h
+++ /dev/null
@@ -1,15 +0,0 @@
1#ifndef __ASMARM_I8253_H
2#define __ASMARM_I8253_H
3
4/* i8253A PIT registers */
5#define PIT_MODE 0x43
6#define PIT_CH0 0x40
7
8#define PIT_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ)
9
10extern raw_spinlock_t i8253_lock;
11
12#define outb_pit outb_p
13#define inb_pit inb_p
14
15#endif
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 46adca068f2c..dc26fff22cf0 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -5,6 +5,7 @@ menu "Footbridge Implementations"
5config ARCH_CATS 5config ARCH_CATS
6 bool "CATS" 6 bool "CATS"
7 select CLKSRC_I8253 7 select CLKSRC_I8253
8 select CLKEVT_I8253
8 select FOOTBRIDGE_HOST 9 select FOOTBRIDGE_HOST
9 select ISA 10 select ISA
10 select ISA_DMA 11 select ISA_DMA
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index 7020f1a3feca..c40bb415f4b5 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -5,64 +5,18 @@
5 * Copyright (C) 1998 Phil Blundell 5 * Copyright (C) 1998 Phil Blundell
6 */ 6 */
7#include <linux/clockchips.h> 7#include <linux/clockchips.h>
8#include <linux/clocksource.h> 8#include <linux/i8253.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/io.h>
13#include <linux/spinlock.h> 12#include <linux/spinlock.h>
14#include <linux/timex.h> 13#include <linux/timex.h>
15 14
16#include <asm/irq.h> 15#include <asm/irq.h>
17#include <asm/i8253.h>
18#include <asm/mach/time.h> 16#include <asm/mach/time.h>
19 17
20#include "common.h" 18#include "common.h"
21 19
22DEFINE_RAW_SPINLOCK(i8253_lock);
23
24static void pit_set_mode(enum clock_event_mode mode,
25 struct clock_event_device *evt)
26{
27 unsigned long flags;
28
29 raw_local_irq_save(flags);
30
31 switch (mode) {
32 case CLOCK_EVT_MODE_PERIODIC:
33 outb_p(0x34, PIT_MODE);
34 outb_p(PIT_LATCH & 0xff, PIT_CH0);
35 outb_p(PIT_LATCH >> 8, PIT_CH0);
36 break;
37
38 case CLOCK_EVT_MODE_SHUTDOWN:
39 case CLOCK_EVT_MODE_UNUSED:
40 outb_p(0x30, PIT_MODE);
41 outb_p(0, PIT_CH0);
42 outb_p(0, PIT_CH0);
43 break;
44
45 case CLOCK_EVT_MODE_ONESHOT:
46 case CLOCK_EVT_MODE_RESUME:
47 break;
48 }
49 local_irq_restore(flags);
50}
51
52static int pit_set_next_event(unsigned long delta,
53 struct clock_event_device *evt)
54{
55 return 0;
56}
57
58static struct clock_event_device pit_ce = {
59 .name = "pit",
60 .features = CLOCK_EVT_FEAT_PERIODIC,
61 .set_mode = pit_set_mode,
62 .set_next_event = pit_set_next_event,
63 .shift = 32,
64};
65
66static irqreturn_t pit_timer_interrupt(int irq, void *dev_id) 20static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
67{ 21{
68 struct clock_event_device *ce = dev_id; 22 struct clock_event_device *ce = dev_id;
@@ -74,20 +28,15 @@ static struct irqaction pit_timer_irq = {
74 .name = "pit", 28 .name = "pit",
75 .handler = pit_timer_interrupt, 29 .handler = pit_timer_interrupt,
76 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 30 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
77 .dev_id = &pit_ce, 31 .dev_id = &i8253_clockevent,
78}; 32};
79 33
80static void __init isa_timer_init(void) 34static void __init isa_timer_init(void)
81{ 35{
82 pit_ce.cpumask = cpumask_of(smp_processor_id());
83 pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
84 pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
85 pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
86
87 clocksource_i8253_init(); 36 clocksource_i8253_init();
88 37
89 setup_irq(pit_ce.irq, &pit_timer_irq); 38 setup_irq(i8253_clockevent.irq, &pit_timer_irq);
90 clockevents_register_device(&pit_ce); 39 clockevent_i8253_init(false);
91} 40}
92 41
93struct sys_timer isa_timer = { 42struct sys_timer isa_timer = {
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 653da62d0682..6cb60adb7b30 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -185,6 +185,7 @@ config MACH_JAZZ
185 select CSRC_R4K 185 select CSRC_R4K
186 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN 186 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
187 select GENERIC_ISA_DMA 187 select GENERIC_ISA_DMA
188 select HAVE_PCSPKR_PLATFORM
188 select IRQ_CPU 189 select IRQ_CPU
189 select I8253 190 select I8253
190 select I8259 191 select I8259
@@ -266,6 +267,7 @@ config MIPS_MALTA
266 select CSRC_R4K 267 select CSRC_R4K
267 select DMA_NONCOHERENT 268 select DMA_NONCOHERENT
268 select GENERIC_ISA_DMA 269 select GENERIC_ISA_DMA
270 select HAVE_PCSPKR_PLATFORM
269 select IRQ_CPU 271 select IRQ_CPU
270 select IRQ_GIC 272 select IRQ_GIC
271 select HW_HAS_PCI 273 select HW_HAS_PCI
@@ -640,6 +642,7 @@ config SNI_RM
640 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN 642 select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
641 select DMA_NONCOHERENT 643 select DMA_NONCOHERENT
642 select GENERIC_ISA_DMA 644 select GENERIC_ISA_DMA
645 select HAVE_PCSPKR_PLATFORM
643 select HW_HAS_EISA 646 select HW_HAS_EISA
644 select HW_HAS_PCI 647 select HW_HAS_PCI
645 select IRQ_CPU 648 select IRQ_CPU
@@ -2388,6 +2391,7 @@ config MMU
2388config I8253 2391config I8253
2389 bool 2392 bool
2390 select CLKSRC_I8253 2393 select CLKSRC_I8253
2394 select CLKEVT_I8253
2391 select MIPS_EXTERNAL_TIMER 2395 select MIPS_EXTERNAL_TIMER
2392 2396
2393config ZONE_DMA32 2397config ZONE_DMA32
diff --git a/arch/mips/cobalt/time.c b/arch/mips/cobalt/time.c
index 0162f9edc693..3bff3b820baf 100644
--- a/arch/mips/cobalt/time.c
+++ b/arch/mips/cobalt/time.c
@@ -17,10 +17,10 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 19 */
20#include <linux/i8253.h>
20#include <linux/init.h> 21#include <linux/init.h>
21 22
22#include <asm/gt64120.h> 23#include <asm/gt64120.h>
23#include <asm/i8253.h>
24#include <asm/time.h> 24#include <asm/time.h>
25 25
26#define GT641XX_BASE_CLOCK 50000000 /* 50MHz */ 26#define GT641XX_BASE_CLOCK 50000000 /* 50MHz */
diff --git a/arch/mips/include/asm/i8253.h b/arch/mips/include/asm/i8253.h
deleted file mode 100644
index 9ad011366f73..000000000000
--- a/arch/mips/include/asm/i8253.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * Machine specific IO port address definition for generic.
3 * Written by Osamu Tomita <tomita@cinet.co.jp>
4 */
5#ifndef __ASM_I8253_H
6#define __ASM_I8253_H
7
8#include <linux/spinlock.h>
9
10/* i8253A PIT registers */
11#define PIT_MODE 0x43
12#define PIT_CH0 0x40
13#define PIT_CH2 0x42
14
15#define PIT_LATCH LATCH
16
17extern raw_spinlock_t i8253_lock;
18
19extern void setup_pit_timer(void);
20
21#define inb_pit inb_p
22#define outb_pit outb_p
23
24#endif /* __ASM_I8253_H */
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 260df4750949..ca9bd2069142 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -7,6 +7,7 @@
7 * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle 7 * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle
8 */ 8 */
9#include <linux/clockchips.h> 9#include <linux/clockchips.h>
10#include <linux/i8253.h>
10#include <linux/init.h> 11#include <linux/init.h>
11#include <linux/interrupt.h> 12#include <linux/interrupt.h>
12#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -15,7 +16,6 @@
15#include <linux/irq.h> 16#include <linux/irq.h>
16 17
17#include <asm/irq_cpu.h> 18#include <asm/irq_cpu.h>
18#include <asm/i8253.h>
19#include <asm/i8259.h> 19#include <asm/i8259.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/jazz.h> 21#include <asm/jazz.h>
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index 391221b6a6aa..be4ee7d63e04 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -3,96 +3,16 @@
3 * 3 *
4 */ 4 */
5#include <linux/clockchips.h> 5#include <linux/clockchips.h>
6#include <linux/init.h> 6#include <linux/i8253.h>
7#include <linux/interrupt.h>
8#include <linux/jiffies.h>
9#include <linux/module.h> 7#include <linux/module.h>
10#include <linux/smp.h> 8#include <linux/smp.h>
11#include <linux/spinlock.h>
12#include <linux/irq.h> 9#include <linux/irq.h>
13 10
14#include <asm/delay.h>
15#include <asm/i8253.h>
16#include <asm/io.h>
17#include <asm/time.h> 11#include <asm/time.h>
18 12
19DEFINE_RAW_SPINLOCK(i8253_lock);
20EXPORT_SYMBOL(i8253_lock);
21
22/*
23 * Initialize the PIT timer.
24 *
25 * This is also called after resume to bring the PIT into operation again.
26 */
27static void init_pit_timer(enum clock_event_mode mode,
28 struct clock_event_device *evt)
29{
30 raw_spin_lock(&i8253_lock);
31
32 switch(mode) {
33 case CLOCK_EVT_MODE_PERIODIC:
34 /* binary, mode 2, LSB/MSB, ch 0 */
35 outb_p(0x34, PIT_MODE);
36 outb_p(LATCH & 0xff , PIT_CH0); /* LSB */
37 outb(LATCH >> 8 , PIT_CH0); /* MSB */
38 break;
39
40 case CLOCK_EVT_MODE_SHUTDOWN:
41 case CLOCK_EVT_MODE_UNUSED:
42 if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
43 evt->mode == CLOCK_EVT_MODE_ONESHOT) {
44 outb_p(0x30, PIT_MODE);
45 outb_p(0, PIT_CH0);
46 outb_p(0, PIT_CH0);
47 }
48 break;
49
50 case CLOCK_EVT_MODE_ONESHOT:
51 /* One shot setup */
52 outb_p(0x38, PIT_MODE);
53 break;
54
55 case CLOCK_EVT_MODE_RESUME:
56 /* Nothing to do here */
57 break;
58 }
59 raw_spin_unlock(&i8253_lock);
60}
61
62/*
63 * Program the next event in oneshot mode
64 *
65 * Delta is given in PIT ticks
66 */
67static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
68{
69 raw_spin_lock(&i8253_lock);
70 outb_p(delta & 0xff , PIT_CH0); /* LSB */
71 outb(delta >> 8 , PIT_CH0); /* MSB */
72 raw_spin_unlock(&i8253_lock);
73
74 return 0;
75}
76
77/*
78 * On UP the PIT can serve all of the possible timer functions. On SMP systems
79 * it can be solely used for the global tick.
80 *
81 * The profiling and update capabilites are switched off once the local apic is
82 * registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
83 * !using_apic_timer decisions in do_timer_interrupt_hook()
84 */
85static struct clock_event_device pit_clockevent = {
86 .name = "pit",
87 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
88 .set_mode = init_pit_timer,
89 .set_next_event = pit_next_event,
90 .irq = 0,
91};
92
93static irqreturn_t timer_interrupt(int irq, void *dev_id) 13static irqreturn_t timer_interrupt(int irq, void *dev_id)
94{ 14{
95 pit_clockevent.event_handler(&pit_clockevent); 15 i8253_clockevent.event_handler(&i8253_clockevent);
96 16
97 return IRQ_HANDLED; 17 return IRQ_HANDLED;
98} 18}
@@ -103,25 +23,9 @@ static struct irqaction irq0 = {
103 .name = "timer" 23 .name = "timer"
104}; 24};
105 25
106/*
107 * Initialize the conversion factor and the min/max deltas of the clock event
108 * structure and register the clock event source with the framework.
109 */
110void __init setup_pit_timer(void) 26void __init setup_pit_timer(void)
111{ 27{
112 struct clock_event_device *cd = &pit_clockevent; 28 clockevent_i8253_init(true);
113 unsigned int cpu = smp_processor_id();
114
115 /*
116 * Start pit with the boot cpu mask and make it global after the
117 * IO_APIC has been initialized.
118 */
119 cd->cpumask = cpumask_of(cpu);
120 clockevent_set_clock(cd, CLOCK_TICK_RATE);
121 cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd);
122 cd->min_delta_ns = clockevent_delta2ns(0xF, cd);
123 clockevents_register_device(cd);
124
125 setup_irq(0, &irq0); 29 setup_irq(0, &irq0);
126} 30}
127 31
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 1620b83cd13e..f8ee945ee411 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/i8253.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/kernel_stat.h> 24#include <linux/kernel_stat.h>
24#include <linux/sched.h> 25#include <linux/sched.h>
@@ -31,7 +32,6 @@
31#include <asm/mipsregs.h> 32#include <asm/mipsregs.h>
32#include <asm/mipsmtregs.h> 33#include <asm/mipsmtregs.h>
33#include <asm/hardirq.h> 34#include <asm/hardirq.h>
34#include <asm/i8253.h>
35#include <asm/irq.h> 35#include <asm/irq.h>
36#include <asm/div64.h> 36#include <asm/div64.h>
37#include <asm/cpu.h> 37#include <asm/cpu.h>
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index 1a94c9894188..607192449335 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -10,6 +10,7 @@
10 * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org) 10 * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org)
11 */ 11 */
12#include <linux/bcd.h> 12#include <linux/bcd.h>
13#include <linux/i8253.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/irq.h> 15#include <linux/irq.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
@@ -20,7 +21,6 @@
20 21
21#include <asm/cpu.h> 22#include <asm/cpu.h>
22#include <asm/mipsregs.h> 23#include <asm/mipsregs.h>
23#include <asm/i8253.h>
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26#include <asm/time.h> 26#include <asm/time.h>
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 0904d4d30cb3..ec0be14996a4 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -1,11 +1,11 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <linux/i8253.h>
2#include <linux/interrupt.h> 3#include <linux/interrupt.h>
3#include <linux/irq.h> 4#include <linux/irq.h>
4#include <linux/smp.h> 5#include <linux/smp.h>
5#include <linux/time.h> 6#include <linux/time.h>
6#include <linux/clockchips.h> 7#include <linux/clockchips.h>
7 8
8#include <asm/i8253.h>
9#include <asm/sni.h> 9#include <asm/sni.h>
10#include <asm/time.h> 10#include <asm/time.h>
11#include <asm-generic/rtc.h> 11#include <asm-generic/rtc.h>
diff --git a/arch/powerpc/include/asm/8253pit.h b/arch/powerpc/include/asm/8253pit.h
deleted file mode 100644
index a71c9c1455a7..000000000000
--- a/arch/powerpc/include/asm/8253pit.h
+++ /dev/null
@@ -1,3 +0,0 @@
1/*
2 * 8253/8254 Programmable Interval Timer
3 */
diff --git a/arch/powerpc/platforms/amigaone/Kconfig b/arch/powerpc/platforms/amigaone/Kconfig
index 022476717718..128de25cc284 100644
--- a/arch/powerpc/platforms/amigaone/Kconfig
+++ b/arch/powerpc/platforms/amigaone/Kconfig
@@ -8,7 +8,7 @@ config AMIGAONE
8 select NOT_COHERENT_CACHE 8 select NOT_COHERENT_CACHE
9 select CHECK_CACHE_COHERENCY 9 select CHECK_CACHE_COHERENCY
10 select DEFAULT_UIMAGE 10 select DEFAULT_UIMAGE
11 select PCSPKR_PLATFORM 11 select HAVE_PCSPKR_PLATFORM
12 help 12 help
13 Select AmigaOne for the following machines: 13 Select AmigaOne for the following machines:
14 - AmigaOne SE/Teron CX (G3 only) 14 - AmigaOne SE/Teron CX (G3 only)
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index bc0b0efdc5fe..d3cdab582c5d 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -1,6 +1,7 @@
1config PPC_CHRP 1config PPC_CHRP
2 bool "Common Hardware Reference Platform (CHRP) based machines" 2 bool "Common Hardware Reference Platform (CHRP) based machines"
3 depends on 6xx 3 depends on 6xx
4 select HAVE_PCSPKR_PLATFORM
4 select MPIC 5 select MPIC
5 select PPC_I8259 6 select PPC_I8259
6 select PPC_INDIRECT_PCI 7 select PPC_INDIRECT_PCI
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
index bf8330ef2e76..f0536c7cda9f 100644
--- a/arch/powerpc/platforms/prep/Kconfig
+++ b/arch/powerpc/platforms/prep/Kconfig
@@ -1,6 +1,7 @@
1config PPC_PREP 1config PPC_PREP
2 bool "PowerPC Reference Platform (PReP) based machines" 2 bool "PowerPC Reference Platform (PReP) based machines"
3 depends on 6xx && BROKEN 3 depends on 6xx && BROKEN
4 select HAVE_PCSPKR_PLATFORM
4 select MPIC 5 select MPIC
5 select PPC_I8259 6 select PPC_I8259
6 select PPC_INDIRECT_PCI 7 select PPC_INDIRECT_PCI
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 71af4c5d6c05..05cf4769b88c 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -1,6 +1,7 @@
1config PPC_PSERIES 1config PPC_PSERIES
2 depends on PPC64 && PPC_BOOK3S 2 depends on PPC64 && PPC_BOOK3S
3 bool "IBM pSeries & new (POWER5-based) iSeries" 3 bool "IBM pSeries & new (POWER5-based) iSeries"
4 select HAVE_PCSPKR_PLATFORM
4 select MPIC 5 select MPIC
5 select PCI_MSI 6 select PCI_MSI
6 select PPC_XICS 7 select PPC_XICS
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7d45601b27e8..fc76e4209003 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -20,6 +20,7 @@ config X86
20 select HAVE_UNSTABLE_SCHED_CLOCK 20 select HAVE_UNSTABLE_SCHED_CLOCK
21 select HAVE_IDE 21 select HAVE_IDE
22 select HAVE_OPROFILE 22 select HAVE_OPROFILE
23 select HAVE_PCSPKR_PLATFORM
23 select HAVE_PERF_EVENTS 24 select HAVE_PERF_EVENTS
24 select HAVE_IRQ_WORK 25 select HAVE_IRQ_WORK
25 select HAVE_IOREMAP_PROT 26 select HAVE_IOREMAP_PROT
@@ -70,6 +71,7 @@ config X86
70 select IRQ_FORCED_THREADING 71 select IRQ_FORCED_THREADING
71 select USE_GENERIC_SMP_HELPERS if SMP 72 select USE_GENERIC_SMP_HELPERS if SMP
72 select HAVE_BPF_JIT if (X86_64 && NET) 73 select HAVE_BPF_JIT if (X86_64 && NET)
74 select CLKEVT_I8253
73 75
74config INSTRUCTION_DECODER 76config INSTRUCTION_DECODER
75 def_bool (KPROBES || PERF_EVENTS) 77 def_bool (KPROBES || PERF_EVENTS)
diff --git a/arch/x86/include/asm/apb_timer.h b/arch/x86/include/asm/apb_timer.h
index af60d8a2e288..082cf8184935 100644
--- a/arch/x86/include/asm/apb_timer.h
+++ b/arch/x86/include/asm/apb_timer.h
@@ -50,7 +50,6 @@
50#define APBT_DEV_USED 1 50#define APBT_DEV_USED 1
51 51
52extern void apbt_time_init(void); 52extern void apbt_time_init(void);
53extern struct clock_event_device *global_clock_event;
54extern unsigned long apbt_quick_calibrate(void); 53extern unsigned long apbt_quick_calibrate(void);
55extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu); 54extern int arch_setup_apbt_irqs(int irq, int trigger, int mask, int cpu);
56extern void apbt_setup_secondary_clock(void); 55extern void apbt_setup_secondary_clock(void);
diff --git a/arch/x86/include/asm/i8253.h b/arch/x86/include/asm/i8253.h
deleted file mode 100644
index 65aaa91d5850..000000000000
--- a/arch/x86/include/asm/i8253.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef _ASM_X86_I8253_H
2#define _ASM_X86_I8253_H
3
4/* i8253A PIT registers */
5#define PIT_MODE 0x43
6#define PIT_CH0 0x40
7#define PIT_CH2 0x42
8
9#define PIT_LATCH LATCH
10
11extern raw_spinlock_t i8253_lock;
12
13extern struct clock_event_device *global_clock_event;
14
15extern void setup_pit_timer(void);
16
17#define inb_pit inb_p
18#define outb_pit outb_p
19
20#endif /* _ASM_X86_I8253_H */
diff --git a/arch/x86/include/asm/time.h b/arch/x86/include/asm/time.h
index 7bdec4e9b739..92b8aec06970 100644
--- a/arch/x86/include/asm/time.h
+++ b/arch/x86/include/asm/time.h
@@ -1,10 +1,12 @@
1#ifndef _ASM_X86_TIME_H 1#ifndef _ASM_X86_TIME_H
2#define _ASM_X86_TIME_H 2#define _ASM_X86_TIME_H
3 3
4extern void hpet_time_init(void); 4#include <linux/clocksource.h>
5
6#include <asm/mc146818rtc.h> 5#include <asm/mc146818rtc.h>
7 6
7extern void hpet_time_init(void);
8extern void time_init(void); 8extern void time_init(void);
9 9
10extern struct clock_event_device *global_clock_event;
11
10#endif /* _ASM_X86_TIME_H */ 12#endif /* _ASM_X86_TIME_H */
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
index 289e92862fd9..2b6630d75e17 100644
--- a/arch/x86/kernel/apb_timer.c
+++ b/arch/x86/kernel/apb_timer.c
@@ -44,6 +44,7 @@
44#include <asm/fixmap.h> 44#include <asm/fixmap.h>
45#include <asm/apb_timer.h> 45#include <asm/apb_timer.h>
46#include <asm/mrst.h> 46#include <asm/mrst.h>
47#include <asm/time.h>
47 48
48#define APBT_MASK CLOCKSOURCE_MASK(32) 49#define APBT_MASK CLOCKSOURCE_MASK(32)
49#define APBT_SHIFT 22 50#define APBT_SHIFT 22
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b9338b8cf420..a7aed48356ef 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -27,6 +27,7 @@
27#include <linux/syscore_ops.h> 27#include <linux/syscore_ops.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/timex.h> 29#include <linux/timex.h>
30#include <linux/i8253.h>
30#include <linux/dmar.h> 31#include <linux/dmar.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/cpu.h> 33#include <linux/cpu.h>
@@ -39,7 +40,6 @@
39#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
40#include <asm/atomic.h> 41#include <asm/atomic.h>
41#include <asm/mpspec.h> 42#include <asm/mpspec.h>
42#include <asm/i8253.h>
43#include <asm/i8259.h> 43#include <asm/i8259.h>
44#include <asm/proto.h> 44#include <asm/proto.h>
45#include <asm/apic.h> 45#include <asm/apic.h>
@@ -48,6 +48,7 @@
48#include <asm/hpet.h> 48#include <asm/hpet.h>
49#include <asm/idle.h> 49#include <asm/idle.h>
50#include <asm/mtrr.h> 50#include <asm/mtrr.h>
51#include <asm/time.h>
51#include <asm/smp.h> 52#include <asm/smp.h>
52#include <asm/mce.h> 53#include <asm/mce.h>
53#include <asm/tsc.h> 54#include <asm/tsc.h>
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 965a7666c283..0371c484bb8a 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -229,11 +229,11 @@
229#include <linux/jiffies.h> 229#include <linux/jiffies.h>
230#include <linux/acpi.h> 230#include <linux/acpi.h>
231#include <linux/syscore_ops.h> 231#include <linux/syscore_ops.h>
232#include <linux/i8253.h>
232 233
233#include <asm/system.h> 234#include <asm/system.h>
234#include <asm/uaccess.h> 235#include <asm/uaccess.h>
235#include <asm/desc.h> 236#include <asm/desc.h>
236#include <asm/i8253.h>
237#include <asm/olpc.h> 237#include <asm/olpc.h>
238#include <asm/paravirt.h> 238#include <asm/paravirt.h>
239#include <asm/reboot.h> 239#include <asm/reboot.h>
@@ -1220,11 +1220,11 @@ static void reinit_timer(void)
1220 1220
1221 raw_spin_lock_irqsave(&i8253_lock, flags); 1221 raw_spin_lock_irqsave(&i8253_lock, flags);
1222 /* set the clock to HZ */ 1222 /* set the clock to HZ */
1223 outb_pit(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ 1223 outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
1224 udelay(10); 1224 udelay(10);
1225 outb_pit(LATCH & 0xff, PIT_CH0); /* LSB */ 1225 outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
1226 udelay(10); 1226 udelay(10);
1227 outb_pit(LATCH >> 8, PIT_CH0); /* MSB */ 1227 outb_p(LATCH >> 8, PIT_CH0); /* MSB */
1228 udelay(10); 1228 udelay(10);
1229 raw_spin_unlock_irqrestore(&i8253_lock, flags); 1229 raw_spin_unlock_irqrestore(&i8253_lock, flags);
1230#endif 1230#endif
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 6781765b3a0d..0f4b0651cd3f 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -4,6 +4,7 @@
4#include <linux/sysdev.h> 4#include <linux/sysdev.h>
5#include <linux/delay.h> 5#include <linux/delay.h>
6#include <linux/errno.h> 6#include <linux/errno.h>
7#include <linux/i8253.h>
7#include <linux/slab.h> 8#include <linux/slab.h>
8#include <linux/hpet.h> 9#include <linux/hpet.h>
9#include <linux/init.h> 10#include <linux/init.h>
@@ -12,8 +13,8 @@
12#include <linux/io.h> 13#include <linux/io.h>
13 14
14#include <asm/fixmap.h> 15#include <asm/fixmap.h>
15#include <asm/i8253.h>
16#include <asm/hpet.h> 16#include <asm/hpet.h>
17#include <asm/time.h>
17 18
18#define HPET_MASK CLOCKSOURCE_MASK(32) 19#define HPET_MASK CLOCKSOURCE_MASK(32)
19 20
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index fb66dc9e36cb..f2b96de3c7c1 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -3,113 +3,24 @@
3 * 3 *
4 */ 4 */
5#include <linux/clockchips.h> 5#include <linux/clockchips.h>
6#include <linux/interrupt.h>
7#include <linux/spinlock.h>
8#include <linux/jiffies.h>
9#include <linux/module.h> 6#include <linux/module.h>
10#include <linux/timex.h> 7#include <linux/timex.h>
11#include <linux/delay.h> 8#include <linux/i8253.h>
12#include <linux/init.h>
13#include <linux/io.h>
14 9
15#include <asm/i8253.h>
16#include <asm/hpet.h> 10#include <asm/hpet.h>
11#include <asm/time.h>
17#include <asm/smp.h> 12#include <asm/smp.h>
18 13
19DEFINE_RAW_SPINLOCK(i8253_lock);
20EXPORT_SYMBOL(i8253_lock);
21
22/* 14/*
23 * HPET replaces the PIT, when enabled. So we need to know, which of 15 * HPET replaces the PIT, when enabled. So we need to know, which of
24 * the two timers is used 16 * the two timers is used
25 */ 17 */
26struct clock_event_device *global_clock_event; 18struct clock_event_device *global_clock_event;
27 19
28/*
29 * Initialize the PIT timer.
30 *
31 * This is also called after resume to bring the PIT into operation again.
32 */
33static void init_pit_timer(enum clock_event_mode mode,
34 struct clock_event_device *evt)
35{
36 raw_spin_lock(&i8253_lock);
37
38 switch (mode) {
39 case CLOCK_EVT_MODE_PERIODIC:
40 /* binary, mode 2, LSB/MSB, ch 0 */
41 outb_pit(0x34, PIT_MODE);
42 outb_pit(LATCH & 0xff , PIT_CH0); /* LSB */
43 outb_pit(LATCH >> 8 , PIT_CH0); /* MSB */
44 break;
45
46 case CLOCK_EVT_MODE_SHUTDOWN:
47 case CLOCK_EVT_MODE_UNUSED:
48 if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
49 evt->mode == CLOCK_EVT_MODE_ONESHOT) {
50 outb_pit(0x30, PIT_MODE);
51 outb_pit(0, PIT_CH0);
52 outb_pit(0, PIT_CH0);
53 }
54 break;
55
56 case CLOCK_EVT_MODE_ONESHOT:
57 /* One shot setup */
58 outb_pit(0x38, PIT_MODE);
59 break;
60
61 case CLOCK_EVT_MODE_RESUME:
62 /* Nothing to do here */
63 break;
64 }
65 raw_spin_unlock(&i8253_lock);
66}
67
68/*
69 * Program the next event in oneshot mode
70 *
71 * Delta is given in PIT ticks
72 */
73static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
74{
75 raw_spin_lock(&i8253_lock);
76 outb_pit(delta & 0xff , PIT_CH0); /* LSB */
77 outb_pit(delta >> 8 , PIT_CH0); /* MSB */
78 raw_spin_unlock(&i8253_lock);
79
80 return 0;
81}
82
83/*
84 * On UP the PIT can serve all of the possible timer functions. On SMP systems
85 * it can be solely used for the global tick.
86 *
87 * The profiling and update capabilities are switched off once the local apic is
88 * registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
89 * !using_apic_timer decisions in do_timer_interrupt_hook()
90 */
91static struct clock_event_device pit_ce = {
92 .name = "pit",
93 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
94 .set_mode = init_pit_timer,
95 .set_next_event = pit_next_event,
96 .irq = 0,
97};
98
99/*
100 * Initialize the conversion factor and the min/max deltas of the clock event
101 * structure and register the clock event source with the framework.
102 */
103void __init setup_pit_timer(void) 20void __init setup_pit_timer(void)
104{ 21{
105 /* 22 clockevent_i8253_init(true);
106 * Start pit with the boot cpu mask and make it global after the 23 global_clock_event = &i8253_clockevent;
107 * IO_APIC has been initialized.
108 */
109 pit_ce.cpumask = cpumask_of(smp_processor_id());
110
111 clockevents_config_and_register(&pit_ce, CLOCK_TICK_RATE, 0xF, 0x7FFF);
112 global_clock_event = &pit_ce;
113} 24}
114 25
115#ifndef CONFIG_X86_64 26#ifndef CONFIG_X86_64
@@ -123,7 +34,7 @@ static int __init init_pit_clocksource(void)
123 * - when local APIC timer is active (PIT is switched off) 34 * - when local APIC timer is active (PIT is switched off)
124 */ 35 */
125 if (num_possible_cpus() > 1 || is_hpet_enabled() || 36 if (num_possible_cpus() > 1 || is_hpet_enabled() ||
126 pit_ce.mode != CLOCK_EVT_MODE_PERIODIC) 37 i8253_clockevent.mode != CLOCK_EVT_MODE_PERIODIC)
127 return 0; 38 return 0;
128 39
129 return clocksource_i8253_init(); 40 return clocksource_i8253_init();
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index 00cbb272627f..5a64d057be57 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -11,13 +11,13 @@
11 11
12#include <linux/clockchips.h> 12#include <linux/clockchips.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/i8253.h>
14#include <linux/time.h> 15#include <linux/time.h>
15#include <linux/mca.h> 16#include <linux/mca.h>
16 17
17#include <asm/vsyscall.h> 18#include <asm/vsyscall.h>
18#include <asm/x86_init.h> 19#include <asm/x86_init.h>
19#include <asm/i8259.h> 20#include <asm/i8259.h>
20#include <asm/i8253.h>
21#include <asm/timer.h> 21#include <asm/timer.h>
22#include <asm/hpet.h> 22#include <asm/hpet.h>
23#include <asm/time.h> 23#include <asm/time.h>
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 007c630904c1..b52c9ca146fc 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -155,7 +155,7 @@ else \
155 155
156#if (HD_DELAY > 0) 156#if (HD_DELAY > 0)
157 157
158#include <asm/i8253.h> 158#include <linux/i8253.h>
159 159
160unsigned long last_req; 160unsigned long last_req;
161 161
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 96c921910469..d8d3e02b912c 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -1,5 +1,14 @@
1config CLKSRC_I8253 1config CLKSRC_I8253
2 bool 2 bool
3 3
4config CLKEVT_I8253
5 bool
6
7config I8253_LOCK
8 bool
9
10config CLKBLD_I8253
11 def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
12
4config CLKSRC_MMIO 13config CLKSRC_MMIO
5 bool 14 bool
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index b995942a5060..7922a0cfc99f 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -6,5 +6,5 @@ obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o
6obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o 6obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
7obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o 7obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o
8obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o 8obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o
9obj-$(CONFIG_CLKSRC_I8253) += i8253.o 9obj-$(CONFIG_CLKBLD_I8253) += i8253.o
10obj-$(CONFIG_CLKSRC_MMIO) += mmio.o 10obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c
index 225c1761b372..27c49e60b7d6 100644
--- a/drivers/clocksource/i8253.c
+++ b/drivers/clocksource/i8253.c
@@ -1,14 +1,25 @@
1/* 1/*
2 * i8253 PIT clocksource 2 * i8253 PIT clocksource
3 */ 3 */
4#include <linux/clocksource.h> 4#include <linux/clockchips.h>
5#include <linux/init.h> 5#include <linux/init.h>
6#include <linux/io.h> 6#include <linux/io.h>
7#include <linux/spinlock.h> 7#include <linux/spinlock.h>
8#include <linux/timex.h> 8#include <linux/timex.h>
9#include <linux/module.h>
10#include <linux/i8253.h>
11#include <linux/smp.h>
9 12
10#include <asm/i8253.h> 13/*
14 * Protects access to I/O ports
15 *
16 * 0040-0043 : timer0, i8253 / i8254
17 * 0061-0061 : NMI Control Register which contains two speaker control bits.
18 */
19DEFINE_RAW_SPINLOCK(i8253_lock);
20EXPORT_SYMBOL(i8253_lock);
11 21
22#ifdef CONFIG_CLKSRC_I8253
12/* 23/*
13 * Since the PIT overflows every tick, its not very useful 24 * Since the PIT overflows every tick, its not very useful
14 * to just read by itself. So use jiffies to emulate a free 25 * to just read by itself. So use jiffies to emulate a free
@@ -37,15 +48,15 @@ static cycle_t i8253_read(struct clocksource *cs)
37 * count), it cannot be newer. 48 * count), it cannot be newer.
38 */ 49 */
39 jifs = jiffies; 50 jifs = jiffies;
40 outb_pit(0x00, PIT_MODE); /* latch the count ASAP */ 51 outb_p(0x00, PIT_MODE); /* latch the count ASAP */
41 count = inb_pit(PIT_CH0); /* read the latched count */ 52 count = inb_p(PIT_CH0); /* read the latched count */
42 count |= inb_pit(PIT_CH0) << 8; 53 count |= inb_p(PIT_CH0) << 8;
43 54
44 /* VIA686a test code... reset the latch if count > max + 1 */ 55 /* VIA686a test code... reset the latch if count > max + 1 */
45 if (count > LATCH) { 56 if (count > LATCH) {
46 outb_pit(0x34, PIT_MODE); 57 outb_p(0x34, PIT_MODE);
47 outb_pit(PIT_LATCH & 0xff, PIT_CH0); 58 outb_p(PIT_LATCH & 0xff, PIT_CH0);
48 outb_pit(PIT_LATCH >> 8, PIT_CH0); 59 outb_p(PIT_LATCH >> 8, PIT_CH0);
49 count = PIT_LATCH - 1; 60 count = PIT_LATCH - 1;
50 } 61 }
51 62
@@ -86,3 +97,90 @@ int __init clocksource_i8253_init(void)
86{ 97{
87 return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE); 98 return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE);
88} 99}
100#endif
101
102#ifdef CONFIG_CLKEVT_I8253
103/*
104 * Initialize the PIT timer.
105 *
106 * This is also called after resume to bring the PIT into operation again.
107 */
108static void init_pit_timer(enum clock_event_mode mode,
109 struct clock_event_device *evt)
110{
111 raw_spin_lock(&i8253_lock);
112
113 switch (mode) {
114 case CLOCK_EVT_MODE_PERIODIC:
115 /* binary, mode 2, LSB/MSB, ch 0 */
116 outb_p(0x34, PIT_MODE);
117 outb_p(LATCH & 0xff , PIT_CH0); /* LSB */
118 outb_p(LATCH >> 8 , PIT_CH0); /* MSB */
119 break;
120
121 case CLOCK_EVT_MODE_SHUTDOWN:
122 case CLOCK_EVT_MODE_UNUSED:
123 if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
124 evt->mode == CLOCK_EVT_MODE_ONESHOT) {
125 outb_p(0x30, PIT_MODE);
126 outb_p(0, PIT_CH0);
127 outb_p(0, PIT_CH0);
128 }
129 break;
130
131 case CLOCK_EVT_MODE_ONESHOT:
132 /* One shot setup */
133 outb_p(0x38, PIT_MODE);
134 break;
135
136 case CLOCK_EVT_MODE_RESUME:
137 /* Nothing to do here */
138 break;
139 }
140 raw_spin_unlock(&i8253_lock);
141}
142
143/*
144 * Program the next event in oneshot mode
145 *
146 * Delta is given in PIT ticks
147 */
148static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
149{
150 raw_spin_lock(&i8253_lock);
151 outb_p(delta & 0xff , PIT_CH0); /* LSB */
152 outb_p(delta >> 8 , PIT_CH0); /* MSB */
153 raw_spin_unlock(&i8253_lock);
154
155 return 0;
156}
157
158/*
159 * On UP the PIT can serve all of the possible timer functions. On SMP systems
160 * it can be solely used for the global tick.
161 */
162struct clock_event_device i8253_clockevent = {
163 .name = "pit",
164 .features = CLOCK_EVT_FEAT_PERIODIC,
165 .set_mode = init_pit_timer,
166 .set_next_event = pit_next_event,
167};
168
169/*
170 * Initialize the conversion factor and the min/max deltas of the clock event
171 * structure and register the clock event source with the framework.
172 */
173void __init clockevent_i8253_init(bool oneshot)
174{
175 if (oneshot)
176 i8253_clockevent.features |= CLOCK_EVT_FEAT_ONESHOT;
177 /*
178 * Start pit with the boot cpu mask. x86 might make it global
179 * when it is used as broadcast device later.
180 */
181 i8253_clockevent.cpumask = cpumask_of(smp_processor_id());
182
183 clockevents_config_and_register(&i8253_clockevent, PIT_TICK_RATE,
184 0xF, 0x7FFF);
185}
186#endif
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 5b8f59d6c3e8..c351aa421f8f 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -47,7 +47,7 @@ static void gameport_disconnect_port(struct gameport *gameport);
47 47
48#if defined(__i386__) 48#if defined(__i386__)
49 49
50#include <asm/i8253.h> 50#include <linux/i8253.h>
51 51
52#define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) 52#define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0))
53#define GET_TIME(x) do { x = get_time_pit(); } while (0) 53#define GET_TIME(x) do { x = get_time_pit(); } while (0)
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 4afe0a3b4884..9882971827e6 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -136,7 +136,7 @@ struct analog_port {
136 136
137#ifdef __i386__ 137#ifdef __i386__
138 138
139#include <asm/i8253.h> 139#include <linux/i8253.h>
140 140
141#define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) 141#define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0)
142#define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0))) 142#define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0)))
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index f080dd31499b..34f4d2e0f50f 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/i8253.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/input.h> 19#include <linux/input.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
@@ -25,14 +26,6 @@ MODULE_DESCRIPTION("PC Speaker beeper driver");
25MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
26MODULE_ALIAS("platform:pcspkr"); 27MODULE_ALIAS("platform:pcspkr");
27 28
28#if defined(CONFIG_MIPS) || defined(CONFIG_X86)
29/* Use the global PIT lock ! */
30#include <asm/i8253.h>
31#else
32#include <asm/8253pit.h>
33static DEFINE_RAW_SPINLOCK(i8253_lock);
34#endif
35
36static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 29static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
37{ 30{
38 unsigned int count = 0; 31 unsigned int count = 0;
diff --git a/include/linux/i8253.h b/include/linux/i8253.h
new file mode 100644
index 000000000000..e6bb36a97519
--- /dev/null
+++ b/include/linux/i8253.h
@@ -0,0 +1,29 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Machine specific IO port address definition for generic.
7 * Written by Osamu Tomita <tomita@cinet.co.jp>
8 */
9#ifndef __LINUX_I8253_H
10#define __LINUX_I8253_H
11
12#include <linux/param.h>
13#include <linux/spinlock.h>
14#include <linux/timex.h>
15
16/* i8253A PIT registers */
17#define PIT_MODE 0x43
18#define PIT_CH0 0x40
19#define PIT_CH2 0x42
20
21#define PIT_LATCH ((PIT_TICK_RATE + HZ/2) / HZ)
22
23extern raw_spinlock_t i8253_lock;
24extern struct clock_event_device i8253_clockevent;
25extern void clockevent_i8253_init(bool oneshot);
26
27extern void setup_pit_timer(void);
28
29#endif /* __LINUX_I8253_H */
diff --git a/init/Kconfig b/init/Kconfig
index 412c21b00d51..27b8a7a43261 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1007,14 +1007,19 @@ config ELF_CORE
1007 help 1007 help
1008 Enable support for generating core dumps. Disabling saves about 4k. 1008 Enable support for generating core dumps. Disabling saves about 4k.
1009 1009
1010
1010config PCSPKR_PLATFORM 1011config PCSPKR_PLATFORM
1011 bool "Enable PC-Speaker support" if EXPERT 1012 bool "Enable PC-Speaker support" if EXPERT
1012 depends on ALPHA || X86 || MIPS || PPC_PREP || PPC_CHRP || PPC_PSERIES 1013 depends on HAVE_PCSPKR_PLATFORM
1014 select I8253_LOCK
1013 default y 1015 default y
1014 help 1016 help
1015 This option allows to disable the internal PC-Speaker 1017 This option allows to disable the internal PC-Speaker
1016 support, saving some memory. 1018 support, saving some memory.
1017 1019
1020config HAVE_PCSPKR_PLATFORM
1021 bool
1022
1018config BASE_FULL 1023config BASE_FULL
1019 default y 1024 default y
1020 bool "Enable full-sized data structures for core" if EXPERT 1025 bool "Enable full-sized data structures for core" if EXPERT
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 4ff6c8cc5077..fc7a2dc410a1 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -10,14 +10,8 @@
10#define __PCSP_H__ 10#define __PCSP_H__
11 11
12#include <linux/hrtimer.h> 12#include <linux/hrtimer.h>
13#include <linux/i8253.h>
13#include <linux/timex.h> 14#include <linux/timex.h>
14#if defined(CONFIG_MIPS) || defined(CONFIG_X86)
15/* Use the global PIT lock ! */
16#include <asm/i8253.h>
17#else
18#include <asm/8253pit.h>
19static DEFINE_RAW_SPINLOCK(i8253_lock);
20#endif
21 15
22#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */ 16#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */
23#define PCSP_DEBUG 0 17#define PCSP_DEBUG 0