[S390] correct ktime to tod clock comparator conversion
[linux-2.6.git] / arch / s390 / kernel / time.c
index c537164..14da278 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/cpu.h>
 #include <linux/stop_machine.h>
 #include <linux/time.h>
-#include <linux/sysdev.h>
+#include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/smp.h>
@@ -48,6 +48,7 @@
 #include <asm/timer.h>
 #include <asm/etr.h>
 #include <asm/cio.h>
+#include "entry.h"
 
 /* change this if you have some constant time drift */
 #define USECS_PER_JIFFY     ((unsigned long) 1000000/HZ)
@@ -112,11 +113,14 @@ static void fixup_clock_comparator(unsigned long long delta)
 static int s390_next_ktime(ktime_t expires,
                           struct clock_event_device *evt)
 {
-       s64 nsecs;
+       struct timespec ts;
+       u64 nsecs;
 
-       nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset()));
+       ts.tv_sec = ts.tv_nsec = 0;
+       monotonic_to_bootbased(&ts);
+       nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
        do_div(nsecs, 125);
-       S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9);
+       S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
        set_clock_comparator(S390_lowcore.clock_comparator);
        return 0;
 }
@@ -1115,34 +1119,35 @@ out_unlock:
 /*
  * Sysfs interface functions
  */
-static struct sysdev_class etr_sysclass = {
-       .name   = "etr",
+static struct bus_type etr_subsys = {
+       .name           = "etr",
+       .dev_name       = "etr",
 };
 
-static struct sys_device etr_port0_dev = {
+static struct device etr_port0_dev = {
        .id     = 0,
-       .cls    = &etr_sysclass,
+       .bus    = &etr_subsys,
 };
 
-static struct sys_device etr_port1_dev = {
+static struct device etr_port1_dev = {
        .id     = 1,
-       .cls    = &etr_sysclass,
+       .bus    = &etr_subsys,
 };
 
 /*
- * ETR class attributes
+ * ETR subsys attributes
  */
-static ssize_t etr_stepping_port_show(struct sysdev_class *class,
-                                       struct sysdev_class_attribute *attr,
+static ssize_t etr_stepping_port_show(struct device *dev,
+                                       struct device_attribute *attr,
                                        char *buf)
 {
        return sprintf(buf, "%i\n", etr_port0.esw.p);
 }
 
-static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
+static DEVICE_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
 
-static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
-                                       struct sysdev_class_attribute *attr,
+static ssize_t etr_stepping_mode_show(struct device *dev,
+                                       struct device_attribute *attr,
                                        char *buf)
 {
        char *mode_str;
@@ -1156,12 +1161,12 @@ static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
        return sprintf(buf, "%s\n", mode_str);
 }
 
-static SYSDEV_CLASS_ATTR(stepping_mode, 0400, etr_stepping_mode_show, NULL);
+static DEVICE_ATTR(stepping_mode, 0400, etr_stepping_mode_show, NULL);
 
 /*
  * ETR port attributes
  */
-static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev)
+static inline struct etr_aib *etr_aib_from_dev(struct device *dev)
 {
        if (dev == &etr_port0_dev)
                return etr_port0_online ? &etr_port0 : NULL;
@@ -1169,8 +1174,8 @@ static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev)
                return etr_port1_online ? &etr_port1 : NULL;
 }
 
-static ssize_t etr_online_show(struct sys_device *dev,
-                               struct sysdev_attribute *attr,
+static ssize_t etr_online_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        unsigned int online;
@@ -1179,8 +1184,8 @@ static ssize_t etr_online_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", online);
 }
 
-static ssize_t etr_online_store(struct sys_device *dev,
-                               struct sysdev_attribute *attr,
+static ssize_t etr_online_store(struct device *dev,
+                               struct device_attribute *attr,
                                const char *buf, size_t count)
 {
        unsigned int value;
@@ -1217,20 +1222,20 @@ out:
        return count;
 }
 
-static SYSDEV_ATTR(online, 0600, etr_online_show, etr_online_store);
+static DEVICE_ATTR(online, 0600, etr_online_show, etr_online_store);
 
-static ssize_t etr_stepping_control_show(struct sys_device *dev,
-                                       struct sysdev_attribute *attr,
+static ssize_t etr_stepping_control_show(struct device *dev,
+                                       struct device_attribute *attr,
                                        char *buf)
 {
        return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?
                       etr_eacr.e0 : etr_eacr.e1);
 }
 
-static SYSDEV_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);
+static DEVICE_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);
 
-static ssize_t etr_mode_code_show(struct sys_device *dev,
-                               struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_mode_code_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
        if (!etr_port0_online && !etr_port1_online)
                /* Status word is not uptodate if both ports are offline. */
@@ -1239,10 +1244,10 @@ static ssize_t etr_mode_code_show(struct sys_device *dev,
                       etr_port0.esw.psc0 : etr_port0.esw.psc1);
 }
 
-static SYSDEV_ATTR(state_code, 0400, etr_mode_code_show, NULL);
+static DEVICE_ATTR(state_code, 0400, etr_mode_code_show, NULL);
 
-static ssize_t etr_untuned_show(struct sys_device *dev,
-                               struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_untuned_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1251,10 +1256,10 @@ static ssize_t etr_untuned_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf1.u);
 }
 
