// SPDX-License-Identifier: GPL-2.0
/*
 *    Time of day based timer functions.
 *
 *  S390 version
 *    Copyright IBM Corp. 1999, 2008
 *    Author(s): Hartmut Penner (hp@de.ibm.com),
 *               Martin Schwidefsky (schwidefsky@de.ibm.com),
 *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
 *
 *  Derived from "arch/i386/kernel/time.c"
 *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
 */

#define KMSG_COMPONENT "time"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/sched/clock.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/cpu.h>
#include <linux/stop_machine.h>
#include <linux/time.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/types.h>
#include <linux/profile.h>
#include <linux/timex.h>
#include <linux/notifier.h>
#include <linux/clockchips.h>
#include <linux/gfp.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <vdso/vsyscall.h>
#include <vdso/clocksource.h>
#include <vdso/helpers.h>
#include <asm/facility.h>
#include <asm/delay.h>
#include <asm/div64.h>
#include <asm/vdso.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/vtimer.h>
#include <asm/stp.h>
#include <asm/cio.h>
#include "entry.h"

union tod_clock tod_clock_base __section(".data");
EXPORT_SYMBOL_GPL(tod_clock_base);

u64 clock_comparator_max = -1ULL;
EXPORT_SYMBOL_GPL(clock_comparator_max);

static DEFINE_PER_CPU(struct clock_event_device, comparators);

ATOMIC_NOTIFIER_HEAD(s390_epoch_delta_notifier);
EXPORT_SYMBOL(s390_epoch_delta_notifier);

unsigned char ptff_function_mask[16];

static unsigned long lpar_offset;
static unsigned long initial_leap_seconds;
static unsigned long tod_steering_end;
static long tod_steering_delta;

/*
 * Get time offsets with PTFF
 */
void __init time_early_init(void)
{
	struct ptff_qto qto;
	struct ptff_qui qui;
	int cs;

	/* Initialize TOD steering parameters */
	tod_steering_end = tod_clock_base.tod;
	for (cs = 0; cs < CS_BASES; cs++)
		vdso_data[cs].arch_data.tod_steering_end = tod_steering_end;

	if (!test_facility(28))
		return;

	ptff(&ptff_function_mask, sizeof(ptff_function_mask), PTFF_QAF);

	/* get LPAR offset */
	if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0)
		lpar_offset = qto.tod_epoch_difference;

	/* get initial leap seconds */
	if (ptff_query(PTFF_QUI) && ptff(&qui, sizeof(qui), PTFF_QUI) == 0)
		initial_leap_seconds = (unsigned long)
			((long) qui.old_leap * 4096000000L);
}

unsigned long long noinstr sched_clock_noinstr(void)
{
	return tod_to_ns(__get_tod_clock_monotonic());
}

/*
 * Scheduler clock - returns current time in nanosec units.
 */
unsigned long long notrace sched_clock(void)
{
	return tod_to_ns(get_tod_clock_monotonic());
}
NOKPROBE_SYMBOL(sched_clock);

static void ext_to_timespec64(union tod_clock *clk, struct timespec64 *xt)
{
	unsigned long rem, sec, nsec;

	sec = clk->us;
	rem = do_div(sec, 1000000);
	nsec = ((clk->sus + (rem << 12)) * 125) >> 9;
	xt->tv_sec = sec;
	xt->tv_nsec = nsec;
}

void clock_comparator_work(void)
{
	struct clock_event_device *cd;

	get_lowcore()->clock_comparator = clock_comparator_max;
	cd = this_cpu_ptr(&comparators);
	cd->event_handler(cd);
}

static int s390_next_event(unsigned long delta,
			   struct clock_event_device *evt)
{
	get_lowcore()->clock_comparator = get_tod_clock() + delta;
	set_clock_comparator(get_lowcore()->clock_comparator);
	return 0;
}

/*
 * Set up lowcore and control register of the current cpu to
 * enable TOD clock and clock comparator interrupts.
 */
