diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2013-04-03 06:27:29 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2013-04-03 06:27:29 -0400 |
commit | 0ed2aef9b3bffe598045b62a31a50d912eee92d8 (patch) | |
tree | d7dda12955c838f531727d2775d09c4e04bdf066 /arch | |
parent | cfea7d7e452f57682a0bb55a55e9f79c569558c2 (diff) | |
parent | 8011657b9e63cb2e914b9a0f75233b910c1854cb (diff) |
Merge branch 'fortglx/3.10/time' of git://git.linaro.org/people/jstultz/linux into timers/core
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-bcm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-bcm/board_bcm.c | 7 | ||||
-rw-r--r-- | arch/s390/include/asm/cpu_mf.h | 1 | ||||
-rw-r--r-- | arch/um/drivers/chan.h | 2 | ||||
-rw-r--r-- | arch/um/drivers/chan_kern.c | 4 | ||||
-rw-r--r-- | arch/um/drivers/chan_user.c | 12 | ||||
-rw-r--r-- | arch/um/drivers/chan_user.h | 6 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 42 | ||||
-rw-r--r-- | arch/um/drivers/net_kern.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/ssl.c | 1 | ||||
-rw-r--r-- | arch/um/drivers/stdio_console.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/start_up.c | 2 | ||||
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/cpufeature.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/rtc.c | 69 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 6 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 24 | ||||
-rw-r--r-- | arch/x86/platform/mrst/vrtc.c | 44 |
20 files changed, 118 insertions, 122 deletions
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index bf02471d7e7c..f11289519c39 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig | |||
@@ -6,6 +6,7 @@ config ARCH_BCM | |||
6 | select ARM_ERRATA_764369 if SMP | 6 | select ARM_ERRATA_764369 if SMP |
7 | select ARM_GIC | 7 | select ARM_GIC |
8 | select CPU_V7 | 8 | select CPU_V7 |
9 | select CLKSRC_OF | ||
9 | select GENERIC_CLOCKEVENTS | 10 | select GENERIC_CLOCKEVENTS |
10 | select GENERIC_TIME | 11 | select GENERIC_TIME |
11 | select GPIO_BCM | 12 | select GPIO_BCM |
diff --git a/arch/arm/mach-bcm/board_bcm.c b/arch/arm/mach-bcm/board_bcm.c index f0f9abafad29..259593540477 100644 --- a/arch/arm/mach-bcm/board_bcm.c +++ b/arch/arm/mach-bcm/board_bcm.c | |||
@@ -16,14 +16,11 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/irqchip.h> | 18 | #include <linux/irqchip.h> |
19 | #include <linux/clocksource.h> | ||
19 | 20 | ||
20 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
21 | #include <asm/mach/time.h> | 22 | #include <asm/mach/time.h> |
22 | 23 | ||
23 | static void timer_init(void) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | 24 | ||
28 | static void __init board_init(void) | 25 | static void __init board_init(void) |
29 | { | 26 | { |
@@ -35,7 +32,7 @@ static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, }; | |||
35 | 32 | ||
36 | DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor") | 33 | DT_MACHINE_START(BCM11351_DT, "Broadcom Application Processor") |
37 | .init_irq = irqchip_init, | 34 | .init_irq = irqchip_init, |
38 | .init_time = timer_init, | 35 | .init_time = clocksource_of_init, |
39 | .init_machine = board_init, | 36 | .init_machine = board_init, |
40 | .dt_compat = bcm11351_dt_compat, | 37 | .dt_compat = bcm11351_dt_compat, |
41 | MACHINE_END | 38 | MACHINE_END |
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h index f1eddd150dd7..c879fad404c8 100644 --- a/arch/s390/include/asm/cpu_mf.h +++ b/arch/s390/include/asm/cpu_mf.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifndef _ASM_S390_CPU_MF_H | 12 | #ifndef _ASM_S390_CPU_MF_H |
13 | #define _ASM_S390_CPU_MF_H | 13 | #define _ASM_S390_CPU_MF_H |
14 | 14 | ||
15 | #include <linux/errno.h> | ||
15 | #include <asm/facility.h> | 16 | #include <asm/facility.h> |
16 | 17 | ||
17 | #define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */ | 18 | #define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */ |
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h index 78f1b8999964..c512b0306dd4 100644 --- a/arch/um/drivers/chan.h +++ b/arch/um/drivers/chan.h | |||
@@ -37,7 +37,7 @@ extern int console_write_chan(struct chan *chan, const char *buf, | |||
37 | extern int console_open_chan(struct line *line, struct console *co); | 37 | extern int console_open_chan(struct line *line, struct console *co); |
38 | extern void deactivate_chan(struct chan *chan, int irq); | 38 | extern void deactivate_chan(struct chan *chan, int irq); |
39 | extern void reactivate_chan(struct chan *chan, int irq); | 39 | extern void reactivate_chan(struct chan *chan, int irq); |
40 | extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty); | 40 | extern void chan_enable_winch(struct chan *chan, struct tty_port *port); |
41 | extern int enable_chan(struct line *line); | 41 | extern int enable_chan(struct line *line); |
42 | extern void close_chan(struct line *line); | 42 | extern void close_chan(struct line *line); |
43 | extern int chan_window_size(struct line *line, | 43 | extern int chan_window_size(struct line *line, |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 15c553c239a1..80b47cb71e0a 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -122,10 +122,10 @@ static int open_chan(struct list_head *chans) | |||
122 | return err; | 122 | return err; |
123 | } | 123 | } |
124 | 124 | ||
125 | void chan_enable_winch(struct chan *chan, struct tty_struct *tty) | 125 | void chan_enable_winch(struct chan *chan, struct tty_port *port) |
126 | { | 126 | { |
127 | if (chan && chan->primary && chan->ops->winch) | 127 | if (chan && chan->primary && chan->ops->winch) |
128 | register_winch(chan->fd, tty); | 128 | register_winch(chan->fd, port); |
129 | } | 129 | } |
130 | 130 | ||
131 | static void line_timer_cb(struct work_struct *work) | 131 | static void line_timer_cb(struct work_struct *work) |
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 9be670ad23b5..3fd7c3efdb18 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c | |||
@@ -216,7 +216,7 @@ static int winch_thread(void *arg) | |||
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
219 | static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, | 219 | static int winch_tramp(int fd, struct tty_port *port, int *fd_out, |
220 | unsigned long *stack_out) | 220 | unsigned long *stack_out) |
221 | { | 221 | { |
222 | struct winch_data data; | 222 | struct winch_data data; |
@@ -271,7 +271,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out, | |||
271 | return err; | 271 | return err; |
272 | } | 272 | } |
273 | 273 | ||
274 | void register_winch(int fd, struct tty_struct *tty) | 274 | void register_winch(int fd, struct tty_port *port) |
275 | { | 275 | { |
276 | unsigned long stack; | 276 | unsigned long stack; |
277 | int pid, thread, count, thread_fd = -1; | 277 | int pid, thread, count, thread_fd = -1; |
@@ -281,17 +281,17 @@ void register_winch(int fd, struct tty_struct *tty) | |||
281 | return; | 281 | return; |
282 | 282 | ||
283 | pid = tcgetpgrp(fd); | 283 | pid = tcgetpgrp(fd); |
284 | if (is_skas_winch(pid, fd, tty)) { | 284 | if (is_skas_winch(pid, fd, port)) { |
285 | register_winch_irq(-1, fd, -1, tty, 0); | 285 | register_winch_irq(-1, fd, -1, port, 0); |
286 | return; | 286 | return; |
287 | } | 287 | } |
288 | 288 | ||
289 | if (pid == -1) { | 289 | if (pid == -1) { |
290 | thread = winch_tramp(fd, tty, &thread_fd, &stack); | 290 | thread = winch_tramp(fd, port, &thread_fd, &stack); |
291 | if (thread < 0) | 291 | if (thread < 0) |
292 | return; | 292 | return; |
293 | 293 | ||
294 | register_winch_irq(thread_fd, fd, thread, tty, stack); | 294 | register_winch_irq(thread_fd, fd, thread, port, stack); |
295 | 295 | ||
296 | count = write(thread_fd, &c, sizeof(c)); | 296 | count = write(thread_fd, &c, sizeof(c)); |
297 | if (count != sizeof(c)) | 297 | if (count != sizeof(c)) |
diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h index dc693298eb8f..03f1b565c5f9 100644 --- a/arch/um/drivers/chan_user.h +++ b/arch/um/drivers/chan_user.h | |||
@@ -38,10 +38,10 @@ extern int generic_window_size(int fd, void *unused, unsigned short *rows_out, | |||
38 | unsigned short *cols_out); | 38 | unsigned short *cols_out); |
39 | extern void generic_free(void *data); | 39 | extern void generic_free(void *data); |
40 | 40 | ||
41 | struct tty_struct; | 41 | struct tty_port; |
42 | extern void register_winch(int fd, struct tty_struct *tty); | 42 | extern void register_winch(int fd, struct tty_port *port); |
43 | extern void register_winch_irq(int fd, int tty_fd, int pid, | 43 | extern void register_winch_irq(int fd, int tty_fd, int pid, |
44 | struct tty_struct *tty, unsigned long stack); | 44 | struct tty_port *port, unsigned long stack); |
45 | 45 | ||
46 | #define __channel_help(fn, prefix) \ | 46 | #define __channel_help(fn, prefix) \ |
47 | __uml_help(fn, prefix "[0-9]*=<channel description>\n" \ | 47 | __uml_help(fn, prefix "[0-9]*=<channel description>\n" \ |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index f1b38571f94e..be541cf69fd2 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -305,7 +305,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty) | |||
305 | return ret; | 305 | return ret; |
306 | 306 | ||
307 | if (!line->sigio) { | 307 | if (!line->sigio) { |
308 | chan_enable_winch(line->chan_out, tty); | 308 | chan_enable_winch(line->chan_out, port); |
309 | line->sigio = 1; | 309 | line->sigio = 1; |
310 | } | 310 | } |
311 | 311 | ||
@@ -315,8 +315,22 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty) | |||
315 | return 0; | 315 | return 0; |
316 | } | 316 | } |
317 | 317 | ||
318 | static void unregister_winch(struct tty_struct *tty); | ||
319 | |||
320 | static void line_destruct(struct tty_port *port) | ||
321 | { | ||
322 | struct tty_struct *tty = tty_port_tty_get(port); | ||
323 | struct line *line = tty->driver_data; | ||
324 | |||
325 | if (line->sigio) { | ||
326 | unregister_winch(tty); | ||
327 | line->sigio = 0; | ||
328 | } | ||
329 | } | ||
330 | |||
318 | static const struct tty_port_operations line_port_ops = { | 331 | static const struct tty_port_operations line_port_ops = { |
319 | .activate = line_activate, | 332 | .activate = line_activate, |
333 | .destruct = line_destruct, | ||
320 | }; | 334 | }; |
321 | 335 | ||
322 | int line_open(struct tty_struct *tty, struct file *filp) | 336 | int line_open(struct tty_struct *tty, struct file *filp) |
@@ -340,18 +354,6 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty, | |||
340 | return 0; | 354 | return 0; |
341 | } | 355 | } |
342 | 356 | ||
343 | static void unregister_winch(struct tty_struct *tty); | ||
344 | |||
345 | void line_cleanup(struct tty_struct *tty) | ||
346 | { | ||
347 | struct line *line = tty->driver_data; | ||
348 | |||
349 | if (line->sigio) { | ||
350 | unregister_winch(tty); | ||
351 | line->sigio = 0; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | void line_close(struct tty_struct *tty, struct file * filp) | 357 | void line_close(struct tty_struct *tty, struct file * filp) |
356 | { | 358 | { |
357 | struct line *line = tty->driver_data; | 359 | struct line *line = tty->driver_data; |
@@ -601,7 +603,7 @@ struct winch { | |||
601 | int fd; | 603 | int fd; |
602 | int tty_fd; | 604 | int tty_fd; |
603 | int pid; | 605 | int pid; |
604 | struct tty_struct *tty; | 606 | struct tty_port *port; |
605 | unsigned long stack; | 607 | unsigned long stack; |
606 | struct work_struct work; | 608 | struct work_struct work; |
607 | }; | 609 | }; |
@@ -655,7 +657,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
655 | goto out; | 657 | goto out; |
656 | } | 658 | } |
657 | } | 659 | } |
658 | tty = winch->tty; | 660 | tty = tty_port_tty_get(winch->port); |
659 | if (tty != NULL) { | 661 | if (tty != NULL) { |
660 | line = tty->driver_data; | 662 | line = tty->driver_data; |
661 | if (line != NULL) { | 663 | if (line != NULL) { |
@@ -663,6 +665,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
663 | &tty->winsize.ws_col); | 665 | &tty->winsize.ws_col); |
664 | kill_pgrp(tty->pgrp, SIGWINCH, 1); | 666 | kill_pgrp(tty->pgrp, SIGWINCH, 1); |
665 | } | 667 | } |
668 | tty_kref_put(tty); | ||
666 | } | 669 | } |
667 | out: | 670 | out: |
668 | if (winch->fd != -1) | 671 | if (winch->fd != -1) |
@@ -670,7 +673,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
670 | return IRQ_HANDLED; | 673 | return IRQ_HANDLED; |
671 | } | 674 | } |
672 | 675 | ||
673 | void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | 676 | void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, |
674 | unsigned long stack) | 677 | unsigned long stack) |
675 | { | 678 | { |
676 | struct winch *winch; | 679 | struct winch *winch; |
@@ -685,7 +688,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | |||
685 | .fd = fd, | 688 | .fd = fd, |
686 | .tty_fd = tty_fd, | 689 | .tty_fd = tty_fd, |
687 | .pid = pid, | 690 | .pid = pid, |
688 | .tty = tty, | 691 | .port = port, |
689 | .stack = stack }); | 692 | .stack = stack }); |
690 | 693 | ||
691 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, | 694 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, |
@@ -714,15 +717,18 @@ static void unregister_winch(struct tty_struct *tty) | |||
714 | { | 717 | { |
715 | struct list_head *ele, *next; | 718 | struct list_head *ele, *next; |
716 | struct winch *winch; | 719 | struct winch *winch; |
720 | struct tty_struct *wtty; | ||
717 | 721 | ||
718 | spin_lock(&winch_handler_lock); | 722 | spin_lock(&winch_handler_lock); |
719 | 723 | ||
720 | list_for_each_safe(ele, next, &winch_handlers) { | 724 | list_for_each_safe(ele, next, &winch_handlers) { |
721 | winch = list_entry(ele, struct winch, list); | 725 | winch = list_entry(ele, struct winch, list); |
722 | if (winch->tty == tty) { | 726 | wtty = tty_port_tty_get(winch->port); |
727 | if (wtty == tty) { | ||
723 | free_winch(winch); | 728 | free_winch(winch); |
724 | break; | 729 | break; |
725 | } | 730 | } |
731 | tty_kref_put(wtty); | ||
726 | } | 732 | } |
727 | spin_unlock(&winch_handler_lock); | 733 | spin_unlock(&winch_handler_lock); |
728 | } | 734 | } |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index d8926c303629..39f186252e02 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -218,6 +218,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
218 | spin_lock_irqsave(&lp->lock, flags); | 218 | spin_lock_irqsave(&lp->lock, flags); |
219 | 219 | ||
220 | len = (*lp->write)(lp->fd, skb, lp); | 220 | len = (*lp->write)(lp->fd, skb, lp); |
221 | skb_tx_timestamp(skb); | ||
221 | 222 | ||
222 | if (len == skb->len) { | 223 | if (len == skb->len) { |
223 | dev->stats.tx_packets++; | 224 | dev->stats.tx_packets++; |
@@ -281,6 +282,7 @@ static void uml_net_get_drvinfo(struct net_device *dev, | |||
281 | static const struct ethtool_ops uml_net_ethtool_ops = { | 282 | static const struct ethtool_ops uml_net_ethtool_ops = { |
282 | .get_drvinfo = uml_net_get_drvinfo, | 283 | .get_drvinfo = uml_net_get_drvinfo, |
283 | .get_link = ethtool_op_get_link, | 284 | .get_link = ethtool_op_get_link, |
285 | .get_ts_info = ethtool_op_get_ts_info, | ||
284 | }; | 286 | }; |
285 | 287 | ||
286 | static void uml_net_user_timer_expire(unsigned long _conn) | 288 | static void uml_net_user_timer_expire(unsigned long _conn) |
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 16fdd0a0f9d6..b8d14fa52059 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
@@ -105,7 +105,6 @@ static const struct tty_operations ssl_ops = { | |||
105 | .throttle = line_throttle, | 105 | .throttle = line_throttle, |
106 | .unthrottle = line_unthrottle, | 106 | .unthrottle = line_unthrottle, |
107 | .install = ssl_install, | 107 | .install = ssl_install, |
108 | .cleanup = line_cleanup, | ||
109 | .hangup = line_hangup, | 108 | .hangup = line_hangup, |
110 | }; | 109 | }; |
111 | 110 | ||
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 827777af3f6d..7b361f36ca96 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
@@ -110,7 +110,6 @@ static const struct tty_operations console_ops = { | |||
110 | .set_termios = line_set_termios, | 110 | .set_termios = line_set_termios, |
111 | .throttle = line_throttle, | 111 | .throttle = line_throttle, |
112 | .unthrottle = line_unthrottle, | 112 | .unthrottle = line_unthrottle, |
113 | .cleanup = line_cleanup, | ||
114 | .hangup = line_hangup, | 113 | .hangup = line_hangup, |
115 | }; | 114 | }; |
116 | 115 | ||
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index b1469fe93295..9d9f1b4bf826 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <sysdep/mcontext.h> | 15 | #include <sysdep/mcontext.h> |
16 | #include "internal.h" | 16 | #include "internal.h" |
17 | 17 | ||
18 | void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = { | 18 | void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { |
19 | [SIGTRAP] = relay_signal, | 19 | [SIGTRAP] = relay_signal, |
20 | [SIGFPE] = relay_signal, | 20 | [SIGFPE] = relay_signal, |
21 | [SIGILL] = relay_signal, | 21 | [SIGILL] = relay_signal, |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index da4b9e9999fd..337518c5042a 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <sys/mman.h> | 15 | #include <sys/mman.h> |
16 | #include <sys/stat.h> | 16 | #include <sys/stat.h> |
17 | #include <sys/wait.h> | 17 | #include <sys/wait.h> |
18 | #include <sys/time.h> | ||
19 | #include <sys/resource.h> | ||
18 | #include <asm/unistd.h> | 20 | #include <asm/unistd.h> |
19 | #include <init.h> | 21 | #include <init.h> |
20 | #include <os.h> | 22 | #include <os.h> |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a4f24f5b1218..26bd79261532 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -120,6 +120,7 @@ config X86 | |||
120 | select OLD_SIGSUSPEND3 if X86_32 || IA32_EMULATION | 120 | select OLD_SIGSUSPEND3 if X86_32 || IA32_EMULATION |
121 | select OLD_SIGACTION if X86_32 | 121 | select OLD_SIGACTION if X86_32 |
122 | select COMPAT_OLD_SIGACTION if IA32_EMULATION | 122 | select COMPAT_OLD_SIGACTION if IA32_EMULATION |
123 | select RTC_LIB | ||
123 | 124 | ||
124 | config INSTRUCTION_DECODER | 125 | config INSTRUCTION_DECODER |
125 | def_bool y | 126 | def_bool y |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 93fe929d1cee..a8466f203e62 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -100,6 +100,7 @@ | |||
100 | #define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */ | 100 | #define X86_FEATURE_AMD_DCM (3*32+27) /* multi-node processor */ |
101 | #define X86_FEATURE_APERFMPERF (3*32+28) /* APERFMPERF */ | 101 | #define X86_FEATURE_APERFMPERF (3*32+28) /* APERFMPERF */ |
102 | #define X86_FEATURE_EAGER_FPU (3*32+29) /* "eagerfpu" Non lazy FPU restore */ | 102 | #define X86_FEATURE_EAGER_FPU (3*32+29) /* "eagerfpu" Non lazy FPU restore */ |
103 | #define X86_FEATURE_NONSTOP_TSC_S3 (3*32+30) /* TSC doesn't stop in S3 state */ | ||
103 | 104 | ||
104 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | 105 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ |
105 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ | 106 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 1905ce98bee0..e7ae0d89e7e0 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -96,6 +96,18 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | |||
96 | sched_clock_stable = 1; | 96 | sched_clock_stable = 1; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* Penwell and Cloverview have the TSC which doesn't sleep on S3 */ | ||
100 | if (c->x86 == 6) { | ||
101 | switch (c->x86_model) { | ||
102 | case 0x27: /* Penwell */ | ||
103 | case 0x35: /* Cloverview */ | ||
104 | set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3); | ||
105 | break; | ||
106 | default: | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | |||
99 | /* | 111 | /* |
100 | * There is a known erratum on Pentium III and Core Solo | 112 | * There is a known erratum on Pentium III and Core Solo |
101 | * and Core Duo CPUs. | 113 | * and Core Duo CPUs. |
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 2e8f3d3b5641..198eb201ed3b 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <asm/x86_init.h> | 13 | #include <asm/x86_init.h> |
14 | #include <asm/time.h> | 14 | #include <asm/time.h> |
15 | #include <asm/mrst.h> | 15 | #include <asm/mrst.h> |
16 | #include <asm/rtc.h> | ||
16 | 17 | ||
17 | #ifdef CONFIG_X86_32 | 18 | #ifdef CONFIG_X86_32 |
18 | /* | 19 | /* |
@@ -36,70 +37,24 @@ EXPORT_SYMBOL(rtc_lock); | |||
36 | * nowtime is written into the registers of the CMOS clock, it will | 37 | * nowtime is written into the registers of the CMOS clock, it will |
37 | * jump to the next second precisely 500 ms later. Check the Motorola | 38 | * jump to the next second precisely 500 ms later. Check the Motorola |
38 | * MC146818A or Dallas DS12887 data sheet for details. | 39 | * MC146818A or Dallas DS12887 data sheet for details. |
39 | * | ||
40 | * BUG: This routine does not handle hour overflow properly; it just | ||
41 | * sets the minutes. Usually you'll only notice that after reboot! | ||
42 | */ | 40 | */ |
43 | int mach_set_rtc_mmss(unsigned long nowtime) | 41 | int mach_set_rtc_mmss(unsigned long nowtime) |
44 | { | 42 | { |
45 | int real_seconds, real_minutes, cmos_minutes; | 43 | struct rtc_time tm; |
46 | unsigned char save_control, save_freq_select; | ||
47 | unsigned long flags; | ||
48 | int retval = 0; | 44 | int retval = 0; |
49 | 45 | ||
50 | spin_lock_irqsave(&rtc_lock, flags); | 46 | rtc_time_to_tm(nowtime, &tm); |
51 | 47 | if (!rtc_valid_tm(&tm)) { | |
52 | /* tell the clock it's being set */ | 48 | retval = set_rtc_time(&tm); |
53 | save_control = CMOS_READ(RTC_CONTROL); | 49 | if (retval) |
54 | CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); | 50 | printk(KERN_ERR "%s: RTC write failed with error %d\n", |
55 | 51 | __FUNCTION__, retval); | |
56 | /* stop and reset prescaler */ | ||
57 | save_freq_select = CMOS_READ(RTC_FREQ_SELECT); | ||
58 | CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | ||
59 | |||
60 | cmos_minutes = CMOS_READ(RTC_MINUTES); | ||
61 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
62 | cmos_minutes = bcd2bin(cmos_minutes); | ||
63 | |||
64 | /* | ||
65 | * since we're only adjusting minutes and seconds, | ||
66 | * don't interfere with hour overflow. This avoids | ||
67 | * messing with unknown time zones but requires your | ||
68 | * RTC not to be off by more than 15 minutes | ||
69 | */ | ||
70 | real_seconds = nowtime % 60; | ||
71 | real_minutes = nowtime / 60; | ||
72 | /* correct for half hour time zone */ | ||
73 | if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) | ||
74 | real_minutes += 30; | ||
75 | real_minutes %= 60; | ||
76 | |||
77 | if (abs(real_minutes - cmos_minutes) < 30) { | ||
78 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
79 | real_seconds = bin2bcd(real_seconds); | ||
80 | real_minutes = bin2bcd(real_minutes); | ||
81 | } | ||
82 | CMOS_WRITE(real_seconds, RTC_SECONDS); | ||
83 | CMOS_WRITE(real_minutes, RTC_MINUTES); | ||
84 | } else { | 52 | } else { |
85 | printk_once(KERN_NOTICE | 53 | printk(KERN_ERR |
86 | "set_rtc_mmss: can't update from %d to %d\n", | 54 | "%s: Invalid RTC value: write of %lx to RTC failed\n", |
87 | cmos_minutes, real_minutes); | 55 | __FUNCTION__, nowtime); |
88 | retval = -1; | 56 | retval = -EINVAL; |
89 | } | 57 | } |
90 | |||
91 | /* The following flags have to be released exactly in this order, | ||
92 | * otherwise the DS12887 (popular MC146818A clone with integrated | ||
93 | * battery and quartz) will not reset the oscillator and will not | ||
94 | * update precisely 500 ms later. You won't find this mentioned in | ||
95 | * the Dallas Semiconductor data sheets, but who believes data | ||
96 | * sheets anyway ... -- Markus Kuhn | ||
97 | */ | ||
98 | CMOS_WRITE(save_control, RTC_CONTROL); | ||
99 | CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); | ||
100 | |||
101 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
102 | |||
103 | return retval; | 58 | return retval; |
104 | } | 59 | } |
105 | 60 | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 4b9ea101fe3b..098b3cfda72e 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -768,7 +768,8 @@ static cycle_t read_tsc(struct clocksource *cs) | |||
768 | 768 | ||
769 | static void resume_tsc(struct clocksource *cs) | 769 | static void resume_tsc(struct clocksource *cs) |
770 | { | 770 | { |
771 | clocksource_tsc.cycle_last = 0; | 771 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) |
772 | clocksource_tsc.cycle_last = 0; | ||
772 | } | 773 | } |
773 | 774 | ||
774 | static struct clocksource clocksource_tsc = { | 775 | static struct clocksource clocksource_tsc = { |
@@ -939,6 +940,9 @@ static int __init init_tsc_clocksource(void) | |||
939 | clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; | 940 | clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; |
940 | } | 941 | } |
941 | 942 | ||
943 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) | ||
944 | clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; | ||
945 | |||
942 | /* | 946 | /* |
943 | * Trust the results of the earlier calibration on systems | 947 | * Trust the results of the earlier calibration on systems |
944 | * exporting a reliable TSC. | 948 | * exporting a reliable TSC. |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 5f2ecaf3f9d8..28d9efacc9b6 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <asm/cacheflush.h> | 48 | #include <asm/cacheflush.h> |
49 | #include <asm/tlbflush.h> | 49 | #include <asm/tlbflush.h> |
50 | #include <asm/x86_init.h> | 50 | #include <asm/x86_init.h> |
51 | #include <asm/rtc.h> | ||
51 | 52 | ||
52 | #define EFI_DEBUG 1 | 53 | #define EFI_DEBUG 1 |
53 | 54 | ||
@@ -258,10 +259,10 @@ static efi_status_t __init phys_efi_get_time(efi_time_t *tm, | |||
258 | 259 | ||
259 | int efi_set_rtc_mmss(unsigned long nowtime) | 260 | int efi_set_rtc_mmss(unsigned long nowtime) |
260 | { | 261 | { |
261 | int real_seconds, real_minutes; | ||
262 | efi_status_t status; | 262 | efi_status_t status; |
263 | efi_time_t eft; | 263 | efi_time_t eft; |
264 | efi_time_cap_t cap; | 264 | efi_time_cap_t cap; |
265 | struct rtc_time tm; | ||
265 | 266 | ||
266 | status = efi.get_time(&eft, &cap); | 267 | status = efi.get_time(&eft, &cap); |
267 | if (status != EFI_SUCCESS) { | 268 | if (status != EFI_SUCCESS) { |
@@ -269,13 +270,20 @@ int efi_set_rtc_mmss(unsigned long nowtime) | |||
269 | return -1; | 270 | return -1; |
270 | } | 271 | } |
271 | 272 | ||
272 | real_seconds = nowtime % 60; | 273 | rtc_time_to_tm(nowtime, &tm); |
273 | real_minutes = nowtime / 60; | 274 | if (!rtc_valid_tm(&tm)) { |
274 | if (((abs(real_minutes - eft.minute) + 15)/30) & 1) | 275 | eft.year = tm.tm_year + 1900; |
275 | real_minutes += 30; | 276 | eft.month = tm.tm_mon + 1; |
276 | real_minutes %= 60; | 277 | eft.day = tm.tm_mday; |
277 | eft.minute = real_minutes; | 278 | eft.minute = tm.tm_min; |
278 | eft.second = real_seconds; | 279 | eft.second = tm.tm_sec; |
280 | eft.nanosecond = 0; | ||
281 | } else { | ||
282 | printk(KERN_ERR | ||
283 | "%s: Invalid EFI RTC value: write of %lx to EFI RTC failed\n", | ||
284 | __FUNCTION__, nowtime); | ||
285 | return -1; | ||
286 | } | ||
279 | 287 | ||
280 | status = efi.set_time(&eft); | 288 | status = efi.set_time(&eft); |
281 | if (status != EFI_SUCCESS) { | 289 | if (status != EFI_SUCCESS) { |
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c index 225bd0f0f675..d62b0a3b5c14 100644 --- a/arch/x86/platform/mrst/vrtc.c +++ b/arch/x86/platform/mrst/vrtc.c | |||
@@ -85,27 +85,35 @@ unsigned long vrtc_get_time(void) | |||
85 | return mktime(year, mon, mday, hour, min, sec); | 85 | return mktime(year, mon, mday, hour, min, sec); |
86 | } | 86 | } |
87 | 87 | ||
88 | /* Only care about the minutes and seconds */ | ||
89 | int vrtc_set_mmss(unsigned long nowtime) | 88 | int vrtc_set_mmss(unsigned long nowtime) |
90 | { | 89 | { |
91 | int real_sec, real_min; | ||
92 | unsigned long flags; | 90 | unsigned long flags; |
93 | int vrtc_min; | 91 | struct rtc_time tm; |
94 | 92 | int year; | |
95 | spin_lock_irqsave(&rtc_lock, flags); | 93 | int retval = 0; |
96 | vrtc_min = vrtc_cmos_read(RTC_MINUTES); | 94 | |
97 | 95 | rtc_time_to_tm(nowtime, &tm); | |
98 | real_sec = nowtime % 60; | 96 | if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) { |
99 | real_min = nowtime / 60; | 97 | /* |
100 | if (((abs(real_min - vrtc_min) + 15)/30) & 1) | 98 | * tm.year is the number of years since 1900, and the |
101 | real_min += 30; | 99 | * vrtc need the years since 1972. |
102 | real_min %= 60; | 100 | */ |
103 | 101 | year = tm.tm_year - 72; | |
104 | vrtc_cmos_write(real_sec, RTC_SECONDS); | 102 | spin_lock_irqsave(&rtc_lock, flags); |
105 | vrtc_cmos_write(real_min, RTC_MINUTES); | 103 | vrtc_cmos_write(year, RTC_YEAR); |
106 | spin_unlock_irqrestore(&rtc_lock, flags); | 104 | vrtc_cmos_write(tm.tm_mon, RTC_MONTH); |
107 | 105 | vrtc_cmos_write(tm.tm_mday, RTC_DAY_OF_MONTH); | |
108 | return 0; | 106 | vrtc_cmos_write(tm.tm_hour, RTC_HOURS); |
107 | vrtc_cmos_write(tm.tm_min, RTC_MINUTES); | ||
108 | vrtc_cmos_write(tm.tm_sec, RTC_SECONDS); | ||
109 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
110 | } else { | ||
111 | printk(KERN_ERR | ||
112 | "%s: Invalid vRTC value: write of %lx to vRTC failed\n", | ||
113 | __FUNCTION__, nowtime); | ||
114 | retval = -EINVAL; | ||
115 | } | ||
116 | return retval; | ||
109 | } | 117 | } |
110 | 118 | ||
111 | void __init mrst_rtc_init(void) | 119 | void __init mrst_rtc_init(void) |