-static SYSDEV_ATTR(untuned, 0400, etr_untuned_show, NULL);
+static DEVICE_ATTR(untuned, 0400, etr_untuned_show, NULL);
 
-static ssize_t etr_network_id_show(struct sys_device *dev,
-                               struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_network_id_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1263,10 +1268,10 @@ static ssize_t etr_network_id_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf1.net_id);
 }
 
-static SYSDEV_ATTR(network, 0400, etr_network_id_show, NULL);
+static DEVICE_ATTR(network, 0400, etr_network_id_show, NULL);
 
-static ssize_t etr_id_show(struct sys_device *dev,
-                       struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_id_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1275,10 +1280,10 @@ static ssize_t etr_id_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf1.etr_id);
 }
 
-static SYSDEV_ATTR(id, 0400, etr_id_show, NULL);
+static DEVICE_ATTR(id, 0400, etr_id_show, NULL);
 
-static ssize_t etr_port_number_show(struct sys_device *dev,
-                       struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_port_number_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1287,10 +1292,10 @@ static ssize_t etr_port_number_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf1.etr_pn);
 }
 
-static SYSDEV_ATTR(port, 0400, etr_port_number_show, NULL);
+static DEVICE_ATTR(port, 0400, etr_port_number_show, NULL);
 
-static ssize_t etr_coupled_show(struct sys_device *dev,
-                       struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_coupled_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1299,10 +1304,10 @@ static ssize_t etr_coupled_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf3.c);
 }
 
-static SYSDEV_ATTR(coupled, 0400, etr_coupled_show, NULL);
+static DEVICE_ATTR(coupled, 0400, etr_coupled_show, NULL);
 
-static ssize_t etr_local_time_show(struct sys_device *dev,
-                       struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_local_time_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1311,10 +1316,10 @@ static ssize_t etr_local_time_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf3.blto);
 }
 
-static SYSDEV_ATTR(local_time, 0400, etr_local_time_show, NULL);
+static DEVICE_ATTR(local_time, 0400, etr_local_time_show, NULL);
 