void init_cpu_timer(void)
{
	struct clock_event_device *cd;
	int cpu;

	get_lowcore()->clock_comparator = clock_comparator_max;
	set_clock_comparator(get_lowcore()->clock_comparator);

	cpu = smp_processor_id();
	cd = &per_cpu(comparators, cpu);
	cd->name		= "comparator";
	cd->features		= CLOCK_EVT_FEAT_ONESHOT;
	cd->mult		= 16777;
	cd->shift		= 12;
	cd->min_delta_ns	= 1;
	cd->min_delta_ticks	= 1;
	cd->max_delta_ns	= LONG_MAX;
	cd->max_delta_ticks	= ULONG_MAX;
	cd->rating		= 400;
	cd->cpumask		= cpumask_of(cpu);
	cd->set_next_event	= s390_next_event;

	clockevents_register_device(cd);

	/* Enable clock comparator timer interrupt. */
	local_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SUBMASK_BIT);

	/* Always allow the timing alert external interrupt. */
	local_ctl_set_bit(0, CR0_ETR_SUBMASK_BIT);
}

static void clock_comparator_interrupt(struct ext_code ext_code,
				       unsigned int param32,
				       unsigned long param64)
{
	inc_irq_stat(IRQEXT_CLK);
	if (get_lowcore()->clock_comparator == clock_comparator_max)
		set_clock_comparator(get_lowcore()->clock_comparator);
}

static void stp_timing_alert(struct stp_irq_parm *);

static void timing_alert_interrupt(struct ext_code ext_code,
				   unsigned int param32, unsigned long param64)
{
	inc_irq_stat(IRQEXT_TLA);
	if (param32 & 0x00038000)
		stp_timing_alert((struct stp_irq_parm *) &param32);
}

static void stp_reset(void);

void read_persistent_clock64(struct timespec64 *ts)
{
	union tod_clock clk;
	u64 delta;

	delta = initial_leap_seconds + TOD_UNIX_EPOCH;
	store_tod_clock_ext(&clk);
	clk.eitod -= delta;
	ext_to_timespec64(&clk, ts);
}

void __init read_persistent_wall_and_boot_offset(struct timespec64 *wall_time,
						 struct timespec64 *boot_offset)
{
	struct timespec64 boot_time;
	union tod_clock clk;
	u64 delta;

	delta = initial_leap_seconds + TOD_UNIX_EPOCH;
	clk = tod_clock_base;
	clk.eitod -= delta;
	ext_to_timespec64(&clk, &boot_time);

	read_persistent_clock64(wall_time);
	*boot_offset = timespec64_sub(*wall_time, boot_time);
}

static u64 read_tod_clock(struct clocksource *cs)
{
	unsigned long now, adj;

	preempt_disable(); /* protect from changes to steering parameters */
	now = get_tod_clock();
	adj = tod_steering_end - now;
	if (unlikely((s64) adj > 0))
		/*
		 * manually steer by 1 cycle every 2^16 cycles. This
		 * corresponds to shifting the tod delta by 15. 1s is
		 * therefore steered in ~9h. The adjust will decrease
		 * over time, until it finally reaches 0.
		 */
		now += (tod_steering_delta < 0) ? (adj >> 15) : -(adj >> 15);
	preempt_enable();
	return now;
}

static struct clocksource clocksource_tod = {
	.name		= "tod",
	.rating		= 400,
	.read		= read_tod_clock,
	.mask		= CLOCKSOURCE_MASK(64),
	.mult		= 4096000,
	.shift		= 24,
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
	.vdso_clock_mode = VDSO_CLOCKMODE_TOD,
	.id		= CSID_S390_TOD,
};

struct clocksource * __init clocksource_default_clock(void)
{
	return &clocksource_tod;
}

/*
 * Initialize the TOD clock and the CPU timer of
 * the boot cpu.
 */
void __init time_init(void)
{
	/* Reset time synchronization interfaces. */
	stp_reset();

	/* request the clock comparator external interrupt */
	if (register_external_irq(EXT_IRQ_CLK_COMP, clock_comparator_interrupt))
		panic("Couldn't request external interrupt 0x1004");

	/* request the timing alert external interrupt */
	if (register_external_irq(EXT_IRQ_TIMING_ALERT, timing_alert_interrupt))
		panic("Couldn't request external interrupt 0x1406");

	if (__clocksource_register(&clocksource_tod) != 0)
		panic("Could not register TOD clock source");

	/* Enable TOD clock interrupts on the boot cpu. */
	init_cpu_timer();

	/* Enable cpu timer interrupts on the boot cpu. */
	vtime_init();
}

