aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/time.c')
-rw-r--r--arch/s390/kernel/time.c76
1 files changed, 48 insertions, 28 deletions
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 34162a0b2caa..d906bf19c14a 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -36,6 +36,7 @@
36#include <linux/notifier.h> 36#include <linux/notifier.h>
37#include <linux/clocksource.h> 37#include <linux/clocksource.h>
38#include <linux/clockchips.h> 38#include <linux/clockchips.h>
39#include <linux/gfp.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/delay.h> 41#include <asm/delay.h>
41#include <asm/s390_ext.h> 42#include <asm/s390_ext.h>
@@ -51,14 +52,6 @@
51#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ) 52#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ)
52#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12) 53#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
53 54
54/*
55 * Create a small time difference between the timer interrupts
56 * on the different cpus to avoid lock contention.
57 */
58#define CPU_DEVIATION (smp_processor_id() << 12)
59
60#define TICK_SIZE tick
61
62u64 sched_clock_base_cc = -1; /* Force to data section. */ 55u64 sched_clock_base_cc = -1; /* Force to data section. */
63EXPORT_SYMBOL_GPL(sched_clock_base_cc); 56EXPORT_SYMBOL_GPL(sched_clock_base_cc);
64 57
@@ -81,15 +74,15 @@ unsigned long long monotonic_clock(void)
81} 74}
82EXPORT_SYMBOL(monotonic_clock); 75EXPORT_SYMBOL(monotonic_clock);
83 76
84void tod_to_timeval(__u64 todval, struct timespec *xtime) 77void tod_to_timeval(__u64 todval, struct timespec *xt)
85{ 78{
86 unsigned long long sec; 79 unsigned long long sec;
87 80
88 sec = todval >> 12; 81 sec = todval >> 12;
89 do_div(sec, 1000000); 82 do_div(sec, 1000000);
90 xtime->tv_sec = sec; 83 xt->tv_sec = sec;
91 todval -= (sec * 1000000) << 12; 84 todval -= (sec * 1000000) << 12;
92 xtime->tv_nsec = ((todval * 1000) >> 12); 85 xt->tv_nsec = ((todval * 1000) >> 12);
93} 86}
94EXPORT_SYMBOL(tod_to_timeval); 87EXPORT_SYMBOL(tod_to_timeval);
95 88
@@ -214,7 +207,8 @@ struct clocksource * __init clocksource_default_clock(void)
214 return &clocksource_tod; 207 return &clocksource_tod;
215} 208}
216 209
217void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) 210void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
211 u32 mult)
218{ 212{
219 if (clock != &clocksource_tod) 213 if (clock != &clocksource_tod)
220 return; 214 return;
@@ -223,10 +217,11 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
223 ++vdso_data->tb_update_count; 217 ++vdso_data->tb_update_count;
224 smp_wmb(); 218 smp_wmb();
225 vdso_data->xtime_tod_stamp = clock->cycle_last; 219 vdso_data->xtime_tod_stamp = clock->cycle_last;
226 vdso_data->xtime_clock_sec = xtime.tv_sec; 220 vdso_data->xtime_clock_sec = wall_time->tv_sec;
227 vdso_data->xtime_clock_nsec = xtime.tv_nsec; 221 vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
228 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; 222 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
229 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; 223 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
224 vdso_data->ntp_mult = mult;
230 smp_wmb(); 225 smp_wmb();
231 ++vdso_data->tb_update_count; 226 ++vdso_data->tb_update_count;
232} 227}
@@ -334,7 +329,7 @@ int get_sync_clock(unsigned long long *clock)
334 sw0 = atomic_read(sw_ptr); 329 sw0 = atomic_read(sw_ptr);
335 *clock = get_clock(); 330 *clock = get_clock();
336 sw1 = atomic_read(sw_ptr); 331 sw1 = atomic_read(sw_ptr);
337 put_cpu_var(clock_sync_sync); 332 put_cpu_var(clock_sync_word);
338 if (sw0 == sw1 && (sw0 & 0x80000000U)) 333 if (sw0 == sw1 && (sw0 & 0x80000000U))
339 /* Success: time is in sync. */ 334 /* Success: time is in sync. */
340 return 0; 335 return 0;
@@ -384,7 +379,7 @@ static inline int check_sync_clock(void)
384 379
385 sw_ptr = &get_cpu_var(clock_sync_word); 380 sw_ptr = &get_cpu_var(clock_sync_word);
386 rc = (atomic_read(sw_ptr) & 0x80000000U) != 0; 381 rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
387 put_cpu_var(clock_sync_sync); 382 put_cpu_var(clock_sync_word);
388 return rc; 383 return rc;
389} 384}
390 385
@@ -1123,14 +1118,18 @@ static struct sys_device etr_port1_dev = {
1123/* 1118/*
1124 * ETR class attributes 1119 * ETR class attributes
1125 */ 1120 */
1126static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf) 1121static ssize_t etr_stepping_port_show(struct sysdev_class *class,
1122 struct sysdev_class_attribute *attr,
1123 char *buf)
1127{ 1124{
1128 return sprintf(buf, "%i\n", etr_port0.esw.p); 1125 return sprintf(buf, "%i\n", etr_port0.esw.p);
1129} 1126}
1130 1127
1131static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL); 1128static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
1132 1129
1133static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf) 1130static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
1131 struct sysdev_class_attribute *attr,
1132 char *buf)
1134{ 1133{
1135 char *mode_str; 1134 char *mode_str;
1136 1135
@@ -1591,7 +1590,9 @@ static struct sysdev_class stp_sysclass = {
1591 .name = "stp", 1590 .name = "stp",
1592}; 1591};
1593 1592
1594static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf) 1593static ssize_t stp_ctn_id_show(struct sysdev_class *class,
1594 struct sysdev_class_attribute *attr,
1595 char *buf)
1595{ 1596{
1596 if (!stp_online) 1597 if (!stp_online)
1597 return -ENODATA; 1598 return -ENODATA;
@@ -1601,7 +1602,9 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
1601 1602
1602static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); 1603static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
1603 1604
1604static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf) 1605static ssize_t stp_ctn_type_show(struct sysdev_class *class,
1606 struct sysdev_class_attribute *attr,
1607 char *buf)
1605{ 1608{
1606 if (!stp_online) 1609 if (!stp_online)
1607 return -ENODATA; 1610 return -ENODATA;
@@ -1610,7 +1613,9 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
1610 1613
1611static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); 1614static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
1612 1615
1613static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf) 1616static ssize_t stp_dst_offset_show(struct sysdev_class *class,
1617 struct sysdev_class_attribute *attr,
1618 char *buf)
1614{ 1619{
1615 if (!stp_online || !(stp_info.vbits & 0x2000)) 1620 if (!stp_online || !(stp_info.vbits & 0x2000))
1616 return -ENODATA; 1621 return -ENODATA;
@@ -1619,7 +1624,9 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
1619 1624
1620static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); 1625static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
1621 1626
1622static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf) 1627static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
1628 struct sysdev_class_attribute *attr,
1629 char *buf)
1623{ 1630{
1624 if (!stp_online || !(stp_info.vbits & 0x8000)) 1631 if (!stp_online || !(stp_info.vbits & 0x8000))
1625 return -ENODATA; 1632 return -ENODATA;
@@ -1628,7 +1635,9 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
1628 1635
1629static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); 1636static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
1630 1637
1631static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf) 1638static ssize_t stp_stratum_show(struct sysdev_class *class,
1639 struct sysdev_class_attribute *attr,
1640 char *buf)
1632{ 1641{
1633 if (!stp_online) 1642 if (!stp_online)
1634 return -ENODATA; 1643 return -ENODATA;
@@ -1637,7 +1646,9 @@ static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
1637 1646
1638static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL); 1647static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL);
1639 1648
1640static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf) 1649static ssize_t stp_time_offset_show(struct sysdev_class *class,
1650 struct sysdev_class_attribute *attr,
1651 char *buf)
1641{ 1652{
1642 if (!stp_online || !(stp_info.vbits & 0x0800)) 1653 if (!stp_online || !(stp_info.vbits & 0x0800))
1643 return -ENODATA; 1654 return -ENODATA;
@@ -1646,7 +1657,9 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
1646 1657
1647static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL); 1658static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
1648 1659
1649static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf) 1660static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
1661 struct sysdev_class_attribute *attr,
1662 char *buf)
1650{ 1663{
1651 if (!stp_online || !(stp_info.vbits & 0x4000)) 1664 if (!stp_online || !(stp_info.vbits & 0x4000))
1652 return -ENODATA; 1665 return -ENODATA;
@@ -1656,7 +1669,9 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
1656static SYSDEV_CLASS_ATTR(time_zone_offset, 0400, 1669static SYSDEV_CLASS_ATTR(time_zone_offset, 0400,
1657 stp_time_zone_offset_show, NULL); 1670 stp_time_zone_offset_show, NULL);
1658 1671
1659static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf) 1672static ssize_t stp_timing_mode_show(struct sysdev_class *class,
1673 struct sysdev_class_attribute *attr,
1674 char *buf)
1660{ 1675{
1661 if (!stp_online) 1676 if (!stp_online)
1662 return -ENODATA; 1677 return -ENODATA;
@@ -1665,7 +1680,9 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
1665 1680
1666static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); 1681static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
1667 1682
1668static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf) 1683static ssize_t stp_timing_state_show(struct sysdev_class *class,
1684 struct sysdev_class_attribute *attr,
1685 char *buf)
1669{ 1686{
1670 if (!stp_online) 1687 if (!stp_online)
1671 return -ENODATA; 1688 return -ENODATA;
@@ -1674,12 +1691,15 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
1674 1691
1675static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL); 1692static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
1676 1693
1677static ssize_t stp_online_show(struct sysdev_class *class, char *buf) 1694static ssize_t stp_online_show(struct sysdev_class *class,
1695 struct sysdev_class_attribute *attr,
1696 char *buf)
1678{ 1697{
1679 return sprintf(buf, "%i\n", stp_online); 1698 return sprintf(buf, "%i\n", stp_online);
1680} 1699}
1681 1700
1682static ssize_t stp_online_store(struct sysdev_class *class, 1701static ssize_t stp_online_store(struct sysdev_class *class,
1702 struct sysdev_class_attribute *attr,
1683 const char *buf, size_t count) 1703 const char *buf, size_t count)
1684{ 1704{
1685 unsigned int value; 1705 unsigned int value;