-static ssize_t etr_utc_offset_show(struct sys_device *dev,
-                       struct sysdev_attribute *attr, char *buf)
+static ssize_t etr_utc_offset_show(struct device *dev,
+                       struct device_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1323,64 +1328,64 @@ static ssize_t etr_utc_offset_show(struct sys_device *dev,
        return sprintf(buf, "%i\n", aib->edf3.buo);
 }
 
-static SYSDEV_ATTR(utc_offset, 0400, etr_utc_offset_show, NULL);
+static DEVICE_ATTR(utc_offset, 0400, etr_utc_offset_show, NULL);
 
-static struct sysdev_attribute *etr_port_attributes[] = {
-       &attr_online,
-       &attr_stepping_control,
-       &attr_state_code,
-       &attr_untuned,
-       &attr_network,
-       &attr_id,
-       &attr_port,
-       &attr_coupled,
-       &attr_local_time,
-       &attr_utc_offset,
+static struct device_attribute *etr_port_attributes[] = {
+       &dev_attr_online,
+       &dev_attr_stepping_control,
+       &dev_attr_state_code,
+       &dev_attr_untuned,
+       &dev_attr_network,
+       &dev_attr_id,
+       &dev_attr_port,
+       &dev_attr_coupled,
+       &dev_attr_local_time,
+       &dev_attr_utc_offset,
        NULL
 };
 
-static int __init etr_register_port(struct sys_device *dev)
+static int __init etr_register_port(struct device *dev)
 {
-       struct sysdev_attribute **attr;
+       struct device_attribute **attr;
        int rc;
 
-       rc = sysdev_register(dev);
+       rc = device_register(dev);
        if (rc)
                goto out;
        for (attr = etr_port_attributes; *attr; attr++) {
-               rc = sysdev_create_file(dev, *attr);
+               rc = device_create_file(dev, *attr);
                if (rc)
                        goto out_unreg;
        }
        return 0;
 out_unreg:
        for (; attr >= etr_port_attributes; attr--)
-               sysdev_remove_file(dev, *attr);
-       sysdev_unregister(dev);
+               device_remove_file(dev, *attr);
+       device_unregister(dev);
 out:
        return rc;
 }
 
-static void __init etr_unregister_port(struct sys_device *dev)
+static void __init etr_unregister_port(struct device *dev)
 {
-       struct sysdev_attribute **attr;
+       struct device_attribute **attr;
 
        for (attr = etr_port_attributes; *attr; attr++)
-               sysdev_remove_file(dev, *attr);
-       sysdev_unregister(dev);
+               device_remove_file(dev, *attr);
+       device_unregister(dev);
 }
 
 static int __init etr_init_sysfs(void)
 {
        int rc;
 
-       rc = sysdev_class_register(&etr_sysclass);
+       rc = subsys_system_register(&etr_subsys, NULL);
        if (rc)
                goto out;
-       rc = sysdev_class_create_file(&etr_sysclass, &attr_stepping_port);
+       rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_port);
        if (rc)
-               goto out_unreg_class;
-       rc = sysdev_class_create_file(&etr_sysclass, &attr_stepping_mode);
+               goto out_unreg_subsys;
+       rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
        if (rc)
                goto out_remove_stepping_port;
        rc = etr_register_port(&etr_port0_dev);
@@ -1394,11 +1399,11 @@ static int __init etr_init_sysfs(void)
 out_remove_port0:
        etr_unregister_port(&etr_port0_dev);
 out_remove_stepping_mode:
-       sysdev_class_remove_file(&etr_sysclass, &attr_stepping_mode);
+       device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
 out_remove_stepping_port:
-       sysdev_class_remove_file(&etr_sysclass, &attr_stepping_port);
-out_unreg_class:
-       sysdev_class_unregister(&etr_sysclass);
+       device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_port);
+out_unreg_subsys:
+       bus_unregister(&etr_subsys);
 out:
        return rc;
 }
@@ -1598,14 +1603,15 @@ out_unlock:
 }
 
 /*
- * STP class sysfs interface functions
+ * STP subsys sysfs interface functions
  */
-static struct sysdev_class stp_sysclass = {
-       .name   = "stp",
+static struct bus_type stp_subsys = {
+       .name           = "stp",
+       .dev_name       = "stp",
 };
 
-static ssize_t stp_ctn_id_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_ctn_id_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online)
@@ -1614,10 +1620,10 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class,
                       *(unsigned long long *) stp_info.ctnid);
 }
 
-static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
+static DEVICE_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
 
-static ssize_t stp_ctn_type_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_ctn_type_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online)
@@ -1625,10 +1631,10 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", stp_info.ctn);
 }
 
-static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
+static DEVICE_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
 
-static ssize_t stp_dst_offset_show(struct sysdev_class *class,
-                                  struct sysdev_class_attribute *attr,
+static ssize_t stp_dst_offset_show(struct device *dev,
+                                  struct device_attribute *attr,
                                   char *buf)
 {
        if (!stp_online || !(stp_info.vbits & 0x2000))
@@ -1636,10 +1642,10 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto);
 }
 
-static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
+static DEVICE_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
 
-static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
-                                       struct sysdev_class_attribute *attr,
+static ssize_t stp_leap_seconds_show(struct device *dev,
+                                       struct device_attribute *attr,
                                        char *buf)
 {
        if (!stp_online || !(stp_info.vbits & 0x8000))
@@ -1647,10 +1653,10 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps);
 }
 