static DEFINE_PER_CPU(atomic_t, clock_sync_word);
static DEFINE_MUTEX(stp_mutex);
static unsigned long clock_sync_flags;

#define CLOCK_SYNC_HAS_STP		0
#define CLOCK_SYNC_STP			1
#define CLOCK_SYNC_STPINFO_VALID	2

/*
 * The get_clock function for the physical clock. It will get the current
 * TOD clock, subtract the LPAR offset and write the result to *clock.
 * The function returns 0 if the clock is in sync with the external time
 * source. If the clock mode is local it will return -EOPNOTSUPP and
 * -EAGAIN if the clock is not in sync with the external reference.
 */
int get_phys_clock(unsigned long *clock)
{
	atomic_t *sw_ptr;
	unsigned int sw0, sw1;

	sw_ptr = &get_cpu_var(clock_sync_word);
	sw0 = atomic_read(sw_ptr);
	*clock = get_tod_clock() - lpar_offset;
	sw1 = atomic_read(sw_ptr);
	put_cpu_var(clock_sync_word);
	if (sw0 == sw1 && (sw0 & 0x80000000U))
		/* Success: time is in sync. */
		return 0;
	if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
		return -EOPNOTSUPP;
	if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
		return -EACCES;
	return -EAGAIN;
}
EXPORT_SYMBOL(get_phys_clock);

/*
 * Make get_phys_clock() return -EAGAIN.
 */
static void disable_sync_clock(void *dummy)
{
	atomic_t *sw_ptr = this_cpu_ptr(&clock_sync_word);
	/*
	 * Clear the in-sync bit 2^31. All get_phys_clock calls will
	 * fail until the sync bit is turned back on. In addition
	 * increase the "sequence" counter to avoid the race of an
	 * stp event and the complete recovery against get_phys_clock.
	 */
	atomic_andnot(0x80000000, sw_ptr);
	atomic_inc(sw_ptr);
}

/*
 * Make get_phys_clock() return 0 again.
 * Needs to be called from a context disabled for preemption.
 */
static void enable_sync_clock(void)
{
	atomic_t *sw_ptr = this_cpu_ptr(&clock_sync_word);
	atomic_or(0x80000000, sw_ptr);
}

/*
 * Function to check if the clock is in sync.
 */
static inline int check_sync_clock(void)
{
	atomic_t *sw_ptr;
	int rc;

	sw_ptr = &get_cpu_var(clock_sync_word);
	rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
	put_cpu_var(clock_sync_word);
	return rc;
}

/*
 * Apply clock delta to the global data structures.
 * This is called once on the CPU that performed the clock sync.
 */
static void clock_sync_global(long delta)
{
	unsigned long now, adj;
	struct ptff_qto qto;
	int cs;

	/* Fixup the monotonic sched clock. */
	tod_clock_base.eitod += delta;
	/* Adjust TOD steering parameters. */
	now = get_tod_clock();
	adj = tod_steering_end - now;
	if (unlikely((s64) adj >= 0))
		/* Calculate how much of the old adjustment is left. */
		tod_steering_delta = (tod_steering_delta < 0) ?
			-(adj >> 15) : (adj >> 15);
	tod_steering_delta += delta;
	if ((abs(tod_steering_delta) >> 48) != 0)
		panic("TOD clock sync offset %li is too large to drift\n",
		      tod_steering_delta);
	tod_steering_end = now + (abs(tod_steering_delta) << 15);
	for (cs = 0; cs < CS_BASES; cs++) {
		vdso_data[cs].arch_data.tod_steering_end = tod_steering_end;
		vdso_data[cs].arch_data.tod_steering_delta = tod_steering_delta;
	}

	/* Update LPAR offset. */
	if (ptff_query(PTFF_QTO) && ptff(&qto, sizeof(qto), PTFF_QTO) == 0)
		lpar_offset = qto.tod_epoch_difference;
	/* Call the TOD clock change notifier. */
	atomic_notifier_call_chain(&s390_epoch_delta_notifier, 0, &delta);
}

/*
 * Apply clock delta to the per-CPU data structures of this CPU.
 * This is called for each online CPU after the call to clock_sync_global.
 */
