aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-02 22:37:26 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-02 22:37:26 -0400
commit29dd5a7733fcb72696e90247ffbab57b0a591f67 (patch)
treeaafbbdc38ea9f9ea42a594fc47b8bd37dc720c23
parent71527bf8332ced9a961827272fe2f83fc5514f42 (diff)
parent3be51f70e1f5e11a723d28b3dde26bc3aacdbc71 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (25 commits) [MIPS] Jazz: disable PIT; cleanup R4030 clockevent [MIPS] Bigsur supports highmem. [MIPS] mtx-1: Enable -Werror. [MIPS] mtx-1: Remove unused mtx1_sys_btn. [MIPS] Pb1200: Enable -Werror. [MIPS] Fix and cleanup the MIPS part of the (ab)use of CLOCK_TICK_RATE. [MIPS] SNI: register a02r clockevent; don't use PIT timer [MIPS] i8253.h: Remove all i8259 related definitions. [MIPS] i8253: Cleanup. [MIPS] Cobalt: Fix IRQ comment; the Cobalt kernel uses CP0 counter now. [MIPS] Pb1200: Fix warning. [MIPS] Pb1200: Fix warning. [MIPS] IP27: Fix build error. [MIPS] Excite: Fix build error. [MIPS] Sibyte: Split and move clock code. [MIPS] Sibyte: Fixes for oneshot timer mode. [MIPS] Sibyte: Remove blank line. [MIPS] Swarm: Fix build failure [MIPS] time: Code cleanups [MIPS] time: Remove now unused local_timer_interrupt. ...
-rw-r--r--arch/mips/Kconfig13
-rw-r--r--arch/mips/au1000/mtx-1/Makefile2
-rw-r--r--arch/mips/au1000/mtx-1/platform.c9
-rw-r--r--arch/mips/au1000/pb1200/Makefile2
-rw-r--r--arch/mips/au1000/pb1200/board_setup.c6
-rw-r--r--arch/mips/au1000/pb1200/irqmap.c100
-rw-r--r--arch/mips/basler/excite/excite_setup.c2
-rw-r--r--arch/mips/jazz/irq.c27
-rw-r--r--arch/mips/kernel/Makefile4
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c149
-rw-r--r--arch/mips/kernel/cevt-sb1250.c148
-rw-r--r--arch/mips/kernel/csrc-bcm1480.c54
-rw-r--r--arch/mips/kernel/csrc-sb1250.c70
-rw-r--r--arch/mips/kernel/i8253.c23
-rw-r--r--arch/mips/kernel/time.c73
-rw-r--r--arch/mips/qemu/q-irq.c1
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c4
-rw-r--r--arch/mips/sgi-ip32/ip32-platform.c2
-rw-r--r--arch/mips/sibyte/Kconfig14
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c16
-rw-r--r--arch/mips/sibyte/bcm1480/time.c159
-rw-r--r--arch/mips/sibyte/sb1250/irq.c14
-rw-r--r--arch/mips/sibyte/sb1250/time.c191
-rw-r--r--arch/mips/sni/time.c5
-rw-r--r--include/asm-mips/i8253.h15
-rw-r--r--include/asm-mips/mach-au1x00/timex.h13
-rw-r--r--include/asm-mips/mach-cobalt/irq.h3
-rw-r--r--include/asm-mips/mach-generic/timex.h13
-rw-r--r--include/asm-mips/mach-jazz/timex.h16
-rw-r--r--include/asm-mips/mach-qemu/timex.h16
-rw-r--r--include/asm-mips/mach-rm/timex.h13
-rw-r--r--include/asm-mips/time.h18
-rw-r--r--include/asm-mips/timex.h25
33 files changed, 575 insertions, 645 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 97da953eb5d0..2c7d6c240b73 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -546,6 +546,7 @@ config SIBYTE_BIGSUR
546 select SWAP_IO_SPACE 546 select SWAP_IO_SPACE
547 select SYS_HAS_CPU_SB1 547 select SYS_HAS_CPU_SB1
548 select SYS_SUPPORTS_BIG_ENDIAN 548 select SYS_SUPPORTS_BIG_ENDIAN
549 select SYS_SUPPORTS_HIGHMEM
549 select SYS_SUPPORTS_LITTLE_ENDIAN 550 select SYS_SUPPORTS_LITTLE_ENDIAN
550 551
551config SNI_RM 552config SNI_RM
@@ -733,15 +734,27 @@ config ARCH_MAY_HAVE_PC_FDC
733config BOOT_RAW 734config BOOT_RAW
734 bool 735 bool
735 736
737config CEVT_BCM1480
738 bool
739
736config CEVT_GT641XX 740config CEVT_GT641XX
737 bool 741 bool
738 742
739config CEVT_R4K 743config CEVT_R4K
740 bool 744 bool
741 745
746config CEVT_SB1250
747 bool
748
742config CEVT_TXX9 749config CEVT_TXX9
743 bool 750 bool
744 751
752config CSRC_BCM1480
753 bool
754
755config CSRC_SB1250
756 bool
757
745config CFE 758config CFE
746 bool 759 bool
747 760
diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile
index afa7007d67f7..85a90941de4f 100644
--- a/arch/mips/au1000/mtx-1/Makefile
+++ b/arch/mips/au1000/mtx-1/Makefile
@@ -9,3 +9,5 @@
9 9
10lib-y := init.o board_setup.o irqmap.o 10lib-y := init.o board_setup.o irqmap.o
11obj-y := platform.o 11obj-y := platform.o
12
13EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
index 01ebff677978..49c0fb409fea 100644
--- a/arch/mips/au1000/mtx-1/platform.c
+++ b/arch/mips/au1000/mtx-1/platform.c
@@ -34,15 +34,6 @@ static struct resource mtx1_wdt_res[] = {
34 } 34 }
35}; 35};
36 36
37static struct resource mtx1_sys_btn[] = {
38 [0] = {
39 .start = 7,
40 .end = 7,
41 .name = "mtx1-sys-btn-gpio",
42 .flags = IORESOURCE_IRQ,
43 }
44};
45
46static struct platform_device mtx1_wdt = { 37static struct platform_device mtx1_wdt = {
47 .name = "mtx1-wdt", 38 .name = "mtx1-wdt",
48 .id = 0, 39 .id = 0,
diff --git a/arch/mips/au1000/pb1200/Makefile b/arch/mips/au1000/pb1200/Makefile
index 22b673cf55af..970b1b1d5cda 100644
--- a/arch/mips/au1000/pb1200/Makefile
+++ b/arch/mips/au1000/pb1200/Makefile
@@ -3,3 +3,5 @@
3# 3#
4 4
5lib-y := init.o board_setup.o irqmap.o 5lib-y := init.o board_setup.o irqmap.o
6
7EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
index 5dbc9868f598..b98bebfa87c6 100644
--- a/arch/mips/au1000/pb1200/board_setup.c
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -68,9 +68,11 @@ void board_reset(void)
68void __init board_setup(void) 68void __init board_setup(void)
69{ 69{
70 char *argptr = NULL; 70 char *argptr = NULL;
71 u32 pin_func;
72 71
73#if 0 72#if 0
73 {
74 u32 pin_func;
75
74 /* Enable PSC1 SYNC for AC97. Normaly done in audio driver, 76 /* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
75 * but it is board specific code, so put it here. 77 * but it is board specific code, so put it here.
76 */ 78 */
@@ -81,11 +83,13 @@ void __init board_setup(void)
81 83
82 au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */ 84 au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
83 au_sync(); 85 au_sync();
86 }
84#endif 87#endif
85 88
86#if defined(CONFIG_I2C_AU1550) 89#if defined(CONFIG_I2C_AU1550)
87 { 90 {
88 u32 freq0, clksrc; 91 u32 freq0, clksrc;
92 u32 pin_func;
89 93
90 /* Select SMBUS in CPLD */ 94 /* Select SMBUS in CPLD */
91 bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); 95 bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
index bdf00e2a35e4..c096be4ed4e7 100644
--- a/arch/mips/au1000/pb1200/irqmap.c
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -94,51 +94,41 @@ inline void pb1200_disable_irq(unsigned int irq_nr)
94 bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN); 94 bcsr->intclr = 1<<(irq_nr - PB1200_INT_BEGIN);
95} 95}
96 96
97static unsigned int pb1200_startup_irq( unsigned int irq_nr ) 97static unsigned int pb1200_setup_cascade(void)
98{ 98{
99 if (++pb1200_cascade_en == 1) 99 int err;
100 { 100
101 request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, 101 err = request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
102 0, "Pb1200 Cascade", (void *)&pb1200_cascade_handler ); 102 0, "Pb1200 Cascade", &pb1200_cascade_handler);
103#ifdef CONFIG_MIPS_PB1200 103 if (err)
104 /* We have a problem with CPLD rev3. Enable a workaround */ 104 return err;
105 if( ((bcsr->whoami & BCSR_WHOAMI_CPLD)>>4) <= 3) 105
106 {
107 printk("\nWARNING!!!\n");
108 printk("\nWARNING!!!\n");
109 printk("\nWARNING!!!\n");
110 printk("\nWARNING!!!\n");
111 printk("\nWARNING!!!\n");
112 printk("\nWARNING!!!\n");
113 printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
114 printk("updated to latest revision. This software will not\n");
115 printk("work on anything less than CPLD rev4\n");
116 printk("\nWARNING!!!\n");
117 printk("\nWARNING!!!\n");
118 printk("\nWARNING!!!\n");
119 printk("\nWARNING!!!\n");
120 printk("\nWARNING!!!\n");
121 printk("\nWARNING!!!\n");
122 while(1);
123 }
124#endif
125 }
126 pb1200_enable_irq(irq_nr);
127 return 0; 106 return 0;
128} 107}
129 108
130static void pb1200_shutdown_irq( unsigned int irq_nr ) 109static unsigned int pb1200_startup_irq(unsigned int irq)
131{ 110{
132 pb1200_disable_irq(irq_nr); 111 if (++pb1200_cascade_en == 1) {
133 if (--pb1200_cascade_en == 0) 112 int res;
134 { 113
135 free_irq(AU1000_GPIO_7, &pb1200_cascade_handler ); 114 res = pb1200_setup_cascade();
115 if (res)
116 return res;
136 } 117 }
137 return; 118
119 pb1200_enable_irq(irq);
120
121 return 0;
138} 122}
139 123
140static struct irq_chip external_irq_type = 124static void pb1200_shutdown_irq(unsigned int irq)
141{ 125{
126 pb1200_disable_irq(irq);
127 if (--pb1200_cascade_en == 0)
128 free_irq(AU1000_GPIO_7, &pb1200_cascade_handler);
129}
130
131static struct irq_chip external_irq_type = {
142#ifdef CONFIG_MIPS_PB1200 132#ifdef CONFIG_MIPS_PB1200
143 .name = "Pb1200 Ext", 133 .name = "Pb1200 Ext",
144#endif 134#endif
@@ -155,16 +145,38 @@ static struct irq_chip external_irq_type =
155 145
156void _board_init_irq(void) 146void _board_init_irq(void)
157{ 147{
158 int irq_nr; 148 unsigned int irq;
159 149
160 for (irq_nr = PB1200_INT_BEGIN; irq_nr <= PB1200_INT_END; irq_nr++) 150#ifdef CONFIG_MIPS_PB1200
161 { 151 /* We have a problem with CPLD rev3. Enable a workaround */
162 set_irq_chip_and_handler(irq_nr, &external_irq_type, 152 if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
153 printk("\nWARNING!!!\n");
154 printk("\nWARNING!!!\n");
155 printk("\nWARNING!!!\n");
156 printk("\nWARNING!!!\n");
157 printk("\nWARNING!!!\n");
158 printk("\nWARNING!!!\n");
159 printk("Pb1200 must be at CPLD rev4. Please have Pb1200\n");
160 printk("updated to latest revision. This software will not\n");
161 printk("work on anything less than CPLD rev4\n");
162 printk("\nWARNING!!!\n");
163 printk("\nWARNING!!!\n");
164 printk("\nWARNING!!!\n");
165 printk("\nWARNING!!!\n");
166 printk("\nWARNING!!!\n");
167 printk("\nWARNING!!!\n");
168 panic("Game over. Your score is 0.");
169 }
170#endif
171
172 for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++) {
173 set_irq_chip_and_handler(irq, &external_irq_type,
163 handle_level_irq); 174 handle_level_irq);
164 pb1200_disable_irq(irq_nr); 175 pb1200_disable_irq(irq);
165 } 176 }
166 177
167 /* GPIO_7 can not be hooked here, so it is hooked upon first 178 /*
168 request of any source attached to the cascade */ 179 * GPIO_7 can not be hooked here, so it is hooked upon first
180 * request of any source attached to the cascade
181 */
169} 182}
170
diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c
index 24378b9223f9..6dd8f0d46d09 100644
--- a/arch/mips/basler/excite/excite_setup.c
+++ b/arch/mips/basler/excite/excite_setup.c
@@ -77,7 +77,7 @@ int titan_irqflags;
77void __init plat_time_init(void) 77void __init plat_time_init(void)
78{ 78{
79 const u32 modebit5 = ocd_readl(0x00e4); 79 const u32 modebit5 = ocd_readl(0x00e4);
80 unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2, 80 unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2;
81 unsigned int div = ((modebit5 >> 16) & 0x1f) + 2; 81 unsigned int div = ((modebit5 >> 16) & 0x1f) + 2;
82 82
83 if (div == 33) 83 if (div == 33)
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index ae25b480723e..d7f8a782aae4 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -97,9 +97,10 @@ asmlinkage void plat_irq_dispatch(void)
97 if (pending & IE_IRQ4) { 97 if (pending & IE_IRQ4) {
98 r4030_read_reg32(JAZZ_TIMER_REGISTER); 98 r4030_read_reg32(JAZZ_TIMER_REGISTER);
99 do_IRQ(JAZZ_TIMER_IRQ); 99 do_IRQ(JAZZ_TIMER_IRQ);
100 } else if (pending & IE_IRQ2) 100 } else if (pending & IE_IRQ2) {
101 do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK)); 101 irq = *(volatile u8 *)JAZZ_EISA_IRQ_ACK;
102 else if (pending & IE_IRQ1) { 102 do_IRQ(irq);
103 } else if (pending & IE_IRQ1) {
103 irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2; 104 irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2;
104 if (likely(irq > 0)) 105 if (likely(irq > 0))
105 do_IRQ(irq + JAZZ_IRQ_START - 1); 106 do_IRQ(irq + JAZZ_IRQ_START - 1);
@@ -117,16 +118,16 @@ static void r4030_set_mode(enum clock_event_mode mode,
117struct clock_event_device r4030_clockevent = { 118struct clock_event_device r4030_clockevent = {
118 .name = "r4030", 119 .name = "r4030",
119 .features = CLOCK_EVT_FEAT_PERIODIC, 120 .features = CLOCK_EVT_FEAT_PERIODIC,
120 .rating = 100, 121 .rating = 300,
121 .irq = JAZZ_TIMER_IRQ, 122 .irq = JAZZ_TIMER_IRQ,
122 .cpumask = CPU_MASK_CPU0,
123 .set_mode = r4030_set_mode, 123 .set_mode = r4030_set_mode,
124}; 124};
125 125
126static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) 126static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
127{ 127{
128 r4030_clockevent.event_handler(&r4030_clockevent); 128 struct clock_event_device *cd = dev_id;
129 129
130 cd->event_handler(cd);
130 return IRQ_HANDLED; 131 return IRQ_HANDLED;
131} 132}
132 133
@@ -134,15 +135,22 @@ static struct irqaction r4030_timer_irqaction = {
134 .handler = r4030_timer_interrupt, 135 .handler = r4030_timer_interrupt,
135 .flags = IRQF_DISABLED, 136 .flags = IRQF_DISABLED,
136 .mask = CPU_MASK_CPU0, 137 .mask = CPU_MASK_CPU0,
137 .name = "timer", 138 .name = "R4030 timer",
138}; 139};
139 140
140void __init plat_time_init(void) 141void __init plat_time_init(void)
141{ 142{
142 struct irqaction *irq = &r4030_timer_irqaction; 143 struct clock_event_device *cd = &r4030_clockevent;
144 struct irqaction *action = &r4030_timer_irqaction;
145 unsigned int cpu = smp_processor_id();
143 146
144 BUG_ON(HZ != 100); 147 BUG_ON(HZ != 100);
145 148
149 cd->cpumask = cpumask_of_cpu(cpu);
150 clockevents_register_device(cd);
151 action->dev_id = cd;
152 setup_irq(JAZZ_TIMER_IRQ, action);
153
146 /* 154 /*
147 * Set clock to 100Hz. 155 * Set clock to 100Hz.
148 * 156 *
@@ -150,8 +158,5 @@ void __init plat_time_init(void)
150 * a programmable 4-bit divider. This makes it fairly inflexible. 158 * a programmable 4-bit divider. This makes it fairly inflexible.
151 */ 159 */
152 r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); 160 r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
153 setup_irq(JAZZ_TIMER_IRQ, irq);
154
155 clockevents_register_device(&r4030_clockevent);
156 setup_pit_timer(); 161 setup_pit_timer();
157} 162}
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 3196509a28d5..b551535b7e48 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -8,9 +8,13 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
8 ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ 8 ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
9 time.o topology.o traps.o unaligned.o 9 time.o topology.o traps.o unaligned.o
10 10
11obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
11obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 12obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
12obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o 13obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
14obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
13obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o 15obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
16obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
17obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
14 18
15binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ 19binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
16 irix5sys.o sysirix.o 20 irix5sys.o sysirix.o
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
new file mode 100644
index 000000000000..21e6d63eb4d1
--- /dev/null
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -0,0 +1,149 @@
1/*
2 * Copyright (C) 2000,2001,2004 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18#include <linux/clockchips.h>
19#include <linux/interrupt.h>
20#include <linux/percpu.h>
21
22#include <asm/addrspace.h>
23#include <asm/io.h>
24#include <asm/time.h>
25
26#include <asm/sibyte/bcm1480_regs.h>
27#include <asm/sibyte/sb1250_regs.h>
28#include <asm/sibyte/bcm1480_int.h>
29#include <asm/sibyte/bcm1480_scd.h>
30
31#include <asm/sibyte/sb1250.h>
32
33#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
34#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
35#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
36
37/*
38 * The general purpose timer ticks at 1MHz independent if
39 * the rest of the system
40 */
41static void sibyte_set_mode(enum clock_event_mode mode,
42 struct clock_event_device *evt)
43{
44 unsigned int cpu = smp_processor_id();
45 void __iomem *cfg, *init;
46
47 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
48 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
49
50 switch (mode) {
51 case CLOCK_EVT_MODE_PERIODIC:
52 __raw_writeq(0, cfg);
53 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
54 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
55 cfg);
56 break;
57
58 case CLOCK_EVT_MODE_ONESHOT:
59 /* Stop the timer until we actually program a shot */
60 case CLOCK_EVT_MODE_SHUTDOWN:
61 __raw_writeq(0, cfg);
62 break;
63
64 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
65 case CLOCK_EVT_MODE_RESUME:
66 ;
67 }
68}
69
70static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
71{
72 unsigned int cpu = smp_processor_id();
73 void __iomem *cfg, *init;
74
75 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
76 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
77
78 __raw_writeq(delta - 1, init);
79 __raw_writeq(M_SCD_TIMER_ENABLE, cfg);
80
81 return 0;
82}
83
84static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
85{
86 unsigned int cpu = smp_processor_id();
87 struct clock_event_device *cd = dev_id;
88 void __iomem *cfg;
89 unsigned long tmode;
90
91 if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
92 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
93 else
94 tmode = 0;
95
96 /* ACK interrupt */
97 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
98 ____raw_writeq(tmode, cfg);
99
100 cd->event_handler(cd);
101
102 return IRQ_HANDLED;
103}
104
105static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
106static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
107static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
108
109void __cpuinit sb1480_clockevent_init(void)
110{
111 unsigned int cpu = smp_processor_id();
112 unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
113 struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
114 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
115 unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
116
117 BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
118
119 sprintf(name, "bcm1480-counter-%d", cpu);
120 cd->name = name;
121 cd->features = CLOCK_EVT_FEAT_PERIODIC |
122 CLOCK_EVT_FEAT_ONESHOT;
123 clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
124 cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
125 cd->min_delta_ns = clockevent_delta2ns(1, cd);
126 cd->rating = 200;
127 cd->irq = irq;
128 cd->cpumask = cpumask_of_cpu(cpu);
129 cd->set_next_event = sibyte_next_event;
130 cd->set_mode = sibyte_set_mode;
131 clockevents_register_device(cd);
132
133 bcm1480_mask_irq(cpu, irq);
134
135 /*
136 * Map the timer interrupt to IP[4] of this cpu
137 */
138 __raw_writeq(IMR_IP4_VAL,
139 IOADDR(A_BCM1480_IMR_REGISTER(cpu,
140 R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
141
142 bcm1480_unmask_irq(cpu, irq);
143
144 action->handler = sibyte_counter_handler;
145 action->flags = IRQF_DISABLED | IRQF_PERCPU;
146 action->name = name;
147 action->dev_id = cd;
148 setup_irq(irq, action);
149}
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
new file mode 100644
index 000000000000..e2029d0fc39b
--- /dev/null
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2000, 2001 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18#include <linux/clockchips.h>
19#include <linux/interrupt.h>
20#include <linux/percpu.h>
21
22#include <asm/addrspace.h>
23#include <asm/io.h>
24#include <asm/time.h>
25
26#include <asm/sibyte/sb1250.h>
27#include <asm/sibyte/sb1250_regs.h>
28#include <asm/sibyte/sb1250_int.h>
29#include <asm/sibyte/sb1250_scd.h>
30
31#define IMR_IP2_VAL K_INT_MAP_I0
32#define IMR_IP3_VAL K_INT_MAP_I1
33#define IMR_IP4_VAL K_INT_MAP_I2
34
35/*
36 * The general purpose timer ticks at 1MHz independent if
37 * the rest of the system
38 */
39static void sibyte_set_mode(enum clock_event_mode mode,
40 struct clock_event_device *evt)
41{
42 unsigned int cpu = smp_processor_id();
43 void __iomem *cfg, *init;
44
45 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
46 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
47
48 switch (mode) {
49 case CLOCK_EVT_MODE_PERIODIC:
50 __raw_writeq(0, cfg);
51 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
52 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
53 cfg);
54 break;
55
56 case CLOCK_EVT_MODE_ONESHOT:
57 /* Stop the timer until we actually program a shot */
58 case CLOCK_EVT_MODE_SHUTDOWN:
59 __raw_writeq(0, cfg);
60 break;
61
62 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
63 case CLOCK_EVT_MODE_RESUME:
64 ;
65 }
66}
67
68static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
69{
70 unsigned int cpu = smp_processor_id();
71 void __iomem *cfg, *init;
72
73 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
74 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
75
76 __raw_writeq(delta - 1, init);
77 __raw_writeq(M_SCD_TIMER_ENABLE, cfg);
78
79 return 0;
80}
81
82static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
83{
84 unsigned int cpu = smp_processor_id();
85 struct clock_event_device *cd = dev_id;
86 void __iomem *cfg;
87 unsigned long tmode;
88
89 if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
90 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
91 else
92 tmode = 0;
93
94 /* ACK interrupt */
95 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
96 ____raw_writeq(tmode, cfg);
97
98 cd->event_handler(cd);
99
100 return IRQ_HANDLED;
101}
102
103static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
104static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
105static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
106
107void __cpuinit sb1250_clockevent_init(void)
108{
109 unsigned int cpu = smp_processor_id();
110 unsigned int irq = K_INT_TIMER_0 + cpu;
111 struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
112 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
113 unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
114
115 /* Only have 4 general purpose timers, and we use last one as hpt */
116 BUG_ON(cpu > 2);
117
118 sprintf(name, "sb1250-counter-%d", cpu);
119 cd->name = name;
120 cd->features = CLOCK_EVT_FEAT_PERIODIC |
121 CLOCK_EVT_FEAT_ONESHOT;
122 clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
123 cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
124 cd->min_delta_ns = clockevent_delta2ns(1, cd);
125 cd->rating = 200;
126 cd->irq = irq;
127 cd->cpumask = cpumask_of_cpu(cpu);
128 cd->set_next_event = sibyte_next_event;
129 cd->set_mode = sibyte_set_mode;
130 clockevents_register_device(cd);
131
132 sb1250_mask_irq(cpu, irq);
133
134 /*
135 * Map the timer interrupt to IP[4] of this cpu
136 */
137 __raw_writeq(IMR_IP4_VAL,
138 IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
139 (irq << 3)));
140
141 sb1250_unmask_irq(cpu, irq);
142
143 action->handler = sibyte_counter_handler;
144 action->flags = IRQF_DISABLED | IRQF_PERCPU;
145 action->name = name;
146 action->dev_id = cd;
147 setup_irq(irq, action);
148}
diff --git a/arch/mips/kernel/csrc-bcm1480.c b/arch/mips/kernel/csrc-bcm1480.c
new file mode 100644
index 000000000000..868745e7184b
--- /dev/null
+++ b/arch/mips/kernel/csrc-bcm1480.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2000,2001,2004 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18#include <linux/clocksource.h>
19
20#include <asm/addrspace.h>
21#include <asm/io.h>
22#include <asm/time.h>
23
24#include <asm/sibyte/bcm1480_regs.h>
25#include <asm/sibyte/sb1250_regs.h>
26#include <asm/sibyte/bcm1480_int.h>
27#include <asm/sibyte/bcm1480_scd.h>
28
29#include <asm/sibyte/sb1250.h>
30
31static cycle_t bcm1480_hpt_read(void)
32{
33 return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
34}
35
36struct clocksource bcm1480_clocksource = {
37 .name = "zbbus-cycles",
38 .rating = 200,
39 .read = bcm1480_hpt_read,
40 .mask = CLOCKSOURCE_MASK(64),
41 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
42};
43
44void __init sb1480_clocksource_init(void)
45{
46 struct clocksource *cs = &bcm1480_clocksource;
47 unsigned int plldiv;
48 unsigned long zbbus;
49
50 plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
51 zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
52 clocksource_set_clock(cs, zbbus);
53 clocksource_register(cs);
54}
diff --git a/arch/mips/kernel/csrc-sb1250.c b/arch/mips/kernel/csrc-sb1250.c
new file mode 100644
index 000000000000..ebb16e668877
--- /dev/null
+++ b/arch/mips/kernel/csrc-sb1250.c
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2000, 2001 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18#include <linux/clocksource.h>
19
20#include <asm/addrspace.h>
21#include <asm/io.h>
22#include <asm/time.h>
23
24#include <asm/sibyte/sb1250.h>
25#include <asm/sibyte/sb1250_regs.h>
26#include <asm/sibyte/sb1250_int.h>
27#include <asm/sibyte/sb1250_scd.h>
28
29#define SB1250_HPT_NUM 3
30#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */
31
32/*
33 * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
34 * again.
35 */
36static cycle_t sb1250_hpt_read(void)
37{
38 unsigned int count;
39
40 count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));
41
42 return SB1250_HPT_VALUE - count;
43}
44
45struct clocksource bcm1250_clocksource = {
46 .name = "MIPS",
47 .rating = 200,
48 .read = sb1250_hpt_read,
49 .mask = CLOCKSOURCE_MASK(23),
50 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
51};
52
53void __init sb1250_clocksource_init(void)
54{
55 struct clocksource *cs = &bcm1250_clocksource;
56
57 /* Setup hpt using timer #3 but do not enable irq for it */
58 __raw_writeq(0,
59 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
60 R_SCD_TIMER_CFG)));
61 __raw_writeq(SB1250_HPT_VALUE,
62 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
63 R_SCD_TIMER_INIT)));
64 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
65 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
66 R_SCD_TIMER_CFG)));
67
68 clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
69 clocksource_register(cs);
70}
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index 5d9830df3595..a925abd8d29e 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -12,6 +12,7 @@
12#include <asm/delay.h> 12#include <asm/delay.h>
13#include <asm/i8253.h> 13#include <asm/i8253.h>
14#include <asm/io.h> 14#include <asm/io.h>
15#include <asm/time.h>
15 16
16static DEFINE_SPINLOCK(i8253_lock); 17static DEFINE_SPINLOCK(i8253_lock);
17 18
@@ -87,11 +88,10 @@ struct clock_event_device pit_clockevent = {
87 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 88 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
88 .set_mode = init_pit_timer, 89 .set_mode = init_pit_timer,
89 .set_next_event = pit_next_event, 90 .set_next_event = pit_next_event,
90 .shift = 32,
91 .irq = 0, 91 .irq = 0,
92}; 92};
93 93
94irqreturn_t timer_interrupt(int irq, void *dev_id) 94static irqreturn_t timer_interrupt(int irq, void *dev_id)
95{ 95{
96 pit_clockevent.event_handler(&pit_clockevent); 96 pit_clockevent.event_handler(&pit_clockevent);
97 97
@@ -111,19 +111,20 @@ static struct irqaction irq0 = {
111 */ 111 */
112void __init setup_pit_timer(void) 112void __init setup_pit_timer(void)
113{ 113{
114 struct clock_event_device *cd = &pit_clockevent;
115 unsigned int cpu = smp_processor_id();
116
114 /* 117 /*
115 * Start pit with the boot cpu mask and make it global after the 118 * Start pit with the boot cpu mask and make it global after the
116 * IO_APIC has been initialized. 119 * IO_APIC has been initialized.
117 */ 120 */
118 pit_clockevent.cpumask = cpumask_of_cpu(0); 121 cd->cpumask = cpumask_of_cpu(cpu);
119 pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); 122 clockevent_set_clock(cd, CLOCK_TICK_RATE);
120 pit_clockevent.max_delta_ns = 123 cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd);
121 clockevent_delta2ns(0x7FFF, &pit_clockevent); 124 cd->min_delta_ns = clockevent_delta2ns(0xF, cd);
122 pit_clockevent.min_delta_ns = 125 clockevents_register_device(cd);
123 clockevent_delta2ns(0xF, &pit_clockevent); 126
124 clockevents_register_device(&pit_clockevent); 127 irq0.mask = cpumask_of_cpu(cpu);
125
126 irq0.mask = cpumask_of_cpu(0);
127 setup_irq(0, &irq0); 128 setup_irq(0, &irq0);
128} 129}
129 130
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 27228f583dae..3284b9b4ecac 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -3,8 +3,7 @@
3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
4 * Copyright (c) 2003, 2004 Maciej W. Rozycki 4 * Copyright (c) 2003, 2004 Maciej W. Rozycki
5 * 5 *
6 * Common time service routines for MIPS machines. See 6 * Common time service routines for MIPS machines.
7 * Documentation/mips/time.README.
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -18,28 +17,17 @@
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/sched.h> 18#include <linux/sched.h>
20#include <linux/param.h> 19#include <linux/param.h>
21#include <linux/profile.h>
22#include <linux/time.h> 20#include <linux/time.h>
23#include <linux/timex.h> 21#include <linux/timex.h>
24#include <linux/smp.h> 22#include <linux/smp.h>
25#include <linux/kernel_stat.h>
26#include <linux/spinlock.h> 23#include <linux/spinlock.h>
27#include <linux/interrupt.h>
28#include <linux/module.h> 24#include <linux/module.h>
29#include <linux/kallsyms.h>
30 25
31#include <asm/bootinfo.h>
32#include <asm/cache.h>
33#include <asm/compiler.h>
34#include <asm/cpu.h>
35#include <asm/cpu-features.h> 26#include <asm/cpu-features.h>
36#include <asm/div64.h> 27#include <asm/div64.h>
37#include <asm/sections.h>
38#include <asm/smtc_ipi.h> 28#include <asm/smtc_ipi.h>
39#include <asm/time.h> 29#include <asm/time.h>
40 30
41#include <irq.h>
42
43/* 31/*
44 * forward reference 32 * forward reference
45 */ 33 */
@@ -63,14 +51,6 @@ int update_persistent_clock(struct timespec now)
63} 51}
64 52
65/* 53/*
66 * Null high precision timer functions for systems lacking one.
67 */
68static cycle_t null_hpt_read(void)
69{
70 return 0;
71}
72
73/*
74 * High precision timer functions for a R4k-compatible timer. 54 * High precision timer functions for a R4k-compatible timer.
75 */ 55 */
76static cycle_t c0_hpt_read(void) 56static cycle_t c0_hpt_read(void)
@@ -80,22 +60,6 @@ static cycle_t c0_hpt_read(void)
80 60
81int (*mips_timer_state)(void); 61int (*mips_timer_state)(void);
82 62
83/*
84 * local_timer_interrupt() does profiling and process accounting
85 * on a per-CPU basis.
86 *
87 * In UP mode, it is invoked from the (global) timer_interrupt.
88 *
89 * In SMP mode, it might invoked by per-CPU timer interrupt, or
90 * a broadcasted inter-processor interrupt which itself is triggered
91 * by the global timer interrupt.
92 */
93void local_timer_interrupt(int irq, void *dev_id)
94{
95 profile_tick(CPU_PROFILING);
96 update_process_times(user_mode(get_irq_regs()));
97}
98
99int null_perf_irq(void) 63int null_perf_irq(void)
100{ 64{
101 return 0; 65 return 0;
@@ -120,6 +84,13 @@ EXPORT_SYMBOL(perf_irq);
120 84
121unsigned int mips_hpt_frequency; 85unsigned int mips_hpt_frequency;
122 86
87static struct clocksource clocksource_mips = {
88 .name = "MIPS",
89 .read = c0_hpt_read,
90 .mask = CLOCKSOURCE_MASK(32),
91 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
92};
93
123static unsigned int __init calibrate_hpt(void) 94static unsigned int __init calibrate_hpt(void)
124{ 95{
125 cycle_t frequency, hpt_start, hpt_end, hpt_count, hz; 96 cycle_t frequency, hpt_start, hpt_end, hpt_count, hz;
@@ -162,12 +133,6 @@ static unsigned int __init calibrate_hpt(void)
162 return frequency >> log_2_loops; 133 return frequency >> log_2_loops;
163} 134}
164 135
165struct clocksource clocksource_mips = {
166 .name = "MIPS",
167 .mask = CLOCKSOURCE_MASK(32),
168 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
169};
170
171void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock) 136void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
172{ 137{
173 u64 temp; 138 u64 temp;
@@ -203,9 +168,6 @@ void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
203 168
204static void __init init_mips_clocksource(void) 169static void __init init_mips_clocksource(void)
205{ 170{
206 if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
207 return;
208
209 /* Calclate a somewhat reasonable rating value */ 171 /* Calclate a somewhat reasonable rating value */
210 clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; 172 clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
211 173
@@ -227,7 +189,7 @@ void __init __weak plat_time_init(void)
227 * setup_irq calls and each clock_event_device should use its own 189 * setup_irq calls and each clock_event_device should use its own
228 * struct irqrequest. 190 * struct irqrequest.
229 */ 191 */
230void __init plat_timer_setup(struct irqaction *irq) 192void __init plat_timer_setup(void)
231{ 193{
232 BUG(); 194 BUG();
233} 195}
@@ -236,21 +198,8 @@ void __init time_init(void)
236{ 198{
237 plat_time_init(); 199 plat_time_init();
238 200
239 /* Choose appropriate high precision timer routines. */ 201 if (cpu_has_counter && (mips_hpt_frequency || mips_timer_state)) {
240 if (!cpu_has_counter && !clocksource_mips.read)
241 /* No high precision timer -- sorry. */
242 clocksource_mips.read = null_hpt_read;
243 else if (!mips_hpt_frequency && !mips_timer_state) {
244 /* A high precision timer of unknown frequency. */
245 if (!clocksource_mips.read)
246 /* No external high precision timer -- use R4k. */
247 clocksource_mips.read = c0_hpt_read;
248 } else {
249 /* We know counter frequency. Or we can get it. */ 202 /* We know counter frequency. Or we can get it. */
250 if (!clocksource_mips.read) {
251 /* No external high precision timer -- use R4k. */
252 clocksource_mips.read = c0_hpt_read;
253 }
254 if (!mips_hpt_frequency) 203 if (!mips_hpt_frequency)
255 mips_hpt_frequency = calibrate_hpt(); 204 mips_hpt_frequency = calibrate_hpt();
256 205
@@ -258,8 +207,8 @@ void __init time_init(void)
258 printk("Using %u.%03u MHz high precision timer.\n", 207 printk("Using %u.%03u MHz high precision timer.\n",
259 ((mips_hpt_frequency + 500) / 1000) / 1000, 208 ((mips_hpt_frequency + 500) / 1000) / 1000,
260 ((mips_hpt_frequency + 500) / 1000) % 1000); 209 ((mips_hpt_frequency + 500) / 1000) % 1000);
210 init_mips_clocksource();
261 } 211 }
262 212
263 init_mips_clocksource();
264 mips_clockevent_init(); 213 mips_clockevent_init();
265} 214}
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c
index 4681757460a1..11f984767880 100644
--- a/arch/mips/qemu/q-irq.c
+++ b/arch/mips/qemu/q-irq.c
@@ -1,4 +1,5 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/interrupt.h>
2#include <linux/linkage.h> 3#include <linux/linkage.h>
3 4
4#include <asm/i8259.h> 5#include <asm/i8259.h>
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index dc59c3b708ed..08d45369be45 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -131,7 +131,7 @@ static struct irq_chip rt_irq_type = {
131static int rt_next_event(unsigned long delta, struct clock_event_device *evt) 131static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
132{ 132{
133 unsigned int cpu = smp_processor_id(); 133 unsigned int cpu = smp_processor_id();
134 int slice putoslice(cpu); 134 int slice = cputoslice(cpu);
135 unsigned long cnt; 135 unsigned long cnt;
136 136
137 cnt = LOCAL_HUB_L(PI_RT_COUNT); 137 cnt = LOCAL_HUB_L(PI_RT_COUNT);
@@ -169,7 +169,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
169 /* 169 /*
170 * Ack 170 * Ack
171 */ 171 */
172 LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, cnt); 172 LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, 0);
173 cd->event_handler(cd); 173 cd->event_handler(cd);
174 174
175 return IRQ_HANDLED; 175 return IRQ_HANDLED;
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c
index 7309e48d163d..77febd68fcd4 100644
--- a/arch/mips/sgi-ip32/ip32-platform.c
+++ b/arch/mips/sgi-ip32/ip32-platform.c
@@ -42,7 +42,7 @@ static struct platform_device uart8250_device = {
42static int __init uart8250_init(void) 42static int __init uart8250_init(void)
43{ 43{
44 uart8250_data[0].membase = (void __iomem *) &mace->isa.serial1; 44 uart8250_data[0].membase = (void __iomem *) &mace->isa.serial1;
45 uart8250_data[1].membase = (void __iomem *) &mace->isa.serial1; 45 uart8250_data[1].membase = (void __iomem *) &mace->isa.serial2;
46 46
47 return platform_device_register(&uart8250_device); 47 return platform_device_register(&uart8250_device);
48} 48}
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
index e8fb880272bd..366b19d33f77 100644
--- a/arch/mips/sibyte/Kconfig
+++ b/arch/mips/sibyte/Kconfig
@@ -1,5 +1,7 @@
1config SIBYTE_SB1250 1config SIBYTE_SB1250
2 bool 2 bool
3 select CEVT_SB1250
4 select CSRC_SB1250
3 select HW_HAS_PCI 5 select HW_HAS_PCI
4 select IRQ_CPU 6 select IRQ_CPU
5 select SIBYTE_ENABLE_LDT_IF_PCI 7 select SIBYTE_ENABLE_LDT_IF_PCI
@@ -9,6 +11,8 @@ config SIBYTE_SB1250
9 11
10config SIBYTE_BCM1120 12config SIBYTE_BCM1120
11 bool 13 bool
14 select CEVT_SB1250
15 select CSRC_SB1250
12 select IRQ_CPU 16 select IRQ_CPU
13 select SIBYTE_BCM112X 17 select SIBYTE_BCM112X
14 select SIBYTE_HAS_ZBUS_PROFILING 18 select SIBYTE_HAS_ZBUS_PROFILING
@@ -16,6 +20,8 @@ config SIBYTE_BCM1120
16 20
17config SIBYTE_BCM1125 21config SIBYTE_BCM1125
18 bool 22 bool
23 select CEVT_SB1250
24 select CSRC_SB1250
19 select HW_HAS_PCI 25 select HW_HAS_PCI
20 select IRQ_CPU 26 select IRQ_CPU
21 select SIBYTE_BCM112X 27 select SIBYTE_BCM112X
@@ -24,6 +30,8 @@ config SIBYTE_BCM1125
24 30
25config SIBYTE_BCM1125H 31config SIBYTE_BCM1125H
26 bool 32 bool
33 select CEVT_SB1250
34 select CSRC_SB1250
27 select HW_HAS_PCI 35 select HW_HAS_PCI
28 select IRQ_CPU 36 select IRQ_CPU
29 select SIBYTE_BCM112X 37 select SIBYTE_BCM112X
@@ -33,12 +41,16 @@ config SIBYTE_BCM1125H
33 41
34config SIBYTE_BCM112X 42config SIBYTE_BCM112X
35 bool 43 bool
44 select CEVT_SB1250
45 select CSRC_SB1250
36 select IRQ_CPU 46 select IRQ_CPU
37 select SIBYTE_SB1xxx_SOC 47 select SIBYTE_SB1xxx_SOC
38 select SIBYTE_HAS_ZBUS_PROFILING 48 select SIBYTE_HAS_ZBUS_PROFILING
39 49
40config SIBYTE_BCM1x80 50config SIBYTE_BCM1x80
41 bool 51 bool
52 select CEVT_BCM1480
53 select CSRC_BCM1480
42 select HW_HAS_PCI 54 select HW_HAS_PCI
43 select IRQ_CPU 55 select IRQ_CPU
44 select SIBYTE_HAS_ZBUS_PROFILING 56 select SIBYTE_HAS_ZBUS_PROFILING
@@ -47,6 +59,8 @@ config SIBYTE_BCM1x80
47 59
48config SIBYTE_BCM1x55 60config SIBYTE_BCM1x55
49 bool 61 bool
62 select CEVT_BCM1480
63 select CSRC_BCM1480
50 select HW_HAS_PCI 64 select HW_HAS_PCI
51 select IRQ_CPU 65 select IRQ_CPU
52 select SIBYTE_SB1xxx_SOC 66 select SIBYTE_SB1xxx_SOC
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 61790c4bfb60..e28d626255a3 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -265,21 +265,6 @@ void __init init_bcm1480_irqs(void)
265 } 265 }
266} 266}
267 267
268
269static irqreturn_t bcm1480_dummy_handler(int irq, void *dev_id)
270{
271 return IRQ_NONE;
272}
273
274static struct irqaction bcm1480_dummy_action = {
275 .handler = bcm1480_dummy_handler,
276 .flags = 0,
277 .mask = CPU_MASK_NONE,
278 .name = "bcm1480-private",
279 .next = NULL,
280 .dev_id = 0
281};
282
283/* 268/*
284 * init_IRQ is called early in the boot sequence from init/main.c. It 269 * init_IRQ is called early in the boot sequence from init/main.c. It
285 * is responsible for setting up the interrupt mapper and installing the 270 * is responsible for setting up the interrupt mapper and installing the
@@ -308,7 +293,6 @@ static struct irqaction bcm1480_dummy_action = {
308 293
309void __init arch_init_irq(void) 294void __init arch_init_irq(void)
310{ 295{
311
312 unsigned int i, cpu; 296 unsigned int i, cpu;
313 u64 tmp; 297 u64 tmp;
314 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | 298 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index bbf19bfabccb..1680a68952ae 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -15,163 +15,10 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18#include <linux/clockchips.h> 18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/irq.h>
21#include <linux/percpu.h>
22#include <linux/spinlock.h>
23 19
24#include <asm/addrspace.h> 20extern void sb1480_clockevent_init(void);
25#include <asm/time.h> 21extern void sb1480_clocksource_init(void);
26#include <asm/io.h>
27
28#include <asm/sibyte/bcm1480_regs.h>
29#include <asm/sibyte/sb1250_regs.h>
30#include <asm/sibyte/bcm1480_int.h>
31#include <asm/sibyte/bcm1480_scd.h>
32
33#include <asm/sibyte/sb1250.h>
34
35
36#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
37#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
38#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
39
40/*
41 * The general purpose timer ticks at 1MHz independent if
42 * the rest of the system
43 */
44static void sibyte_set_mode(enum clock_event_mode mode,
45 struct clock_event_device *evt)
46{
47 unsigned int cpu = smp_processor_id();
48 void __iomem *timer_cfg, *timer_init;
49
50 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
51 timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
52
53 switch (mode) {
54 case CLOCK_EVT_MODE_PERIODIC:
55 __raw_writeq(0, timer_cfg);
56 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
57 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
58 timer_cfg);
59 break;
60
61 case CLOCK_EVT_MODE_ONESHOT:
62 /* Stop the timer until we actually program a shot */
63 case CLOCK_EVT_MODE_SHUTDOWN:
64 __raw_writeq(0, timer_cfg);
65 break;
66
67 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
68 case CLOCK_EVT_MODE_RESUME:
69 ;
70 }
71}
72
73static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
74{
75 unsigned int cpu = smp_processor_id();
76 void __iomem *timer_init;
77 unsigned int cnt;
78 int res;
79
80 timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
81 cnt = __raw_readq(timer_init);
82 cnt += delta;
83 __raw_writeq(cnt, timer_init);
84 res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0;
85
86 return res;
87}
88
89static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
90{
91 unsigned int cpu = smp_processor_id();
92 struct clock_event_device *cd = dev_id;
93 void __iomem *timer_cfg;
94
95 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
96
97 /* Reset the timer */
98 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
99 timer_cfg);
100 cd->event_handler(cd);
101
102 return IRQ_HANDLED;
103}
104
105static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
106static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
107static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
108
109void __cpuinit sb1480_clockevent_init(void)
110{
111 unsigned int cpu = smp_processor_id();
112 unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
113 struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
114 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
115 unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
116
117 BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
118
119 sprintf(name, "bcm1480-counter %d", cpu);
120 cd->name = name;
121 cd->features = CLOCK_EVT_FEAT_PERIODIC |
122 CLOCK_EVT_FEAT_ONESHOT;
123 clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
124 cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
125 cd->min_delta_ns = clockevent_delta2ns(1, cd);
126 cd->rating = 200;
127 cd->irq = irq;
128 cd->cpumask = cpumask_of_cpu(cpu);
129 cd->set_next_event = sibyte_next_event;
130 cd->set_mode = sibyte_set_mode;
131 clockevents_register_device(cd);
132
133 bcm1480_mask_irq(cpu, irq);
134
135 /*
136 * Map timer interrupt to IP[4] of this cpu
137 */
138 __raw_writeq(IMR_IP4_VAL,
139 IOADDR(A_BCM1480_IMR_REGISTER(cpu,
140 R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
141
142 bcm1480_unmask_irq(cpu, irq);
143
144 action->handler = sibyte_counter_handler;
145 action->flags = IRQF_DISABLED | IRQF_PERCPU;
146 action->name = name;
147 action->dev_id = cd;
148 setup_irq(irq, action);
149}
150
151static cycle_t bcm1480_hpt_read(void)
152{
153 return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
154}
155
156struct clocksource bcm1480_clocksource = {
157 .name = "zbbus-cycles",
158 .rating = 200,
159 .read = bcm1480_hpt_read,
160 .mask = CLOCKSOURCE_MASK(64),
161 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
162};
163
164void __init sb1480_clocksource_init(void)
165{
166 struct clocksource *cs = &bcm1480_clocksource;
167 unsigned int plldiv;
168 unsigned long zbbus;
169
170 plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
171 zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
172 clocksource_set_clock(cs, zbbus);
173 clocksource_register(cs);
174}
175 22
176void __init plat_time_init(void) 23void __init plat_time_init(void)
177{ 24{
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 52d18fc91f32..eac9065ffe0c 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -236,20 +236,6 @@ void __init init_sb1250_irqs(void)
236} 236}
237 237
238 238
239static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id)
240{
241 return IRQ_NONE;
242}
243
244static struct irqaction sb1250_dummy_action = {
245 .handler = sb1250_dummy_handler,
246 .flags = 0,
247 .mask = CPU_MASK_NONE,
248 .name = "sb1250-private",
249 .next = NULL,
250 .dev_id = 0
251};
252
253/* 239/*
254 * arch_init_irq is called early in the boot sequence from init/main.c via 240 * arch_init_irq is called early in the boot sequence from init/main.c via
255 * init_IRQ. It is responsible for setting up the interrupt mapper and 241 * init_IRQ. It is responsible for setting up the interrupt mapper and
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 95ad34e3fbac..68337bf7a5aa 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -15,195 +15,10 @@
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */ 17 */
18#include <linux/init.h>
18 19
19/* 20extern void sb1250_clocksource_init(void);
20 * These are routines to set up and handle interrupts from the 21extern void sb1250_clockevent_init(void);
21 * sb1250 general purpose timer 0. We're using the timer as a
22 * system clock, so we set it up to run at 100 Hz. On every
23 * interrupt, we update our idea of what the time of day is,
24 * then call do_timer() in the architecture-independent kernel
25 * code to do general bookkeeping (e.g. update jiffies, run
26 * bottom halves, etc.)
27 */
28#include <linux/clockchips.h>
29#include <linux/interrupt.h>
30#include <linux/sched.h>
31#include <linux/spinlock.h>
32#include <linux/kernel_stat.h>
33
34#include <asm/irq.h>
35#include <asm/addrspace.h>
36#include <asm/time.h>
37#include <asm/io.h>
38
39#include <asm/sibyte/sb1250.h>
40#include <asm/sibyte/sb1250_regs.h>
41#include <asm/sibyte/sb1250_int.h>
42#include <asm/sibyte/sb1250_scd.h>
43
44
45#define IMR_IP2_VAL K_INT_MAP_I0
46#define IMR_IP3_VAL K_INT_MAP_I1
47#define IMR_IP4_VAL K_INT_MAP_I2
48
49#define SB1250_HPT_NUM 3
50#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */
51
52
53/*
54 * The general purpose timer ticks at 1 Mhz independent if
55 * the rest of the system
56 */
57static void sibyte_set_mode(enum clock_event_mode mode,
58 struct clock_event_device *evt)
59{
60 unsigned int cpu = smp_processor_id();
61 void __iomem *timer_cfg, *timer_init;
62
63 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
64 timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
65
66 switch(mode) {
67 case CLOCK_EVT_MODE_PERIODIC:
68 __raw_writeq(0, timer_cfg);
69 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
70 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
71 timer_cfg);
72 break;
73
74 case CLOCK_EVT_MODE_ONESHOT:
75 /* Stop the timer until we actually program a shot */
76 case CLOCK_EVT_MODE_SHUTDOWN:
77 __raw_writeq(0, timer_cfg);
78 break;
79
80 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
81 case CLOCK_EVT_MODE_RESUME:
82 ;
83 }
84}
85
86static int
87sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
88{
89 unsigned int cpu = smp_processor_id();
90 void __iomem *timer_cfg, *timer_init;
91
92 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
93 timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
94
95 __raw_writeq(0, timer_cfg);
96 __raw_writeq(delta, timer_init);
97 __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg);
98
99 return 0;
100}
101
102static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
103{
104 unsigned int cpu = smp_processor_id();
105 struct clock_event_device *cd = dev_id;
106
107 /* ACK interrupt */
108 ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
109 IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
110
111 cd->event_handler(cd);
112
113 return IRQ_HANDLED;
114}
115
116static struct irqaction sibyte_irqaction = {
117 .handler = sibyte_counter_handler,
118 .flags = IRQF_DISABLED | IRQF_PERCPU,
119 .name = "timer",
120};
121
122static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
123static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
124static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
125
126void __cpuinit sb1250_clockevent_init(void)
127{
128 unsigned int cpu = smp_processor_id();
129 unsigned int irq = K_INT_TIMER_0 + cpu;
130 struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
131 struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
132 unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
133
134 /* Only have 4 general purpose timers, and we use last one as hpt */
135 BUG_ON(cpu > 2);
136
137 sprintf(name, "bcm1480-counter %d", cpu);
138 cd->name = name;
139 cd->features = CLOCK_EVT_FEAT_PERIODIC |
140 CLOCK_EVT_FEAT_ONESHOT;
141 clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
142 cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
143 cd->min_delta_ns = clockevent_delta2ns(1, cd);
144 cd->rating = 200;
145 cd->irq = irq;
146 cd->cpumask = cpumask_of_cpu(cpu);
147 cd->set_next_event = sibyte_next_event;
148 cd->set_mode = sibyte_set_mode;
149 clockevents_register_device(cd);
150
151 sb1250_mask_irq(cpu, irq);
152
153 /* Map the timer interrupt to ip[4] of this cpu */
154 __raw_writeq(IMR_IP4_VAL,
155 IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
156 (irq << 3)));
157 cd->cpumask = cpumask_of_cpu(0);
158
159 sb1250_unmask_irq(cpu, irq);
160
161 action->handler = sibyte_counter_handler;
162 action->flags = IRQF_DISABLED | IRQF_PERCPU;
163 action->name = name;
164 action->dev_id = cd;
165 setup_irq(irq, &sibyte_irqaction);
166}
167
168/*
169 * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
170 * again.
171 */
172static cycle_t sb1250_hpt_read(void)
173{
174 unsigned int count;
175
176 count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));
177
178 return SB1250_HPT_VALUE - count;
179}
180
181struct clocksource bcm1250_clocksource = {
182 .name = "MIPS",
183 .rating = 200,
184 .read = sb1250_hpt_read,
185 .mask = CLOCKSOURCE_MASK(23),
186 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
187};
188
189void __init sb1250_clocksource_init(void)
190{
191 struct clocksource *cs = &bcm1250_clocksource;
192
193 /* Setup hpt using timer #3 but do not enable irq for it */
194 __raw_writeq(0,
195 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
196 R_SCD_TIMER_CFG)));
197 __raw_writeq(SB1250_HPT_VALUE,
198 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
199 R_SCD_TIMER_INIT)));
200 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
201 IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
202 R_SCD_TIMER_CFG)));
203
204 clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
205 clocksource_register(cs);
206}
207 22
208void __init plat_time_init(void) 23void __init plat_time_init(void)
209{ 24{
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 60bc62ef0935..6f339af08d22 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -1,6 +1,7 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <linux/interrupt.h> 2#include <linux/interrupt.h>
3#include <linux/time.h> 3#include <linux/time.h>
4#include <linux/clockchips.h>
4 5
5#include <asm/i8253.h> 6#include <asm/i8253.h>
6#include <asm/sni.h> 7#include <asm/sni.h>
@@ -80,7 +81,7 @@ static void __init sni_a20r_timer_setup(void)
80 unsigned int cpu = smp_processor_id(); 81 unsigned int cpu = smp_processor_id();
81 82
82 cd->cpumask = cpumask_of_cpu(cpu); 83 cd->cpumask = cpumask_of_cpu(cpu);
83 84 clockevents_register_device(cd);
84 action->dev_id = cd; 85 action->dev_id = cd;
85 setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction); 86 setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction);
86} 87}
@@ -169,8 +170,6 @@ void __init plat_time_init(void)
169 170
170 mips_hpt_frequency = r4k_tick * HZ; 171 mips_hpt_frequency = r4k_tick * HZ;
171 172
172 setup_pit_timer();
173
174 switch (sni_brd_type) { 173 switch (sni_brd_type) {
175 case SNI_BRD_10: 174 case SNI_BRD_10:
176 case SNI_BRD_10NEW: 175 case SNI_BRD_10NEW:
diff --git a/include/asm-mips/i8253.h b/include/asm-mips/i8253.h
index affb32ce4af9..778b2f023905 100644
--- a/include/asm-mips/i8253.h
+++ b/include/asm-mips/i8253.h
@@ -10,21 +10,6 @@
10#define PIT_CH0 0x40 10#define PIT_CH0 0x40
11#define PIT_CH2 0x42 11#define PIT_CH2 0x42
12 12
13/* i8259A PIC registers */
14#define PIC_MASTER_CMD 0x20
15#define PIC_MASTER_IMR 0x21
16#define PIC_MASTER_ISR PIC_MASTER_CMD
17#define PIC_MASTER_POLL PIC_MASTER_ISR
18#define PIC_MASTER_OCW3 PIC_MASTER_ISR
19#define PIC_SLAVE_CMD 0xa0
20#define PIC_SLAVE_IMR 0xa1
21
22/* i8259A PIC related value */
23#define PIC_CASCADE_IR 2
24#define MASTER_ICW4_DEFAULT 0x01
25#define SLAVE_ICW4_DEFAULT 0x01
26#define PIC_ICW4_AEOI 2
27
28extern void setup_pit_timer(void); 13extern void setup_pit_timer(void);
29 14
30#endif /* __ASM_I8253_H */ 15#endif /* __ASM_I8253_H */
diff --git a/include/asm-mips/mach-au1x00/timex.h b/include/asm-mips/mach-au1x00/timex.h
deleted file mode 100644
index e3ada66cb636..000000000000
--- a/include/asm-mips/mach-au1x00/timex.h
+++ /dev/null
@@ -1,13 +0,0 @@
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 * Copyright (C) 2003 by Ralf Baechle
7 */
8#ifndef __ASM_MACH_AU1X00_TIMEX_H
9#define __ASM_MACH_AU1X00_TIMEX_H
10
11#define CLOCK_TICK_RATE ((HZ * 100000UL) / 2)
12
13#endif /* __ASM_MACH_AU1X00_TIMEX_H */
diff --git a/include/asm-mips/mach-cobalt/irq.h b/include/asm-mips/mach-cobalt/irq.h
index 179d0e850b59..57c8c9ac5851 100644
--- a/include/asm-mips/mach-cobalt/irq.h
+++ b/include/asm-mips/mach-cobalt/irq.h
@@ -35,7 +35,7 @@
35 * 4 - ethernet 35 * 4 - ethernet
36 * 5 - 16550 UART 36 * 5 - 16550 UART
37 * 6 - cascade i8259 37 * 6 - cascade i8259
38 * 7 - CP0 counter (unused) 38 * 7 - CP0 counter
39 */ 39 */
40#define MIPS_CPU_IRQ_BASE 16 40#define MIPS_CPU_IRQ_BASE 16
41 41
@@ -48,7 +48,6 @@
48#define SCSI_IRQ (MIPS_CPU_IRQ_BASE + 5) 48#define SCSI_IRQ (MIPS_CPU_IRQ_BASE + 5)
49#define I8259_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 6) 49#define I8259_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 6)
50 50
51
52#define GT641XX_IRQ_BASE 24 51#define GT641XX_IRQ_BASE 24
53 52
54#include <asm/irq_gt641xx.h> 53#include <asm/irq_gt641xx.h>
diff --git a/include/asm-mips/mach-generic/timex.h b/include/asm-mips/mach-generic/timex.h
deleted file mode 100644
index 48b4cfaa0d50..000000000000
--- a/include/asm-mips/mach-generic/timex.h
+++ /dev/null
@@ -1,13 +0,0 @@
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 * Copyright (C) 2003, 2005 by Ralf Baechle
7 */
8#ifndef __ASM_MACH_GENERIC_TIMEX_H
9#define __ASM_MACH_GENERIC_TIMEX_H
10
11#define CLOCK_TICK_RATE 500000
12
13#endif /* __ASM_MACH_GENERIC_TIMEX_H */
diff --git a/include/asm-mips/mach-jazz/timex.h b/include/asm-mips/mach-jazz/timex.h
deleted file mode 100644
index 93affa33dfa8..000000000000
--- a/include/asm-mips/mach-jazz/timex.h
+++ /dev/null
@@ -1,16 +0,0 @@
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 * Copyright (C) 2003 by Ralf Baechle
7 */
8#ifndef __ASM_MACH_JAZZ_TIMEX_H
9#define __ASM_MACH_JAZZ_TIMEX_H
10
11/*
12 * Jazz is still using the R4030 100Hz counter
13 */
14#define CLOCK_TICK_RATE 100
15
16#endif /* __ASM_MACH_JAZZ_TIMEX_H */
diff --git a/include/asm-mips/mach-qemu/timex.h b/include/asm-mips/mach-qemu/timex.h
deleted file mode 100644
index cd543693fb0a..000000000000
--- a/include/asm-mips/mach-qemu/timex.h
+++ /dev/null
@@ -1,16 +0,0 @@
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 * Copyright (C) 2005 Daniel Jacobowitz
7 */
8#ifndef __ASM_MACH_QEMU_TIMEX_H
9#define __ASM_MACH_QEMU_TIMEX_H
10
11/*
12 * We use a simulated i8254 PIC...
13 */
14#define CLOCK_TICK_RATE 1193182
15
16#endif /* __ASM_MACH_QEMU_TIMEX_H */
diff --git a/include/asm-mips/mach-rm/timex.h b/include/asm-mips/mach-rm/timex.h
deleted file mode 100644
index 11ff6cb0f214..000000000000
--- a/include/asm-mips/mach-rm/timex.h
+++ /dev/null
@@ -1,13 +0,0 @@
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 * Copyright (C) 2003, 2005 by Ralf Baechle
7 */
8#ifndef __ASM_MACH_RM200_TIMEX_H
9#define __ASM_MACH_RM200_TIMEX_H
10
11#define CLOCK_TICK_RATE 1193182
12
13#endif /* __ASM_MACH_RM200_TIMEX_H */
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 0a6bc7dc158e..ee1663e64da1 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -10,15 +10,10 @@
10 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your 11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. 12 * option) any later version.
13 *
14 * Please refer to Documentation/mips/time.README.
15 */ 13 */
16#ifndef _ASM_TIME_H 14#ifndef _ASM_TIME_H
17#define _ASM_TIME_H 15#define _ASM_TIME_H
18 16
19#include <linux/interrupt.h>
20#include <linux/linkage.h>
21#include <linux/ptrace.h>
22#include <linux/rtc.h> 17#include <linux/rtc.h>
23#include <linux/spinlock.h> 18#include <linux/spinlock.h>
24#include <linux/clockchips.h> 19#include <linux/clockchips.h>
@@ -38,25 +33,12 @@ extern int rtc_mips_set_mmss(unsigned long);
38/* 33/*
39 * Timer interrupt functions. 34 * Timer interrupt functions.
40 * mips_timer_state is needed for high precision timer calibration. 35 * mips_timer_state is needed for high precision timer calibration.
41 * mips_timer_ack may be NULL if the interrupt is self-recoverable.
42 */ 36 */
43extern int (*mips_timer_state)(void); 37extern int (*mips_timer_state)(void);
44 38
45/* 39/*
46 * High precision timer clocksource.
47 * If .read is NULL, an R4k-compatible timer setup is attempted.
48 */
49extern struct clocksource clocksource_mips;
50
51/*
52 * profiling and process accouting is done separately in local_timer_interrupt
53 */
54extern void local_timer_interrupt(int irq, void *dev_id);
55
56/*
57 * board specific routines required by time_init(). 40 * board specific routines required by time_init().
58 */ 41 */
59struct irqaction;
60extern void plat_time_init(void); 42extern void plat_time_init(void);
61 43
62/* 44/*
diff --git a/include/asm-mips/timex.h b/include/asm-mips/timex.h
index 87c68ae76ff8..5816ad1569d6 100644
--- a/include/asm-mips/timex.h
+++ b/include/asm-mips/timex.h
@@ -13,27 +13,12 @@
13#include <asm/mipsregs.h> 13#include <asm/mipsregs.h>
14 14
15/* 15/*
16 * This is the frequency of the timer used for Linux's timer interrupt. 16 * This is the clock rate of the i8253 PIT. A MIPS system may not have
17 * The value should be defined as accurate as possible or under certain 17 * a PIT by the symbol is used all over the kernel including some APIs.
18 * circumstances Linux timekeeping might become inaccurate or fail. 18 * So keeping it defined to the number for the PIT is the only sane thing
19 * 19 * for now.
20 * For many system the exact clockrate of the timer isn't known but due to
21 * the way this value is used we can get away with a wrong value as long
22 * as this value is:
23 *
24 * - a multiple of HZ
25 * - a divisor of the actual rate
26 *
27 * 500000 is a good such cheat value.
28 *
29 * The obscure number 1193182 is the same as used by the original i8254
30 * time in legacy PC hardware; the chip unfortunately also found in a
31 * bunch of MIPS systems. The last remaining user of the i8254 for the
32 * timer interrupt is the RM200; it's a very standard system so there is
33 * no reason to make this a separate architecture.
34 */ 20 */
35 21#define CLOCK_TICK_RATE 1193182
36#include <timex.h>
37 22
38/* 23/*
39 * Standard way to access the cycle counter. 24 * Standard way to access the cycle counter.