-static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
+static DEVICE_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
 
-static ssize_t stp_stratum_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_stratum_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online)
@@ -1658,10 +1664,10 @@ static ssize_t stp_stratum_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum);
 }
 
-static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL);
+static DEVICE_ATTR(stratum, 0400, stp_stratum_show, NULL);
 
-static ssize_t stp_time_offset_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_time_offset_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online || !(stp_info.vbits & 0x0800))
@@ -1669,10 +1675,10 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", (int) stp_info.tto);
 }
 
-static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
+static DEVICE_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
 
-static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_time_zone_offset_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online || !(stp_info.vbits & 0x4000))
@@ -1680,11 +1686,11 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo);
 }
 
-static SYSDEV_CLASS_ATTR(time_zone_offset, 0400,
+static DEVICE_ATTR(time_zone_offset, 0400,
                         stp_time_zone_offset_show, NULL);
 
-static ssize_t stp_timing_mode_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_timing_mode_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online)
@@ -1692,10 +1698,10 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", stp_info.tmd);
 }
 
-static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
+static DEVICE_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
 
-static ssize_t stp_timing_state_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_timing_state_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        if (!stp_online)
@@ -1703,17 +1709,17 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class,
        return sprintf(buf, "%i\n", stp_info.tst);
 }
 
-static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
+static DEVICE_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
 
-static ssize_t stp_online_show(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_online_show(struct device *dev,
+                               struct device_attribute *attr,
                                char *buf)
 {
        return sprintf(buf, "%i\n", stp_online);
 }
 
-static ssize_t stp_online_store(struct sysdev_class *class,
-                               struct sysdev_class_attribute *attr,
+static ssize_t stp_online_store(struct device *dev,
+                               struct device_attribute *attr,
                                const char *buf, size_t count)
 {
        unsigned int value;
@@ -1735,47 +1741,47 @@ static ssize_t stp_online_store(struct sysdev_class *class,
 }
 
 /*
- * Can't use SYSDEV_CLASS_ATTR because the attribute should be named
- * stp/online but attr_online already exists in this file ..
+ * Can't use DEVICE_ATTR because the attribute should be named
+ * stp/online but dev_attr_online already exists in this file ..
  */
-static struct sysdev_class_attribute attr_stp_online = {
+static struct device_attribute dev_attr_stp_online = {
        .attr = { .name = "online", .mode = 0600 },
        .show   = stp_online_show,
        .store  = stp_online_store,
 };
 
-static struct sysdev_class_attribute *stp_attributes[] = {
-       &attr_ctn_id,
-       &attr_ctn_type,
-       &attr_dst_offset,
-       &attr_leap_seconds,
-       &attr_stp_online,
-       &attr_stratum,
-       &attr_time_offset,
-       &attr_time_zone_offset,
-       &attr_timing_mode,
-       &attr_timing_state,
+static struct device_attribute *stp_attributes[] = {
+       &dev_attr_ctn_id,
+       &dev_attr_ctn_type,
+       &dev_attr_dst_offset,
+       &dev_attr_leap_seconds,
+       &dev_attr_stp_online,
+       &dev_attr_stratum,
+       &dev_attr_time_offset,
+       &dev_attr_time_zone_offset,
+       &dev_attr_timing_mode,
+       &dev_attr_timing_state,
        NULL
 };
 
 static int __init stp_init_sysfs(void)
 {
-       struct sysdev_class_attribute **attr;
+       struct device_attribute **attr;
        int rc;
 
-       rc = sysdev_class_register(&stp_sysclass);
+       rc = subsys_system_register(&stp_subsys, NULL);
        if (rc)
                goto out;
        for (attr = stp_attributes; *attr; attr++) {
-               rc = sysdev_class_create_file(&stp_sysclass, *attr);
+               rc = device_create_file(stp_subsys.dev_root, *attr);
                if (rc)
                        goto out_unreg;
        }
        return 0;
 out_unreg:
        for (; attr >= stp_attributes; attr--)
-               sysdev_class_remove_file(&stp_sysclass, *attr);
-       sysdev_class_unregister(&stp_sysclass);
+               device_remove_file(stp_subsys.dev_root, *attr);
+       bus_unregister(&stp_subsys);
 out:
        return rc;
 }