static void clock_sync_local(long delta)
{
	/* Add the delta to the clock comparator. */
	if (get_lowcore()->clock_comparator != clock_comparator_max) {
		get_lowcore()->clock_comparator += delta;
		set_clock_comparator(get_lowcore()->clock_comparator);
	}
	/* Adjust the last_update_clock time-stamp. */
	get_lowcore()->last_update_clock += delta;
}

/* Single threaded workqueue used for stp sync events */
static struct workqueue_struct *time_sync_wq;

static void __init time_init_wq(void)
{
	if (time_sync_wq)
		return;
	time_sync_wq = create_singlethread_workqueue("timesync");
}

struct clock_sync_data {
	atomic_t cpus;
	int in_sync;
	long clock_delta;
};

/*
 * Server Time Protocol (STP) code.
 */
static bool stp_online;
static struct stp_sstpi stp_info;
static void *stp_page;

static void stp_work_fn(struct work_struct *work);
static DECLARE_WORK(stp_work, stp_work_fn);
static struct timer_list stp_timer;

static int __init early_parse_stp(char *p)
{
	return kstrtobool(p, &stp_online);
}
early_param("stp", early_parse_stp);

/*
 * Reset STP attachment.
 */
static void __init stp_reset(void)
{
	int rc;

	stp_page = (void *) get_zeroed_page(GFP_ATOMIC);
	rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000, NULL);
	if (rc == 0)
		set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags);
	else if (stp_online) {
		pr_warn("The real or virtual hardware system does not provide an STP interface\n");
		free_page((unsigned long) stp_page);
		stp_page = NULL;
		stp_online = false;
	}
}

bool stp_enabled(void)
{
	return test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags) && stp_online;
}
EXPORT_SYMBOL(stp_enabled);

static void stp_timeout(struct timer_list *unused)
{
	queue_work(time_sync_wq, &stp_work);
}

static int __init stp_init(void)
{
	if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
		return 0;
	timer_setup(&stp_timer, stp_timeout, 0);
	time_init_wq();
	if (!stp_online)
		return 0;
	queue_work(time_sync_wq, &stp_work);
	return 0;
}

arch_initcall(stp_init);

/*
 * STP timing alert. There are three causes:
 * 1) timing status change
 * 2) link availability change
 * 3) time control parameter change
 * In all three cases we are only interested in the clock source state.
 * If a STP clock source is now available use it.
 */
static void stp_timing_alert(struct stp_irq_parm *intparm)
{
	if (intparm->tsc || intparm->lac || intparm->tcpc)
		queue_work(time_sync_wq, &stp_work);
}

/*
 * STP sync check machine check. This is called when the timing state
 * changes from the synchronized state to the unsynchronized state.
 * After a STP sync check the clock is not in sync. The machine check
 * is broadcasted to all cpus at the same time.
 */
int stp_sync_check(void)
{
	disable_sync_clock(NULL);
	return 1;
}

/*
 * STP island condition machine check. This is called when an attached
 * server  attempts to communicate over an STP link and the servers
 * have matching CTN ids and have a valid stratum-1 configuration
 * but the configurations do not match.
 */
int stp_island_check(void)
{
	disable_sync_clock(NULL);
	return 1;
}

void stp_queue_work(void)
{
	queue_work(time_sync_wq, &stp_work);
}

static int __store_stpinfo(void)
{
	int rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi));

	if (rc)
		clear_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags);
	else
		set_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags);
	return rc;
}

static int stpinfo_valid(void)
{
	return stp_online && test_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags);
}

static int stp_sync_clock(void *data)
{
	struct clock_sync_data *sync = data;
	long clock_delta, flags;
	static int first;
	int rc;

	enable_sync_clock();
	if (xchg(&first, 1) == 0) {
		/* Wait until all other cpus entered the sync function. */
		while (atomic_read(&sync->cpus) != 0)
			cpu_relax();
		rc = 0;
		if (stp_info.todoff || stp_info.tmd != 2) {
			flags = vdso_update_begin();
			rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0,
					&clock_delta);
			if (rc == 0) {
				sync->clock_delta = clock_delta;
				clock_sync_global(clock_delta);
				rc = __store_stpinfo();
				if (rc == 0 && stp_info.tmd != 2)
					rc = -EAGAIN;
			}
			vdso_update_end(flags);
		}
		sync->in_sync = rc ? -EAGAIN : 1;
		xchg(&first, 0);
	} else {
		/* Slave */
		atomic_dec(&sync->cpus);
		/* Wait for in_sync to be set. */
		while (READ_ONCE(sync->in_sync) == 0)
			__udelay(1);
	}
	if (sync->in_sync != 1)
		/* Didn't work. Clear per-cpu in sync bit again. */
		disable_sync_clock(NULL);
	/* Apply clock delta to per-CPU fields of this CPU. */
	clock_sync_local(sync->clock_delta);

	return 0;
}

