aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/Kconfig76
-rw-r--r--arch/alpha/include/asm/machvec.h22
-rw-r--r--arch/alpha/include/asm/pal.h71
-rw-r--r--arch/alpha/include/asm/rtc.h11
-rw-r--r--arch/alpha/include/asm/string.h24
-rw-r--r--arch/alpha/include/uapi/asm/pal.h1
-rw-r--r--arch/alpha/kernel/Makefile1
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c1
-rw-r--r--arch/alpha/kernel/irq_alpha.c16
-rw-r--r--arch/alpha/kernel/machvec_impl.h5
-rw-r--r--arch/alpha/kernel/perf_event.c15
-rw-r--r--arch/alpha/kernel/process.c17
-rw-r--r--arch/alpha/kernel/proto.h6
-rw-r--r--arch/alpha/kernel/rtc.c323
-rw-r--r--arch/alpha/kernel/setup.c23
-rw-r--r--arch/alpha/kernel/smp.c33
-rw-r--r--arch/alpha/kernel/sys_jensen.c2
-rw-r--r--arch/alpha/kernel/sys_marvel.c55
-rw-r--r--arch/alpha/kernel/time.c405
-rw-r--r--arch/alpha/kernel/traps.c15
-rw-r--r--arch/alpha/lib/csum_partial_copy.c10
-rw-r--r--arch/alpha/lib/ev6-memset.S12
-rw-r--r--arch/alpha/lib/memset.S11
-rw-r--r--drivers/rtc/Kconfig10
24 files changed, 777 insertions, 388 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 135c674eaf9e..d39dc9b95a2c 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -16,8 +16,8 @@ config ALPHA
16 select ARCH_WANT_IPC_PARSE_VERSION 16 select ARCH_WANT_IPC_PARSE_VERSION
17 select ARCH_HAVE_NMI_SAFE_CMPXCHG 17 select ARCH_HAVE_NMI_SAFE_CMPXCHG
18 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 18 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
19 select GENERIC_CLOCKEVENTS
19 select GENERIC_SMP_IDLE_THREAD 20 select GENERIC_SMP_IDLE_THREAD
20 select GENERIC_CMOS_UPDATE
21 select GENERIC_STRNCPY_FROM_USER 21 select GENERIC_STRNCPY_FROM_USER
22 select GENERIC_STRNLEN_USER 22 select GENERIC_STRNLEN_USER
23 select HAVE_MOD_ARCH_SPECIFIC 23 select HAVE_MOD_ARCH_SPECIFIC
@@ -488,6 +488,20 @@ config VGA_HOSE
488 which always have multiple hoses, and whose consoles support it. 488 which always have multiple hoses, and whose consoles support it.
489 489
490 490
491config ALPHA_QEMU
492 bool "Run under QEMU emulation"
493 depends on !ALPHA_GENERIC
494 ---help---
495 Assume the presence of special features supported by QEMU PALcode
496 that reduce the overhead of system emulation.
497
498 Generic kernels will auto-detect QEMU. But when building a
499 system-specific kernel, the assumption is that we want to
500 elimiate as many runtime tests as possible.
501
502 If unsure, say N.
503
504
491config ALPHA_SRM 505config ALPHA_SRM
492 bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME 506 bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
493 depends on TTY 507 depends on TTY
@@ -572,6 +586,30 @@ config NUMA
572 Access). This option is for configuring high-end multiprocessor 586 Access). This option is for configuring high-end multiprocessor
573 server machines. If in doubt, say N. 587 server machines. If in doubt, say N.
574 588
589config ALPHA_WTINT
590 bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
591 default y if ALPHA_QEMU
592 default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
593 default n if !ALPHA_SRM && !ALPHA_GENERIC
594 default y if SMP
595 ---help---
596 The Wait for Interrupt (WTINT) PALcall attempts to place the CPU
597 to sleep until the next interrupt. This may reduce the power
598 consumed, and the heat produced by the computer. However, it has
599 the side effect of making the cycle counter unreliable as a timing
600 device across the sleep.
601
602 For emulation under QEMU, definitely say Y here, as we have other
603 mechanisms for measuring time than the cycle counter.
604
605 For EV4 (but not LCA), EV5 and EV56 systems, or for systems running
606 MILO, sleep mode is not supported so you might as well say N here.
607
608 For SMP systems we cannot use the cycle counter for timing anyway,
609 so you might as well say Y here.
610
611 If unsure, say N.
612
575config NODES_SHIFT 613config NODES_SHIFT
576 int 614 int
577 default "7" 615 default "7"
@@ -613,9 +651,41 @@ config VERBOSE_MCHECK_ON
613 651
614 Take the default (1) unless you want more control or more info. 652 Take the default (1) unless you want more control or more info.
615 653
654choice
655 prompt "Timer interrupt frequency (HZ)?"
656 default HZ_128 if ALPHA_QEMU
657 default HZ_1200 if ALPHA_RAWHIDE
658 default HZ_1024
659 ---help---
660 The frequency at which timer interrupts occur. A high frequency
661 minimizes latency, whereas a low frequency minimizes overhead of
662 process accounting. The later effect is especially significant
663 when being run under QEMU.
664
665 Note that some Alpha hardware cannot change the interrupt frequency
666 of the timer. If unsure, say 1024 (or 1200 for Rawhide).
667
668 config HZ_32
669 bool "32 Hz"
670 config HZ_64
671 bool "64 Hz"
672 config HZ_128
673 bool "128 Hz"
674 config HZ_256
675 bool "256 Hz"
676 config HZ_1024
677 bool "1024 Hz"
678 config HZ_1200
679 bool "1200 Hz"
680endchoice
681
616config HZ 682config HZ
617 int 683 int
618 default 1200 if ALPHA_RAWHIDE 684 default 32 if HZ_32
685 default 64 if HZ_64
686 default 128 if HZ_128
687 default 256 if HZ_256
688 default 1200 if HZ_1200
619 default 1024 689 default 1024
620 690
621source "drivers/pci/Kconfig" 691source "drivers/pci/Kconfig"
diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
index 72dbf2359270..75cb3641ed2f 100644
--- a/arch/alpha/include/asm/machvec.h
+++ b/arch/alpha/include/asm/machvec.h
@@ -33,6 +33,7 @@ struct alpha_machine_vector
33 33
34 int nr_irqs; 34 int nr_irqs;
35 int rtc_port; 35 int rtc_port;
36 int rtc_boot_cpu_only;
36 unsigned int max_asn; 37 unsigned int max_asn;
37 unsigned long max_isa_dma_address; 38 unsigned long max_isa_dma_address;
38 unsigned long irq_probe_mask; 39 unsigned long irq_probe_mask;
@@ -95,9 +96,6 @@ struct alpha_machine_vector
95 96
96 struct _alpha_agp_info *(*agp_info)(void); 97 struct _alpha_agp_info *(*agp_info)(void);
97 98
98 unsigned int (*rtc_get_time)(struct rtc_time *);
99 int (*rtc_set_time)(struct rtc_time *);
100
101 const char *vector_name; 99 const char *vector_name;
102 100
103 /* NUMA information */ 101 /* NUMA information */
@@ -126,13 +124,19 @@ extern struct alpha_machine_vector alpha_mv;
126 124
127#ifdef CONFIG_ALPHA_GENERIC 125#ifdef CONFIG_ALPHA_GENERIC
128extern int alpha_using_srm; 126extern int alpha_using_srm;
127extern int alpha_using_qemu;
129#else 128#else
130#ifdef CONFIG_ALPHA_SRM 129# ifdef CONFIG_ALPHA_SRM
131#define alpha_using_srm 1 130# define alpha_using_srm 1
132#else 131# else
133#define alpha_using_srm 0 132# define alpha_using_srm 0
134#endif 133# endif
134# ifdef CONFIG_ALPHA_QEMU
135# define alpha_using_qemu 1
136# else
137# define alpha_using_qemu 0
138# endif
135#endif /* GENERIC */ 139#endif /* GENERIC */
136 140
137#endif 141#endif /* __KERNEL__ */
138#endif /* __ALPHA_MACHVEC_H */ 142#endif /* __ALPHA_MACHVEC_H */
diff --git a/arch/alpha/include/asm/pal.h b/arch/alpha/include/asm/pal.h
index 6fcd2b5b08f0..5422a47646fc 100644
--- a/arch/alpha/include/asm/pal.h
+++ b/arch/alpha/include/asm/pal.h
@@ -89,6 +89,7 @@ __CALL_PAL_W1(wrmces, unsigned long);
89__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long); 89__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
90__CALL_PAL_W1(wrusp, unsigned long); 90__CALL_PAL_W1(wrusp, unsigned long);
91__CALL_PAL_W1(wrvptptr, unsigned long); 91__CALL_PAL_W1(wrvptptr, unsigned long);
92__CALL_PAL_RW1(wtint, unsigned long, unsigned long);
92 93
93/* 94/*
94 * TB routines.. 95 * TB routines..
@@ -111,5 +112,75 @@ __CALL_PAL_W1(wrvptptr, unsigned long);
111#define tbiap() __tbi(-1, /* no second argument */) 112#define tbiap() __tbi(-1, /* no second argument */)
112#define tbia() __tbi(-2, /* no second argument */) 113#define tbia() __tbi(-2, /* no second argument */)
113 114
115/*
116 * QEMU Cserv routines..
117 */
118
119static inline unsigned long
120qemu_get_walltime(void)
121{
122 register unsigned long v0 __asm__("$0");
123 register unsigned long a0 __asm__("$16") = 3;
124
125 asm("call_pal %2 # cserve get_time"
126 : "=r"(v0), "+r"(a0)
127 : "i"(PAL_cserve)
128 : "$17", "$18", "$19", "$20", "$21");
129
130 return v0;
131}
132
133static inline unsigned long
134qemu_get_alarm(void)
135{
136 register unsigned long v0 __asm__("$0");
137 register unsigned long a0 __asm__("$16") = 4;
138
139 asm("call_pal %2 # cserve get_alarm"
140 : "=r"(v0), "+r"(a0)
141 : "i"(PAL_cserve)
142 : "$17", "$18", "$19", "$20", "$21");
143
144 return v0;
145}
146
147static inline void
148qemu_set_alarm_rel(unsigned long expire)
149{
150 register unsigned long a0 __asm__("$16") = 5;
151 register unsigned long a1 __asm__("$17") = expire;
152
153 asm volatile("call_pal %2 # cserve set_alarm_rel"
154 : "+r"(a0), "+r"(a1)
155 : "i"(PAL_cserve)
156 : "$0", "$18", "$19", "$20", "$21");
157}
158
159static inline void
160qemu_set_alarm_abs(unsigned long expire)
161{
162 register unsigned long a0 __asm__("$16") = 6;
163 register unsigned long a1 __asm__("$17") = expire;
164
165 asm volatile("call_pal %2 # cserve set_alarm_abs"
166 : "+r"(a0), "+r"(a1)
167 : "i"(PAL_cserve)
168 : "$0", "$18", "$19", "$20", "$21");
169}
170
171static inline unsigned long
172qemu_get_vmtime(void)
173{
174 register unsigned long v0 __asm__("$0");
175 register unsigned long a0 __asm__("$16") = 7;
176
177 asm("call_pal %2 # cserve get_time"
178 : "=r"(v0), "+r"(a0)
179 : "i"(PAL_cserve)
180 : "$17", "$18", "$19", "$20", "$21");
181
182 return v0;
183}
184
114#endif /* !__ASSEMBLY__ */ 185#endif /* !__ASSEMBLY__ */
115#endif /* __ALPHA_PAL_H */ 186#endif /* __ALPHA_PAL_H */
diff --git a/arch/alpha/include/asm/rtc.h b/arch/alpha/include/asm/rtc.h
index d70408d36677..f71c3b0ed360 100644
--- a/arch/alpha/include/asm/rtc.h
+++ b/arch/alpha/include/asm/rtc.h
@@ -1,12 +1 @@
1#ifndef _ALPHA_RTC_H
2#define _ALPHA_RTC_H
3
4#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \
5 || defined(CONFIG_ALPHA_GENERIC)
6# define get_rtc_time alpha_mv.rtc_get_time
7# define set_rtc_time alpha_mv.rtc_set_time
8#endif
9
10#include <asm-generic/rtc.h> #include <asm-generic/rtc.h>
11
12#endif
diff --git a/arch/alpha/include/asm/string.h b/arch/alpha/include/asm/string.h
index b02b8a282940..c2911f591704 100644
--- a/arch/alpha/include/asm/string.h
+++ b/arch/alpha/include/asm/string.h
@@ -22,15 +22,27 @@ extern void * __memcpy(void *, const void *, size_t);
22 22
23#define __HAVE_ARCH_MEMSET 23#define __HAVE_ARCH_MEMSET
24extern void * __constant_c_memset(void *, unsigned long, size_t); 24extern void * __constant_c_memset(void *, unsigned long, size_t);
25extern void * ___memset(void *, int, size_t);
25extern void * __memset(void *, int, size_t); 26extern void * __memset(void *, int, size_t);
26extern void * memset(void *, int, size_t); 27extern void * memset(void *, int, size_t);
27 28
28#define memset(s, c, n) \ 29/* For gcc 3.x, we cannot have the inline function named "memset" because
29(__builtin_constant_p(c) \ 30 the __builtin_memset will attempt to resolve to the inline as well,
30 ? (__builtin_constant_p(n) && (c) == 0 \ 31 leading to a "sorry" about unimplemented recursive inlining. */
31 ? __builtin_memset((s),0,(n)) \ 32extern inline void *__memset(void *s, int c, size_t n)
32 : __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n))) \ 33{
33 : __memset((s),(c),(n))) 34 if (__builtin_constant_p(c)) {
35 if (__builtin_constant_p(n)) {
36 return __builtin_memset(s, c, n);
37 } else {
38 unsigned long c8 = (c & 0xff) * 0x0101010101010101UL;
39 return __constant_c_memset(s, c8, n);
40 }
41 }
42 return ___memset(s, c, n);
43}
44
45#define memset __memset
34 46
35#define __HAVE_ARCH_STRCPY 47#define __HAVE_ARCH_STRCPY
36extern char * strcpy(char *,const char *); 48extern char * strcpy(char *,const char *);
diff --git a/arch/alpha/include/uapi/asm/pal.h b/arch/alpha/include/uapi/asm/pal.h
index 3c0ce08e5f59..dfc8140b9088 100644
--- a/arch/alpha/include/uapi/asm/pal.h
+++ b/arch/alpha/include/uapi/asm/pal.h
@@ -46,6 +46,7 @@
46#define PAL_rdusp 58 46#define PAL_rdusp 58
47#define PAL_whami 60 47#define PAL_whami 60
48#define PAL_retsys 61 48#define PAL_retsys 61
49#define PAL_wtint 62
49#define PAL_rti 63 50#define PAL_rti 63
50 51
51 52
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 84ec46b38f7d..0d54650e78fc 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o
16obj-$(CONFIG_SRM_ENV) += srm_env.o 16obj-$(CONFIG_SRM_ENV) += srm_env.o
17obj-$(CONFIG_MODULES) += module.o 17obj-$(CONFIG_MODULES) += module.o
18obj-$(CONFIG_PERF_EVENTS) += perf_event.o 18obj-$(CONFIG_PERF_EVENTS) += perf_event.o
19obj-$(CONFIG_RTC_DRV_ALPHA) += rtc.o
19 20
20ifdef CONFIG_ALPHA_GENERIC 21ifdef CONFIG_ALPHA_GENERIC
21 22
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 89566b346c0f..f4c7ab6f43b0 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -40,6 +40,7 @@ EXPORT_SYMBOL(strrchr);
40EXPORT_SYMBOL(memmove); 40EXPORT_SYMBOL(memmove);
41EXPORT_SYMBOL(__memcpy); 41EXPORT_SYMBOL(__memcpy);
42EXPORT_SYMBOL(__memset); 42EXPORT_SYMBOL(__memset);
43EXPORT_SYMBOL(___memset);
43EXPORT_SYMBOL(__memsetw); 44EXPORT_SYMBOL(__memsetw);
44EXPORT_SYMBOL(__constant_c_memset); 45EXPORT_SYMBOL(__constant_c_memset);
45EXPORT_SYMBOL(copy_page); 46EXPORT_SYMBOL(copy_page);
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index 28e4429596f3..1c8625cb0e25 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -66,21 +66,7 @@ do_entInt(unsigned long type, unsigned long vector,
66 break; 66 break;
67 case 1: 67 case 1:
68 old_regs = set_irq_regs(regs); 68 old_regs = set_irq_regs(regs);
69#ifdef CONFIG_SMP
70 {
71 long cpu;
72
73 smp_percpu_timer_interrupt(regs);
74 cpu = smp_processor_id();
75 if (cpu != boot_cpuid) {
76 kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
77 } else {
78 handle_irq(RTC_IRQ);
79 }
80 }
81#else
82 handle_irq(RTC_IRQ); 69 handle_irq(RTC_IRQ);
83#endif
84 set_irq_regs(old_regs); 70 set_irq_regs(old_regs);
85 return; 71 return;
86 case 2: 72 case 2:
@@ -228,7 +214,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
228 */ 214 */
229 215
230struct irqaction timer_irqaction = { 216struct irqaction timer_irqaction = {
231 .handler = timer_interrupt, 217 .handler = rtc_timer_interrupt,
232 .name = "timer", 218 .name = "timer",
233}; 219};
234 220
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index 7fa62488bd16..f54bdf658cd0 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -43,10 +43,7 @@
43#define CAT1(x,y) x##y 43#define CAT1(x,y) x##y
44#define CAT(x,y) CAT1(x,y) 44#define CAT(x,y) CAT1(x,y)
45 45
46#define DO_DEFAULT_RTC \ 46#define DO_DEFAULT_RTC .rtc_port = 0x70
47 .rtc_port = 0x70, \
48 .rtc_get_time = common_get_rtc_time, \
49 .rtc_set_time = common_set_rtc_time
50 47
51#define DO_EV4_MMU \ 48#define DO_EV4_MMU \
52 .max_asn = EV4_MAX_ASN, \ 49 .max_asn = EV4_MAX_ASN, \
diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c
index d821b17047e0..c52e7f0ee5f6 100644
--- a/arch/alpha/kernel/perf_event.c
+++ b/arch/alpha/kernel/perf_event.c
@@ -83,6 +83,8 @@ struct alpha_pmu_t {
83 long pmc_left[3]; 83 long pmc_left[3];
84 /* Subroutine for allocation of PMCs. Enforces constraints. */ 84 /* Subroutine for allocation of PMCs. Enforces constraints. */
85 int (*check_constraints)(struct perf_event **, unsigned long *, int); 85 int (*check_constraints)(struct perf_event **, unsigned long *, int);
86 /* Subroutine for checking validity of a raw event for this PMU. */
87 int (*raw_event_valid)(u64 config);
86}; 88};
87 89
88/* 90/*
@@ -203,6 +205,12 @@ success:
203} 205}
204 206
205 207
208static int ev67_raw_event_valid(u64 config)
209{
210 return config >= EV67_CYCLES && config < EV67_LAST_ET;
211};
212
213
206static const struct alpha_pmu_t ev67_pmu = { 214static const struct alpha_pmu_t ev67_pmu = {
207 .event_map = ev67_perfmon_event_map, 215 .event_map = ev67_perfmon_event_map,
208 .max_events = ARRAY_SIZE(ev67_perfmon_event_map), 216 .max_events = ARRAY_SIZE(ev67_perfmon_event_map),
@@ -211,7 +219,8 @@ static const struct alpha_pmu_t ev67_pmu = {
211 .pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0}, 219 .pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0},
212 .pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0}, 220 .pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0},
213 .pmc_left = {16, 4, 0}, 221 .pmc_left = {16, 4, 0},
214 .check_constraints = ev67_check_constraints 222 .check_constraints = ev67_check_constraints,
223 .raw_event_valid = ev67_raw_event_valid,
215}; 224};
216 225
217 226
@@ -609,7 +618,9 @@ static int __hw_perf_event_init(struct perf_event *event)
609 } else if (attr->type == PERF_TYPE_HW_CACHE) { 618 } else if (attr->type == PERF_TYPE_HW_CACHE) {
610 return -EOPNOTSUPP; 619 return -EOPNOTSUPP;
611 } else if (attr->type == PERF_TYPE_RAW) { 620 } else if (attr->type == PERF_TYPE_RAW) {
612 ev = attr->config & 0xff; 621 if (!alpha_pmu->raw_event_valid(attr->config))
622 return -EINVAL;
623 ev = attr->config;
613 } else { 624 } else {
614 return -EOPNOTSUPP; 625 return -EOPNOTSUPP;
615 } 626 }
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index f2360a74e5d5..1941a07b5811 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -46,6 +46,23 @@
46void (*pm_power_off)(void) = machine_power_off; 46void (*pm_power_off)(void) = machine_power_off;
47EXPORT_SYMBOL(pm_power_off); 47EXPORT_SYMBOL(pm_power_off);
48 48
49#ifdef CONFIG_ALPHA_WTINT
50/*
51 * Sleep the CPU.
52 * EV6, LCA45 and QEMU know how to power down, skipping N timer interrupts.
53 */
54void arch_cpu_idle(void)
55{
56 wtint(0);
57 local_irq_enable();
58}
59
60void arch_cpu_idle_dead(void)
61{
62 wtint(INT_MAX);
63}
64#endif /* ALPHA_WTINT */
65
49struct halt_info { 66struct halt_info {
50 int mode; 67 int mode;
51 char *restart_cmd; 68 char *restart_cmd;
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index d3e52d3fd592..da2d6ec9c370 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -135,17 +135,15 @@ extern void unregister_srm_console(void);
135/* smp.c */ 135/* smp.c */
136extern void setup_smp(void); 136extern void setup_smp(void);
137extern void handle_ipi(struct pt_regs *); 137extern void handle_ipi(struct pt_regs *);
138extern void smp_percpu_timer_interrupt(struct pt_regs *);
139 138
140/* bios32.c */ 139/* bios32.c */
141/* extern void reset_for_srm(void); */ 140/* extern void reset_for_srm(void); */
142 141
143/* time.c */ 142/* time.c */
144extern irqreturn_t timer_interrupt(int irq, void *dev); 143extern irqreturn_t rtc_timer_interrupt(int irq, void *dev);
144extern void init_clockevent(void);
145extern void common_init_rtc(void); 145extern void common_init_rtc(void);
146extern unsigned long est_cycle_freq; 146extern unsigned long est_cycle_freq;
147extern unsigned int common_get_rtc_time(struct rtc_time *time);
148extern int common_set_rtc_time(struct rtc_time *time);
149 147
150/* smc37c93x.c */ 148/* smc37c93x.c */
151extern void SMC93x_Init(void); 149extern void SMC93x_Init(void);
diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c
new file mode 100644
index 000000000000..c8d284d8521f
--- /dev/null
+++ b/arch/alpha/kernel/rtc.c
@@ -0,0 +1,323 @@
1/*
2 * linux/arch/alpha/kernel/rtc.c
3 *
4 * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds
5 *
6 * This file contains date handling.
7 */
8#include <linux/errno.h>
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/param.h>
12#include <linux/string.h>
13#include <linux/mc146818rtc.h>
14#include <linux/bcd.h>
15#include <linux/rtc.h>
16#include <linux/platform_device.h>
17
18#include <asm/rtc.h>
19
20#include "proto.h"
21
22
23/*
24 * Support for the RTC device.
25 *
26 * We don't want to use the rtc-cmos driver, because we don't want to support
27 * alarms, as that would be indistinguishable from timer interrupts.
28 *
29 * Further, generic code is really, really tied to a 1900 epoch. This is
30 * true in __get_rtc_time as well as the users of struct rtc_time e.g.
31 * rtc_tm_to_time. Thankfully all of the other epochs in use are later
32 * than 1900, and so it's easy to adjust.
33 */
34
35static unsigned long rtc_epoch;
36
37static int __init
38specifiy_epoch(char *str)
39{
40 unsigned long epoch = simple_strtoul(str, NULL, 0);
41 if (epoch < 1900)
42 printk("Ignoring invalid user specified epoch %lu\n", epoch);
43 else
44 rtc_epoch = epoch;
45 return 1;
46}
47__setup("epoch=", specifiy_epoch);
48
49static void __init
50init_rtc_epoch(void)
51{
52 int epoch, year, ctrl;
53
54 if (rtc_epoch != 0) {
55 /* The epoch was specified on the command-line. */
56 return;
57 }
58
59 /* Detect the epoch in use on this computer. */
60 ctrl = CMOS_READ(RTC_CONTROL);
61 year = CMOS_READ(RTC_YEAR);
62 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
63 year = bcd2bin(year);
64
65 /* PC-like is standard; used for year >= 70 */
66 epoch = 1900;
67 if (year < 20) {
68 epoch = 2000;
69 } else if (year >= 20 && year < 48) {
70 /* NT epoch */
71 epoch = 1980;
72 } else if (year >= 48 && year < 70) {
73 /* Digital UNIX epoch */
74 epoch = 1952;
75 }
76 rtc_epoch = epoch;
77
78 printk(KERN_INFO "Using epoch %d for rtc year %d\n", epoch, year);
79}
80
81static int
82alpha_rtc_read_time(struct device *dev, struct rtc_time *tm)
83{
84 __get_rtc_time(tm);
85
86 /* Adjust for non-default epochs. It's easier to depend on the
87 generic __get_rtc_time and adjust the epoch here than create
88 a copy of __get_rtc_time with the edits we need. */
89 if (rtc_epoch != 1900) {
90 int year = tm->tm_year;
91 /* Undo the century adjustment made in __get_rtc_time. */
92 if (year >= 100)
93 year -= 100;
94 year += rtc_epoch - 1900;
95 /* Redo the century adjustment with the epoch in place. */
96 if (year <= 69)
97 year += 100;
98 tm->tm_year = year;
99 }
100
101 return rtc_valid_tm(tm);
102}
103
104static int
105alpha_rtc_set_time(struct device *dev, struct rtc_time *tm)
106{
107 struct rtc_time xtm;
108
109 if (rtc_epoch != 1900) {
110 xtm = *tm;
111 xtm.tm_year -= rtc_epoch - 1900;
112 tm = &xtm;
113 }
114
115 return __set_rtc_time(tm);
116}
117
118static int
119alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime)
120{
121 int retval = 0;
122 int real_seconds, real_minutes, cmos_minutes;
123 unsigned char save_control, save_freq_select;
124
125 /* Note: This code only updates minutes and seconds. Comments
126 indicate this was to avoid messing with unknown time zones,
127 and with the epoch nonsense described above. In order for
128 this to work, the existing clock cannot be off by more than
129 15 minutes.
130
131 ??? This choice is may be out of date. The x86 port does
132 not have problems with timezones, and the epoch processing has
133 now been fixed in alpha_set_rtc_time.
134
135 In either case, one can always force a full rtc update with
136 the userland hwclock program, so surely 15 minute accuracy
137 is no real burden. */
138
139 /* In order to set the CMOS clock precisely, we have to be called
140 500 ms after the second nowtime has started, because when
141 nowtime is written into the registers of the CMOS clock, it will
142 jump to the next second precisely 500 ms later. Check the Motorola
143 MC146818A or Dallas DS12887 data sheet for details. */
144
145 /* irq are locally disabled here */
146 spin_lock(&rtc_lock);
147 /* Tell the clock it's being set */
148 save_control = CMOS_READ(RTC_CONTROL);
149 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
150
151 /* Stop and reset prescaler */
152 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
153 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
154
155 cmos_minutes = CMOS_READ(RTC_MINUTES);
156 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
157 cmos_minutes = bcd2bin(cmos_minutes);
158
159 real_seconds = nowtime % 60;
160 real_minutes = nowtime / 60;
161 if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) {
162 /* correct for half hour time zone */
163 real_minutes += 30;
164 }
165 real_minutes %= 60;
166
167 if (abs(real_minutes - cmos_minutes) < 30) {
168 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
169 real_seconds = bin2bcd(real_seconds);
170 real_minutes = bin2bcd(real_minutes);
171 }
172 CMOS_WRITE(real_seconds,RTC_SECONDS);
173 CMOS_WRITE(real_minutes,RTC_MINUTES);
174 } else {
175 printk_once(KERN_NOTICE
176 "set_rtc_mmss: can't update from %d to %d\n",
177 cmos_minutes, real_minutes);
178 retval = -1;
179 }
180
181 /* The following flags have to be released exactly in this order,
182 * otherwise the DS12887 (popular MC146818A clone with integrated
183 * battery and quartz) will not reset the oscillator and will not
184 * update precisely 500 ms later. You won't find this mentioned in
185 * the Dallas Semiconductor data sheets, but who believes data
186 * sheets anyway ... -- Markus Kuhn
187 */
188 CMOS_WRITE(save_control, RTC_CONTROL);
189 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
190 spin_unlock(&rtc_lock);
191
192 return retval;
193}
194
195static int
196alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
197{
198 switch (cmd) {
199 case RTC_EPOCH_READ:
200 return put_user(rtc_epoch, (unsigned long __user *)arg);
201 case RTC_EPOCH_SET:
202 if (arg < 1900)
203 return -EINVAL;
204 rtc_epoch = arg;
205 return 0;
206 default:
207 return -ENOIOCTLCMD;
208 }
209}
210
211static const struct rtc_class_ops alpha_rtc_ops = {
212 .read_time = alpha_rtc_read_time,
213 .set_time = alpha_rtc_set_time,
214 .set_mmss = alpha_rtc_set_mmss,
215 .ioctl = alpha_rtc_ioctl,
216};
217
218/*
219 * Similarly, except do the actual CMOS access on the boot cpu only.
220 * This requires marshalling the data across an interprocessor call.
221 */
222
223#if defined(CONFIG_SMP) && \
224 (defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_MARVEL))
225# define HAVE_REMOTE_RTC 1
226
227union remote_data {
228 struct rtc_time *tm;
229 unsigned long now;
230 long retval;
231};
232
233static void
234do_remote_read(void *data)
235{
236 union remote_data *x = data;
237 x->retval = alpha_rtc_read_time(NULL, x->tm);
238}
239
240static int
241remote_read_time(struct device *dev, struct rtc_time *tm)
242{
243 union remote_data x;
244 if (smp_processor_id() != boot_cpuid) {
245 x.tm = tm;
246 smp_call_function_single(boot_cpuid, do_remote_read, &x, 1);
247 return x.retval;
248 }
249 return alpha_rtc_read_time(NULL, tm);
250}
251
252static void
253do_remote_set(void *data)
254{
255 union remote_data *x = data;
256 x->retval = alpha_rtc_set_time(NULL, x->tm);
257}
258
259static int
260remote_set_time(struct device *dev, struct rtc_time *tm)
261{
262 union remote_data x;
263 if (smp_processor_id() != boot_cpuid) {
264 x.tm = tm;
265 smp_call_function_single(boot_cpuid, do_remote_set, &x, 1);
266 return x.retval;
267 }
268 return alpha_rtc_set_time(NULL, tm);
269}
270
271static void
272do_remote_mmss(void *data)
273{
274 union remote_data *x = data;
275 x->retval = alpha_rtc_set_mmss(NULL, x->now);
276}
277
278static int
279remote_set_mmss(struct device *dev, unsigned long now)
280{
281 union remote_data x;
282 if (smp_processor_id() != boot_cpuid) {
283 x.now = now;
284 smp_call_function_single(boot_cpuid, do_remote_mmss, &x, 1);
285 return x.retval;
286 }
287 return alpha_rtc_set_mmss(NULL, now);
288}
289
290static const struct rtc_class_ops remote_rtc_ops = {
291 .read_time = remote_read_time,
292 .set_time = remote_set_time,
293 .set_mmss = remote_set_mmss,
294 .ioctl = alpha_rtc_ioctl,
295};
296#endif
297
298static int __init
299alpha_rtc_init(void)
300{
301 const struct rtc_class_ops *ops;
302 struct platform_device *pdev;
303 struct rtc_device *rtc;
304 const char *name;
305
306 init_rtc_epoch();
307 name = "rtc-alpha";
308 ops = &alpha_rtc_ops;
309
310#ifdef HAVE_REMOTE_RTC
311 if (alpha_mv.rtc_boot_cpu_only)
312 ops = &remote_rtc_ops;
313#endif
314
315 pdev = platform_device_register_simple(name, -1, NULL, 0);
316 rtc = devm_rtc_device_register(&pdev->dev, name, ops, THIS_MODULE);
317 if (IS_ERR(rtc))
318 return PTR_ERR(rtc);
319
320 platform_set_drvdata(pdev, rtc);
321 return 0;
322}
323device_initcall(alpha_rtc_init);
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 9e3107cc5ebb..b20af76f12c1 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -115,10 +115,17 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
115 115
116#ifdef CONFIG_ALPHA_GENERIC 116#ifdef CONFIG_ALPHA_GENERIC
117struct alpha_machine_vector alpha_mv; 117struct alpha_machine_vector alpha_mv;
118#endif
119
120#ifndef alpha_using_srm
118int alpha_using_srm; 121int alpha_using_srm;
119EXPORT_SYMBOL(alpha_using_srm); 122EXPORT_SYMBOL(alpha_using_srm);
120#endif 123#endif
121 124
125#ifndef alpha_using_qemu
126int alpha_using_qemu;
127#endif
128
122static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long, 129static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,
123 unsigned long); 130 unsigned long);
124static struct alpha_machine_vector *get_sysvec_byname(const char *); 131static struct alpha_machine_vector *get_sysvec_byname(const char *);
@@ -529,11 +536,15 @@ setup_arch(char **cmdline_p)
529 atomic_notifier_chain_register(&panic_notifier_list, 536 atomic_notifier_chain_register(&panic_notifier_list,
530 &alpha_panic_block); 537 &alpha_panic_block);
531 538
532#ifdef CONFIG_ALPHA_GENERIC 539#ifndef alpha_using_srm
533 /* Assume that we've booted from SRM if we haven't booted from MILO. 540 /* Assume that we've booted from SRM if we haven't booted from MILO.
534 Detect the later by looking for "MILO" in the system serial nr. */ 541 Detect the later by looking for "MILO" in the system serial nr. */
535 alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0; 542 alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
536#endif 543#endif
544#ifndef alpha_using_qemu
545 /* Similarly, look for QEMU. */
546 alpha_using_qemu = strstr((const char *)hwrpb->ssn, "QEMU") != 0;
547#endif
537 548
538 /* If we are using SRM, we want to allow callbacks 549 /* If we are using SRM, we want to allow callbacks
539 as early as possible, so do this NOW, and then 550 as early as possible, so do this NOW, and then
@@ -1207,6 +1218,7 @@ show_cpuinfo(struct seq_file *f, void *slot)
1207 char *systype_name; 1218 char *systype_name;
1208 char *sysvariation_name; 1219 char *sysvariation_name;
1209 int nr_processors; 1220 int nr_processors;
1221 unsigned long timer_freq;
1210 1222
1211 cpu_index = (unsigned) (cpu->type - 1); 1223 cpu_index = (unsigned) (cpu->type - 1);
1212 cpu_name = "Unknown"; 1224 cpu_name = "Unknown";
@@ -1218,6 +1230,12 @@ show_cpuinfo(struct seq_file *f, void *slot)
1218 1230
1219 nr_processors = get_nr_processors(cpu, hwrpb->nr_processors); 1231 nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
1220 1232
1233#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200
1234 timer_freq = (100UL * hwrpb->intr_freq) / 4096;
1235#else
1236 timer_freq = 100UL * CONFIG_HZ;
1237#endif
1238
1221 seq_printf(f, "cpu\t\t\t: Alpha\n" 1239 seq_printf(f, "cpu\t\t\t: Alpha\n"
1222 "cpu model\t\t: %s\n" 1240 "cpu model\t\t: %s\n"
1223 "cpu variation\t\t: %ld\n" 1241 "cpu variation\t\t: %ld\n"
@@ -1243,8 +1261,7 @@ show_cpuinfo(struct seq_file *f, void *slot)
1243 (char*)hwrpb->ssn, 1261 (char*)hwrpb->ssn,
1244 est_cycle_freq ? : hwrpb->cycle_freq, 1262 est_cycle_freq ? : hwrpb->cycle_freq,
1245 est_cycle_freq ? "est." : "", 1263 est_cycle_freq ? "est." : "",
1246 hwrpb->intr_freq / 4096, 1264 timer_freq / 100, timer_freq % 100,
1247 (100 * hwrpb->intr_freq / 4096) % 100,
1248 hwrpb->pagesize, 1265 hwrpb->pagesize,
1249 hwrpb->pa_bits, 1266 hwrpb->pa_bits,
1250 hwrpb->max_asn, 1267 hwrpb->max_asn,
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 9dbbcb3b9146..99ac36d5de4e 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -138,9 +138,11 @@ smp_callin(void)
138 138
139 /* Get our local ticker going. */ 139 /* Get our local ticker going. */
140 smp_setup_percpu_timer(cpuid); 140 smp_setup_percpu_timer(cpuid);
141 init_clockevent();
141 142
142 /* Call platform-specific callin, if specified */ 143 /* Call platform-specific callin, if specified */
143 if (alpha_mv.smp_callin) alpha_mv.smp_callin(); 144 if (alpha_mv.smp_callin)
145 alpha_mv.smp_callin();
144 146
145 /* All kernel threads share the same mm context. */ 147 /* All kernel threads share the same mm context. */
146 atomic_inc(&init_mm.mm_count); 148 atomic_inc(&init_mm.mm_count);
@@ -498,35 +500,6 @@ smp_cpus_done(unsigned int max_cpus)
498 ((bogosum + 2500) / (5000/HZ)) % 100); 500 ((bogosum + 2500) / (5000/HZ)) % 100);
499} 501}
500 502
501
502void
503smp_percpu_timer_interrupt(struct pt_regs *regs)
504{
505 struct pt_regs *old_regs;
506 int cpu = smp_processor_id();
507 unsigned long user = user_mode(regs);
508 struct cpuinfo_alpha *data = &cpu_data[cpu];
509
510 old_regs = set_irq_regs(regs);
511
512 /* Record kernel PC. */
513 profile_tick(CPU_PROFILING);
514
515 if (!--data->prof_counter) {
516 /* We need to make like a normal interrupt -- otherwise
517 timer interrupts ignore the global interrupt lock,
518 which would be a Bad Thing. */
519 irq_enter();
520
521 update_process_times(user);
522
523 data->prof_counter = data->prof_multiplier;
524
525 irq_exit();
526 }
527 set_irq_regs(old_regs);
528}
529
530int 503int
531setup_profiling_timer(unsigned int multiplier) 504setup_profiling_timer(unsigned int multiplier)
532{ 505{
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 5a0af11b3a61..608f2a7fa0a3 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -224,8 +224,6 @@ struct alpha_machine_vector jensen_mv __initmv = {
224 .machine_check = jensen_machine_check, 224 .machine_check = jensen_machine_check,
225 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 225 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
226 .rtc_port = 0x170, 226 .rtc_port = 0x170,
227 .rtc_get_time = common_get_rtc_time,
228 .rtc_set_time = common_set_rtc_time,
229 227
230 .nr_irqs = 16, 228 .nr_irqs = 16,
231 .device_interrupt = jensen_device_interrupt, 229 .device_interrupt = jensen_device_interrupt,
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index c92e389ff219..f21d61fab678 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -22,7 +22,6 @@
22#include <asm/hwrpb.h> 22#include <asm/hwrpb.h>
23#include <asm/tlbflush.h> 23#include <asm/tlbflush.h>
24#include <asm/vga.h> 24#include <asm/vga.h>
25#include <asm/rtc.h>
26 25
27#include "proto.h" 26#include "proto.h"
28#include "err_impl.h" 27#include "err_impl.h"
@@ -400,57 +399,6 @@ marvel_init_rtc(void)
400 init_rtc_irq(); 399 init_rtc_irq();
401} 400}
402 401
403struct marvel_rtc_time {
404 struct rtc_time *time;
405 int retval;
406};
407
408#ifdef CONFIG_SMP
409static void
410smp_get_rtc_time(void *data)
411{
412 struct marvel_rtc_time *mrt = data;
413 mrt->retval = __get_rtc_time(mrt->time);
414}
415
416static void
417smp_set_rtc_time(void *data)
418{
419 struct marvel_rtc_time *mrt = data;
420 mrt->retval = __set_rtc_time(mrt->time);
421}
422#endif
423
424static unsigned int
425marvel_get_rtc_time(struct rtc_time *time)
426{
427#ifdef CONFIG_SMP
428 struct marvel_rtc_time mrt;
429
430 if (smp_processor_id() != boot_cpuid) {
431 mrt.time = time;
432 smp_call_function_single(boot_cpuid, smp_get_rtc_time, &mrt, 1);
433 return mrt.retval;
434 }
435#endif
436 return __get_rtc_time(time);
437}
438
439static int
440marvel_set_rtc_time(struct rtc_time *time)
441{
442#ifdef CONFIG_SMP
443 struct marvel_rtc_time mrt;
444
445 if (smp_processor_id() != boot_cpuid) {
446 mrt.time = time;
447 smp_call_function_single(boot_cpuid, smp_set_rtc_time, &mrt, 1);
448 return mrt.retval;
449 }
450#endif
451 return __set_rtc_time(time);
452}
453
454static void 402static void
455marvel_smp_callin(void) 403marvel_smp_callin(void)
456{ 404{
@@ -492,8 +440,7 @@ struct alpha_machine_vector marvel_ev7_mv __initmv = {
492 .vector_name = "MARVEL/EV7", 440 .vector_name = "MARVEL/EV7",
493 DO_EV7_MMU, 441 DO_EV7_MMU,
494 .rtc_port = 0x70, 442 .rtc_port = 0x70,
495 .rtc_get_time = marvel_get_rtc_time, 443 .rtc_boot_cpu_only = 1,
496 .rtc_set_time = marvel_set_rtc_time,
497 DO_MARVEL_IO, 444 DO_MARVEL_IO,
498 .machine_check = marvel_machine_check, 445 .machine_check = marvel_machine_check,
499 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS, 446 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index ea3395036556..ee39cee8064c 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -3,13 +3,7 @@
3 * 3 *
4 * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds 4 * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds
5 * 5 *
6 * This file contains the PC-specific time handling details: 6 * This file contains the clocksource time handling.
7 * reading the RTC at bootup, etc..
8 * 1994-07-02 Alan Modra
9 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
10 * 1995-03-26 Markus Kuhn
11 * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
12 * precision CMOS clock update
13 * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 7 * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
14 * "A Kernel Model for Precision Timekeeping" by Dave Mills 8 * "A Kernel Model for Precision Timekeeping" by Dave Mills
15 * 1997-01-09 Adrian Sun 9 * 1997-01-09 Adrian Sun
@@ -21,9 +15,6 @@
21 * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net) 15 * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net)
22 * fixed algorithm in do_gettimeofday() for calculating the precise time 16 * fixed algorithm in do_gettimeofday() for calculating the precise time
23 * from processor cycle counter (now taking lost_ticks into account) 17 * from processor cycle counter (now taking lost_ticks into account)
24 * 2000-08-13 Jan-Benedict Glaw <jbglaw@lug-owl.de>
25 * Fixed time_init to be aware of epoches != 1900. This prevents
26 * booting up in 2048 for me;) Code is stolen from rtc.c.
27 * 2003-06-03 R. Scott Bailey <scott.bailey@eds.com> 18 * 2003-06-03 R. Scott Bailey <scott.bailey@eds.com>
28 * Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM 19 * Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM
29 */ 20 */
@@ -46,40 +37,19 @@
46#include <asm/uaccess.h> 37#include <asm/uaccess.h>
47#include <asm/io.h> 38#include <asm/io.h>
48#include <asm/hwrpb.h> 39#include <asm/hwrpb.h>
49#include <asm/rtc.h>
50 40
51#include <linux/mc146818rtc.h> 41#include <linux/mc146818rtc.h>
52#include <linux/time.h> 42#include <linux/time.h>
53#include <linux/timex.h> 43#include <linux/timex.h>
54#include <linux/clocksource.h> 44#include <linux/clocksource.h>
45#include <linux/clockchips.h>
55 46
56#include "proto.h" 47#include "proto.h"
57#include "irq_impl.h" 48#include "irq_impl.h"
58 49
59static int set_rtc_mmss(unsigned long);
60
61DEFINE_SPINLOCK(rtc_lock); 50DEFINE_SPINLOCK(rtc_lock);
62EXPORT_SYMBOL(rtc_lock); 51EXPORT_SYMBOL(rtc_lock);
63 52
64#define TICK_SIZE (tick_nsec / 1000)
65
66/*
67 * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting
68 * by 48 gives us 16 bits for HZ while keeping the accuracy good even
69 * for large CPU clock rates.
70 */
71#define FIX_SHIFT 48
72
73/* lump static variables together for more efficient access: */
74static struct {
75 /* cycle counter last time it got invoked */
76 __u32 last_time;
77 /* ticks/cycle * 2^48 */
78 unsigned long scaled_ticks_per_cycle;
79 /* partial unused tick */
80 unsigned long partial_tick;
81} state;
82
83unsigned long est_cycle_freq; 53unsigned long est_cycle_freq;
84 54
85#ifdef CONFIG_IRQ_WORK 55#ifdef CONFIG_IRQ_WORK
@@ -108,109 +78,156 @@ static inline __u32 rpcc(void)
108 return __builtin_alpha_rpcc(); 78 return __builtin_alpha_rpcc();
109} 79}
110 80
111int update_persistent_clock(struct timespec now)
112{
113 return set_rtc_mmss(now.tv_sec);
114}
115 81
116void read_persistent_clock(struct timespec *ts) 82
83/*
84 * The RTC as a clock_event_device primitive.
85 */
86
87static DEFINE_PER_CPU(struct clock_event_device, cpu_ce);
88
89irqreturn_t
90rtc_timer_interrupt(int irq, void *dev)
117{ 91{
118 unsigned int year, mon, day, hour, min, sec, epoch; 92 int cpu = smp_processor_id();
119 93 struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
120 sec = CMOS_READ(RTC_SECONDS);
121 min = CMOS_READ(RTC_MINUTES);
122 hour = CMOS_READ(RTC_HOURS);
123 day = CMOS_READ(RTC_DAY_OF_MONTH);
124 mon = CMOS_READ(RTC_MONTH);
125 year = CMOS_READ(RTC_YEAR);
126
127 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
128 sec = bcd2bin(sec);
129 min = bcd2bin(min);
130 hour = bcd2bin(hour);
131 day = bcd2bin(day);
132 mon = bcd2bin(mon);
133 year = bcd2bin(year);
134 }
135 94
136 /* PC-like is standard; used for year >= 70 */ 95 /* Don't run the hook for UNUSED or SHUTDOWN. */
137 epoch = 1900; 96 if (likely(ce->mode == CLOCK_EVT_MODE_PERIODIC))
138 if (year < 20) 97 ce->event_handler(ce);
139 epoch = 2000;
140 else if (year >= 20 && year < 48)
141 /* NT epoch */
142 epoch = 1980;
143 else if (year >= 48 && year < 70)
144 /* Digital UNIX epoch */
145 epoch = 1952;
146 98
147 printk(KERN_INFO "Using epoch = %d\n", epoch); 99 if (test_irq_work_pending()) {
100 clear_irq_work_pending();
101 irq_work_run();
102 }
148 103
149 if ((year += epoch) < 1970) 104 return IRQ_HANDLED;
150 year += 100; 105}
151 106
152 ts->tv_sec = mktime(year, mon, day, hour, min, sec); 107static void
153 ts->tv_nsec = 0; 108rtc_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
109{
110 /* The mode member of CE is updated in generic code.
111 Since we only support periodic events, nothing to do. */
112}
113
114static int
115rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
116{
117 /* This hook is for oneshot mode, which we don't support. */
118 return -EINVAL;
154} 119}
155 120
121static void __init
122init_rtc_clockevent(void)
123{
124 int cpu = smp_processor_id();
125 struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
126
127 *ce = (struct clock_event_device){
128 .name = "rtc",
129 .features = CLOCK_EVT_FEAT_PERIODIC,
130 .rating = 100,
131 .cpumask = cpumask_of(cpu),
132 .set_mode = rtc_ce_set_mode,
133 .set_next_event = rtc_ce_set_next_event,
134 };
156 135
136 clockevents_config_and_register(ce, CONFIG_HZ, 0, 0);
137}
157 138
139
158/* 140/*
159 * timer_interrupt() needs to keep up the real-time clock, 141 * The QEMU clock as a clocksource primitive.
160 * as well as call the "xtime_update()" routine every clocktick
161 */ 142 */
162irqreturn_t timer_interrupt(int irq, void *dev) 143
144static cycle_t
145qemu_cs_read(struct clocksource *cs)
163{ 146{
164 unsigned long delta; 147 return qemu_get_vmtime();
165 __u32 now; 148}
166 long nticks;
167 149
168#ifndef CONFIG_SMP 150static struct clocksource qemu_cs = {
169 /* Not SMP, do kernel PC profiling here. */ 151 .name = "qemu",
170 profile_tick(CPU_PROFILING); 152 .rating = 400,
171#endif 153 .read = qemu_cs_read,
154 .mask = CLOCKSOURCE_MASK(64),
155 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
156 .max_idle_ns = LONG_MAX
157};
172 158
173 /*
174 * Calculate how many ticks have passed since the last update,
175 * including any previous partial leftover. Save any resulting
176 * fraction for the next pass.
177 */
178 now = rpcc();
179 delta = now - state.last_time;
180 state.last_time = now;
181 delta = delta * state.scaled_ticks_per_cycle + state.partial_tick;
182 state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1);
183 nticks = delta >> FIX_SHIFT;
184 159
185 if (nticks) 160/*
186 xtime_update(nticks); 161 * The QEMU alarm as a clock_event_device primitive.
162 */
187 163
188 if (test_irq_work_pending()) { 164static void
189 clear_irq_work_pending(); 165qemu_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
190 irq_work_run(); 166{
191 } 167 /* The mode member of CE is updated for us in generic code.
168 Just make sure that the event is disabled. */
169 qemu_set_alarm_abs(0);
170}
192 171
193#ifndef CONFIG_SMP 172static int
194 while (nticks--) 173qemu_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
195 update_process_times(user_mode(get_irq_regs())); 174{
196#endif 175 qemu_set_alarm_rel(evt);
176 return 0;
177}
197 178
179static irqreturn_t
180qemu_timer_interrupt(int irq, void *dev)
181{
182 int cpu = smp_processor_id();
183 struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
184
185 ce->event_handler(ce);
198 return IRQ_HANDLED; 186 return IRQ_HANDLED;
199} 187}
200 188
189static void __init
190init_qemu_clockevent(void)
191{
192 int cpu = smp_processor_id();
193 struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
194
195 *ce = (struct clock_event_device){
196 .name = "qemu",
197 .features = CLOCK_EVT_FEAT_ONESHOT,
198 .rating = 400,
199 .cpumask = cpumask_of(cpu),
200 .set_mode = qemu_ce_set_mode,
201 .set_next_event = qemu_ce_set_next_event,
202 };
203
204 clockevents_config_and_register(ce, NSEC_PER_SEC, 1000, LONG_MAX);
205}
206
207
201void __init 208void __init
202common_init_rtc(void) 209common_init_rtc(void)
203{ 210{
204 unsigned char x; 211 unsigned char x, sel = 0;
205 212
206 /* Reset periodic interrupt frequency. */ 213 /* Reset periodic interrupt frequency. */
207 x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; 214#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200
208 /* Test includes known working values on various platforms 215 x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
209 where 0x26 is wrong; we refuse to change those. */ 216 /* Test includes known working values on various platforms
210 if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { 217 where 0x26 is wrong; we refuse to change those. */
211 printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); 218 if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) {
212 CMOS_WRITE(0x26, RTC_FREQ_SELECT); 219 sel = RTC_REF_CLCK_32KHZ + 6;
213 } 220 }
221#elif CONFIG_HZ == 256 || CONFIG_HZ == 128 || CONFIG_HZ == 64 || CONFIG_HZ == 32
222 sel = RTC_REF_CLCK_32KHZ + __builtin_ffs(32768 / CONFIG_HZ);
223#else
224# error "Unknown HZ from arch/alpha/Kconfig"
225#endif
226 if (sel) {
227 printk(KERN_INFO "Setting RTC_FREQ to %d Hz (%x)\n",
228 CONFIG_HZ, sel);
229 CMOS_WRITE(sel, RTC_FREQ_SELECT);
230 }
214 231
215 /* Turn on periodic interrupts. */ 232 /* Turn on periodic interrupts. */
216 x = CMOS_READ(RTC_CONTROL); 233 x = CMOS_READ(RTC_CONTROL);
@@ -233,16 +250,37 @@ common_init_rtc(void)
233 init_rtc_irq(); 250 init_rtc_irq();
234} 251}
235 252
236unsigned int common_get_rtc_time(struct rtc_time *time) 253
237{ 254#ifndef CONFIG_ALPHA_WTINT
238 return __get_rtc_time(time); 255/*
239} 256 * The RPCC as a clocksource primitive.
257 *
258 * While we have free-running timecounters running on all CPUs, and we make
259 * a half-hearted attempt in init_rtc_rpcc_info to sync the timecounter
260 * with the wall clock, that initialization isn't kept up-to-date across
261 * different time counters in SMP mode. Therefore we can only use this
262 * method when there's only one CPU enabled.
263 *
264 * When using the WTINT PALcall, the RPCC may shift to a lower frequency,
265 * or stop altogether, while waiting for the interrupt. Therefore we cannot
266 * use this method when WTINT is in use.
267 */
240 268
241int common_set_rtc_time(struct rtc_time *time) 269static cycle_t read_rpcc(struct clocksource *cs)
242{ 270{
243 return __set_rtc_time(time); 271 return rpcc();
244} 272}
245 273
274static struct clocksource clocksource_rpcc = {
275 .name = "rpcc",
276 .rating = 300,
277 .read = read_rpcc,
278 .mask = CLOCKSOURCE_MASK(32),
279 .flags = CLOCK_SOURCE_IS_CONTINUOUS
280};
281#endif /* ALPHA_WTINT */
282
283
246/* Validate a computed cycle counter result against the known bounds for 284/* Validate a computed cycle counter result against the known bounds for
247 the given processor core. There's too much brokenness in the way of 285 the given processor core. There's too much brokenness in the way of
248 timing hardware for any one method to work everywhere. :-( 286 timing hardware for any one method to work everywhere. :-(
@@ -353,33 +391,6 @@ rpcc_after_update_in_progress(void)
353 return rpcc(); 391 return rpcc();
354} 392}
355 393
356#ifndef CONFIG_SMP
357/* Until and unless we figure out how to get cpu cycle counters
358 in sync and keep them there, we can't use the rpcc. */
359static cycle_t read_rpcc(struct clocksource *cs)
360{
361 cycle_t ret = (cycle_t)rpcc();
362 return ret;
363}
364
365static struct clocksource clocksource_rpcc = {
366 .name = "rpcc",
367 .rating = 300,
368 .read = read_rpcc,
369 .mask = CLOCKSOURCE_MASK(32),
370 .flags = CLOCK_SOURCE_IS_CONTINUOUS
371};
372
373static inline void register_rpcc_clocksource(long cycle_freq)
374{
375 clocksource_register_hz(&clocksource_rpcc, cycle_freq);
376}
377#else /* !CONFIG_SMP */
378static inline void register_rpcc_clocksource(long cycle_freq)
379{
380}
381#endif /* !CONFIG_SMP */
382
383void __init 394void __init
384time_init(void) 395time_init(void)
385{ 396{
@@ -387,6 +398,15 @@ time_init(void)
387 unsigned long cycle_freq, tolerance; 398 unsigned long cycle_freq, tolerance;
388 long diff; 399 long diff;
389 400
401 if (alpha_using_qemu) {
402 clocksource_register_hz(&qemu_cs, NSEC_PER_SEC);
403 init_qemu_clockevent();
404
405 timer_irqaction.handler = qemu_timer_interrupt;
406 init_rtc_irq();
407 return;
408 }
409
390 /* Calibrate CPU clock -- attempt #1. */ 410 /* Calibrate CPU clock -- attempt #1. */
391 if (!est_cycle_freq) 411 if (!est_cycle_freq)
392 est_cycle_freq = validate_cc_value(calibrate_cc_with_pit()); 412 est_cycle_freq = validate_cc_value(calibrate_cc_with_pit());
@@ -421,100 +441,25 @@ time_init(void)
421 "and unable to estimate a proper value!\n"); 441 "and unable to estimate a proper value!\n");
422 } 442 }
423 443
424 /* From John Bowman <bowman@math.ualberta.ca>: allow the values 444 /* See above for restrictions on using clocksource_rpcc. */
425 to settle, as the Update-In-Progress bit going low isn't good 445#ifndef CONFIG_ALPHA_WTINT
426 enough on some hardware. 2ms is our guess; we haven't found 446 if (hwrpb->nr_processors == 1)
427 bogomips yet, but this is close on a 500Mhz box. */ 447 clocksource_register_hz(&clocksource_rpcc, cycle_freq);
428 __delay(1000000); 448#endif
429
430
431 if (HZ > (1<<16)) {
432 extern void __you_loose (void);
433 __you_loose();
434 }
435
436 register_rpcc_clocksource(cycle_freq);
437
438 state.last_time = cc1;
439 state.scaled_ticks_per_cycle
440 = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
441 state.partial_tick = 0L;
442 449
443 /* Startup the timer source. */ 450 /* Startup the timer source. */
444 alpha_mv.init_rtc(); 451 alpha_mv.init_rtc();
452 init_rtc_clockevent();
445} 453}
446 454
447/* 455/* Initialize the clock_event_device for secondary cpus. */
448 * In order to set the CMOS clock precisely, set_rtc_mmss has to be 456#ifdef CONFIG_SMP
449 * called 500 ms after the second nowtime has started, because when 457void __init
450 * nowtime is written into the registers of the CMOS clock, it will 458init_clockevent(void)
451 * jump to the next second precisely 500 ms later. Check the Motorola
452 * MC146818A or Dallas DS12887 data sheet for details.
453 *
454 * BUG: This routine does not handle hour overflow properly; it just
455 * sets the minutes. Usually you won't notice until after reboot!
456 */
457
458
459static int
460set_rtc_mmss(unsigned long nowtime)
461{ 459{
462 int retval = 0; 460 if (alpha_using_qemu)
463 int real_seconds, real_minutes, cmos_minutes; 461 init_qemu_clockevent();
464 unsigned char save_control, save_freq_select; 462 else
465 463 init_rtc_clockevent();
466 /* irq are locally disabled here */
467 spin_lock(&rtc_lock);
468 /* Tell the clock it's being set */
469 save_control = CMOS_READ(RTC_CONTROL);
470 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
471
472 /* Stop and reset prescaler */
473 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
474 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
475
476 cmos_minutes = CMOS_READ(RTC_MINUTES);
477 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
478 cmos_minutes = bcd2bin(cmos_minutes);
479
480 /*
481 * since we're only adjusting minutes and seconds,
482 * don't interfere with hour overflow. This avoids
483 * messing with unknown time zones but requires your
484 * RTC not to be off by more than 15 minutes
485 */
486 real_seconds = nowtime % 60;
487 real_minutes = nowtime / 60;
488 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) {
489 /* correct for half hour time zone */
490 real_minutes += 30;
491 }
492 real_minutes %= 60;
493
494 if (abs(real_minutes - cmos_minutes) < 30) {
495 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
496 real_seconds = bin2bcd(real_seconds);
497 real_minutes = bin2bcd(real_minutes);
498 }
499 CMOS_WRITE(real_seconds,RTC_SECONDS);
500 CMOS_WRITE(real_minutes,RTC_MINUTES);
501 } else {
502 printk_once(KERN_NOTICE
503 "set_rtc_mmss: can't update from %d to %d\n",
504 cmos_minutes, real_minutes);
505 retval = -1;
506 }
507
508 /* The following flags have to be released exactly in this order,
509 * otherwise the DS12887 (popular MC146818A clone with integrated
510 * battery and quartz) will not reset the oscillator and will not
511 * update precisely 500 ms later. You won't find this mentioned in
512 * the Dallas Semiconductor data sheets, but who believes data
513 * sheets anyway ... -- Markus Kuhn
514 */
515 CMOS_WRITE(save_control, RTC_CONTROL);
516 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
517 spin_unlock(&rtc_lock);
518
519 return retval;
520} 464}
465#endif
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index bd0665cdc840..9c4c189eb22f 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -241,6 +241,21 @@ do_entIF(unsigned long type, struct pt_regs *regs)
241 (const char *)(data[1] | (long)data[2] << 32), 241 (const char *)(data[1] | (long)data[2] << 32),
242 data[0]); 242 data[0]);
243 } 243 }
244#ifdef CONFIG_ALPHA_WTINT
245 if (type == 4) {
246 /* If CALL_PAL WTINT is totally unsupported by the
247 PALcode, e.g. MILO, "emulate" it by overwriting
248 the insn. */
249 unsigned int *pinsn
250 = (unsigned int *) regs->pc - 1;
251 if (*pinsn == PAL_wtint) {
252 *pinsn = 0x47e01400; /* mov 0,$0 */
253 imb();
254 regs->r0 = 0;
255 return;
256 }
257 }
258#endif /* ALPHA_WTINT */
244 die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"), 259 die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
245 regs, type, NULL); 260 regs, type, NULL);
246 } 261 }
diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c
index ffb19b7da999..ff3c10721caf 100644
--- a/arch/alpha/lib/csum_partial_copy.c
+++ b/arch/alpha/lib/csum_partial_copy.c
@@ -130,7 +130,7 @@ csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst,
130 *dst = word | tmp; 130 *dst = word | tmp;
131 checksum += carry; 131 checksum += carry;
132 } 132 }
133 if (err) *errp = err; 133 if (err && errp) *errp = err;
134 return checksum; 134 return checksum;
135} 135}
136 136
@@ -185,7 +185,7 @@ csum_partial_cfu_dest_aligned(const unsigned long __user *src,
185 *dst = word | tmp; 185 *dst = word | tmp;
186 checksum += carry; 186 checksum += carry;
187 } 187 }
188 if (err) *errp = err; 188 if (err && errp) *errp = err;
189 return checksum; 189 return checksum;
190} 190}
191 191
@@ -242,7 +242,7 @@ csum_partial_cfu_src_aligned(const unsigned long __user *src,
242 stq_u(partial_dest | second_dest, dst); 242 stq_u(partial_dest | second_dest, dst);
243out: 243out:
244 checksum += carry; 244 checksum += carry;
245 if (err) *errp = err; 245 if (err && errp) *errp = err;
246 return checksum; 246 return checksum;
247} 247}
248 248
@@ -325,7 +325,7 @@ csum_partial_cfu_unaligned(const unsigned long __user * src,
325 stq_u(partial_dest | word | second_dest, dst); 325 stq_u(partial_dest | word | second_dest, dst);
326 checksum += carry; 326 checksum += carry;
327 } 327 }
328 if (err) *errp = err; 328 if (err && errp) *errp = err;
329 return checksum; 329 return checksum;
330} 330}
331 331
@@ -339,7 +339,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst, int len,
339 339
340 if (len) { 340 if (len) {
341 if (!access_ok(VERIFY_READ, src, len)) { 341 if (!access_ok(VERIFY_READ, src, len)) {
342 *errp = -EFAULT; 342 if (errp) *errp = -EFAULT;
343 memset(dst, 0, len); 343 memset(dst, 0, len);
344 return sum; 344 return sum;
345 } 345 }
diff --git a/arch/alpha/lib/ev6-memset.S b/arch/alpha/lib/ev6-memset.S
index d8b94e1c7fca..356bb2fdd705 100644
--- a/arch/alpha/lib/ev6-memset.S
+++ b/arch/alpha/lib/ev6-memset.S
@@ -30,14 +30,15 @@
30 .set noat 30 .set noat
31 .set noreorder 31 .set noreorder
32.text 32.text
33 .globl memset
33 .globl __memset 34 .globl __memset
35 .globl ___memset
34 .globl __memsetw 36 .globl __memsetw
35 .globl __constant_c_memset 37 .globl __constant_c_memset
36 .globl memset
37 38
38 .ent __memset 39 .ent ___memset
39.align 5 40.align 5
40__memset: 41___memset:
41 .frame $30,0,$26,0 42 .frame $30,0,$26,0
42 .prologue 0 43 .prologue 0
43 44
@@ -227,7 +228,7 @@ end_b:
227 nop 228 nop
228 nop 229 nop
229 ret $31,($26),1 # L0 : 230 ret $31,($26),1 # L0 :
230 .end __memset 231 .end ___memset
231 232
232 /* 233 /*
233 * This is the original body of code, prior to replication and 234 * This is the original body of code, prior to replication and
@@ -594,4 +595,5 @@ end_w:
594 595
595 .end __memsetw 596 .end __memsetw
596 597
597memset = __memset 598memset = ___memset
599__memset = ___memset
diff --git a/arch/alpha/lib/memset.S b/arch/alpha/lib/memset.S
index 311b8cfc6914..76ccc6d1f364 100644
--- a/arch/alpha/lib/memset.S
+++ b/arch/alpha/lib/memset.S
@@ -19,11 +19,13 @@
19.text 19.text
20 .globl memset 20 .globl memset
21 .globl __memset 21 .globl __memset
22 .globl ___memset
22 .globl __memsetw 23 .globl __memsetw
23 .globl __constant_c_memset 24 .globl __constant_c_memset
24 .ent __memset 25
26 .ent ___memset
25.align 5 27.align 5
26__memset: 28___memset:
27 .frame $30,0,$26,0 29 .frame $30,0,$26,0
28 .prologue 0 30 .prologue 0
29 31
@@ -103,7 +105,7 @@ within_one_quad:
103 105
104end: 106end:
105 ret $31,($26),1 /* E1 */ 107 ret $31,($26),1 /* E1 */
106 .end __memset 108 .end ___memset
107 109
108 .align 5 110 .align 5
109 .ent __memsetw 111 .ent __memsetw
@@ -121,4 +123,5 @@ __memsetw:
121 123
122 .end __memsetw 124 .end __memsetw
123 125
124memset = __memset 126memset = ___memset
127__memset = ___memset
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 15f166a470a7..007730222116 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -626,7 +626,7 @@ comment "Platform RTC drivers"
626 626
627config RTC_DRV_CMOS 627config RTC_DRV_CMOS
628 tristate "PC-style 'CMOS'" 628 tristate "PC-style 'CMOS'"
629 depends on X86 || ALPHA || ARM || M32R || ATARI || PPC || MIPS || SPARC64 629 depends on X86 || ARM || M32R || ATARI || PPC || MIPS || SPARC64
630 default y if X86 630 default y if X86
631 help 631 help
632 Say "yes" here to get direct support for the real time clock 632 Say "yes" here to get direct support for the real time clock
@@ -643,6 +643,14 @@ config RTC_DRV_CMOS
643 This driver can also be built as a module. If so, the module 643 This driver can also be built as a module. If so, the module
644 will be called rtc-cmos. 644 will be called rtc-cmos.
645 645
646config RTC_DRV_ALPHA
647 bool "Alpha PC-style CMOS"
648 depends on ALPHA
649 default y
650 help
651 Direct support for the real-time clock found on every Alpha
652 system, specifically MC146818 compatibles. If in doubt, say Y.
653
646config RTC_DRV_VRTC 654config RTC_DRV_VRTC
647 tristate "Virtual RTC for Intel MID platforms" 655 tristate "Virtual RTC for Intel MID platforms"
648 depends on X86_INTEL_MID 656 depends on X86_INTEL_MID