diff options
Diffstat (limited to 'arch/s390/kernel/time.c')
-rw-r--r-- | arch/s390/kernel/time.c | 76 |
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 | |||
62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ | 55 | u64 sched_clock_base_cc = -1; /* Force to data section. */ |
63 | EXPORT_SYMBOL_GPL(sched_clock_base_cc); | 56 | EXPORT_SYMBOL_GPL(sched_clock_base_cc); |
64 | 57 | ||
@@ -81,15 +74,15 @@ unsigned long long monotonic_clock(void) | |||
81 | } | 74 | } |
82 | EXPORT_SYMBOL(monotonic_clock); | 75 | EXPORT_SYMBOL(monotonic_clock); |
83 | 76 | ||
84 | void tod_to_timeval(__u64 todval, struct timespec *xtime) | 77 | void 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 | } |
94 | EXPORT_SYMBOL(tod_to_timeval); | 87 | EXPORT_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 | ||
217 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | 210 | void 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 | */ |
1126 | static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf) | 1121 | static 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 | ||
1131 | static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL); | 1128 | static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL); |
1132 | 1129 | ||
1133 | static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf) | 1130 | static 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 | ||
1594 | static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf) | 1593 | static 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 | ||
1602 | static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); | 1603 | static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); |
1603 | 1604 | ||
1604 | static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf) | 1605 | static 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 | ||
1611 | static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); | 1614 | static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); |
1612 | 1615 | ||
1613 | static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf) | 1616 | static 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 | ||
1620 | static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); | 1625 | static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); |
1621 | 1626 | ||
1622 | static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf) | 1627 | static 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 | ||
1629 | static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); | 1636 | static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); |
1630 | 1637 | ||
1631 | static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf) | 1638 | static 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 | ||
1638 | static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL); | 1647 | static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL); |
1639 | 1648 | ||
1640 | static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf) | 1649 | static 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 | ||
1647 | static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL); | 1658 | static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL); |
1648 | 1659 | ||
1649 | static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf) | 1660 | static 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) | |||
1656 | static SYSDEV_CLASS_ATTR(time_zone_offset, 0400, | 1669 | static SYSDEV_CLASS_ATTR(time_zone_offset, 0400, |
1657 | stp_time_zone_offset_show, NULL); | 1670 | stp_time_zone_offset_show, NULL); |
1658 | 1671 | ||
1659 | static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf) | 1672 | static 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 | ||
1666 | static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); | 1681 | static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); |
1667 | 1682 | ||
1668 | static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf) | 1683 | static 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 | ||
1675 | static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL); | 1692 | static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL); |
1676 | 1693 | ||
1677 | static ssize_t stp_online_show(struct sysdev_class *class, char *buf) | 1694 | static 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 | ||
1682 | static ssize_t stp_online_store(struct sysdev_class *class, | 1701 | static 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; |