static int stp_clear_leap(void)
{
	struct __kernel_timex txc;
	int ret;

	memset(&txc, 0, sizeof(txc));

	ret = do_adjtimex(&txc);
	if (ret < 0)
		return ret;

	txc.modes = ADJ_STATUS;
	txc.status &= ~(STA_INS|STA_DEL);
	return do_adjtimex(&txc);
}

static void stp_check_leap(void)
{
	struct stp_stzi stzi;
	struct stp_lsoib *lsoib = &stzi.lsoib;
	struct __kernel_timex txc;
	int64_t timediff;
	int leapdiff, ret;

	if (!stp_info.lu || !check_sync_clock()) {
		/*
		 * Either a scheduled leap second was removed by the operator,
		 * or STP is out of sync. In both cases, clear the leap second
		 * kernel flags.
		 */
		if (stp_clear_leap() < 0)
			pr_err("failed to clear leap second flags\n");
		return;
	}

	if (chsc_stzi(stp_page, &stzi, sizeof(stzi))) {
		pr_err("stzi failed\n");
		return;
	}

	timediff = tod_to_ns(lsoib->nlsout - get_tod_clock()) / NSEC_PER_SEC;
	leapdiff = lsoib->nlso - lsoib->also;

	if (leapdiff != 1 && leapdiff != -1) {
		pr_err("Cannot schedule %d leap seconds\n", leapdiff);
		return;
	}

	if (timediff < 0) {
		if (stp_clear_leap() < 0)
			pr_err("failed to clear leap second flags\n");
	} else if (timediff < 7200) {
		memset(&txc, 0, sizeof(txc));
		ret = do_adjtimex(&txc);
		if (ret < 0)
			return;

		txc.modes = ADJ_STATUS;
		if (leapdiff > 0)
			txc.status |= STA_INS;
		else
			txc.status |= STA_DEL;
		ret = do_adjtimex(&txc);
		if (ret < 0)
			pr_err("failed to set leap second flags\n");
		/* arm Timer to clear leap second flags */
		mod_timer(&stp_timer, jiffies + secs_to_jiffies(14400));
	} else {
		/* The day the leap second is scheduled for hasn't been reached. Retry
		 * in one hour.
		 */
		mod_timer(&stp_timer, jiffies + secs_to_jiffies(3600));
	}
}

/*
 * STP work. Check for the STP state and take over the clock
 * synchronization if the STP clock source is usable.
 */
static void stp_work_fn(struct work_struct *work)
{
	struct clock_sync_data stp_sync;
	int rc;

	/* prevent multiple execution. */
	mutex_lock(&stp_mutex);

	if (!stp_online) {
		chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000, NULL);
		del_timer_sync(&stp_timer);
		goto out_unlock;
	}

	rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xf0e0, NULL);
	if (rc)
		goto out_unlock;

	rc = __store_stpinfo();
	if (rc || stp_info.c == 0)
		goto out_unlock;

	/* Skip synchronization if the clock is already in sync. */
	if (!check_sync_clock()) {
		memset(&stp_sync, 0, sizeof(stp_sync));
		cpus_read_lock();
		atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
		stop_machine_cpuslocked(stp_sync_clock, &stp_sync, cpu_online_mask);
		cpus_read_unlock();
	}

	if (!check_sync_clock())
		/*
		 * There is a usable clock but the synchronization failed.
		 * Retry after a second.
		 */
		mod_timer(&stp_timer, jiffies + msecs_to_jiffies(MSEC_PER_SEC));
	else if (stp_info.lu)
		stp_check_leap();

out_unlock:
	mutex_unlock(&stp_mutex);
}

/*
 * STP subsys sysfs interface functions
 */
static const struct bus_type stp_subsys = {
	.name		= "stp",
	.dev_name	= "stp",
};

static ssize_t ctn_id_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid())
		ret = sysfs_emit(buf, "%016lx\n",
				 *(unsigned long *)stp_info.ctnid);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(ctn_id);

static ssize_t ctn_type_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid())
		ret = sysfs_emit(buf, "%i\n", stp_info.ctn);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(ctn_type);

static ssize_t dst_offset_show(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid() && (stp_info.vbits & 0x2000))
		ret = sysfs_emit(buf, "%i\n", (int)(s16)stp_info.dsto);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(dst_offset);

static ssize_t leap_seconds_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid() && (stp_info.vbits & 0x8000))
		ret = sysfs_emit(buf, "%i\n", (int)(s16)stp_info.leaps);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(leap_seconds);

static ssize_t leap_seconds_scheduled_show(struct device *dev,
						struct device_attribute *attr,
						char *buf)
{
	struct stp_stzi stzi;
	ssize_t ret;

	mutex_lock(&stp_mutex);
	if (!stpinfo_valid() || !(stp_info.vbits & 0x8000) || !stp_info.lu) {
		mutex_unlock(&stp_mutex);
		return -ENODATA;
	}

	ret = chsc_stzi(stp_page, &stzi, sizeof(stzi));
	mutex_unlock(&stp_mutex);
	if (ret < 0)
		return ret;

	if (!stzi.lsoib.p)
		return sysfs_emit(buf, "0,0\n");

	return sysfs_emit(buf, "%lu,%d\n",
			  tod_to_ns(stzi.lsoib.nlsout - TOD_UNIX_EPOCH) / NSEC_PER_SEC,
			  stzi.lsoib.nlso - stzi.lsoib.also);
}

static DEVICE_ATTR_RO(leap_seconds_scheduled);

static ssize_t stratum_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid())
		ret = sysfs_emit(buf, "%i\n", (int)(s16)stp_info.stratum);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(stratum);

static ssize_t time_offset_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid() && (stp_info.vbits & 0x0800))
		ret = sysfs_emit(buf, "%i\n", (int)stp_info.tto);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(time_offset);

static ssize_t time_zone_offset_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid() && (stp_info.vbits & 0x4000))
		ret = sysfs_emit(buf, "%i\n", (int)(s16)stp_info.tzo);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(time_zone_offset);

static ssize_t timing_mode_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid())
		ret = sysfs_emit(buf, "%i\n", stp_info.tmd);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(timing_mode);

static ssize_t timing_state_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	ssize_t ret = -ENODATA;

	mutex_lock(&stp_mutex);
	if (stpinfo_valid())
		ret = sysfs_emit(buf, "%i\n", stp_info.tst);
	mutex_unlock(&stp_mutex);
	return ret;
}

static DEVICE_ATTR_RO(timing_state);

static ssize_t online_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sysfs_emit(buf, "%i\n", stp_online);
}

static ssize_t online_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	unsigned int value;

	value = simple_strtoul(buf, NULL, 0);
	if (value != 0 && value != 1)
		return -EINVAL;
	if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
		return -EOPNOTSUPP;
	mutex_lock(&stp_mutex);
	stp_online = value;
	if (stp_online)
		set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
	else
		clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
	queue_work(time_sync_wq, &stp_work);
	mutex_unlock(&stp_mutex);
	return count;
}

/*
 * Can't use DEVICE_ATTR because the attribute should be named
 * stp/online but dev_attr_online already exists in this file ..
 */
static DEVICE_ATTR_RW(online);

static struct attribute *stp_dev_attrs[] = {
	&dev_attr_ctn_id.attr,
	&dev_attr_ctn_type.attr,
	&dev_attr_dst_offset.attr,
	&dev_attr_leap_seconds.attr,
	&dev_attr_online.attr,
	&dev_attr_leap_seconds_scheduled.attr,
	&dev_attr_stratum.attr,
	&dev_attr_time_offset.attr,
	&dev_attr_time_zone_offset.attr,
	&dev_attr_timing_mode.attr,
	&dev_attr_timing_state.attr,
	NULL
};
ATTRIBUTE_GROUPS(stp_dev);

static int __init stp_init_sysfs(void)
{
	return subsys_system_register(&stp_subsys, stp_dev_groups);
}

device_initcall(stp_init_sysfs);
