// 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 __bootdata_preserved(tod_clock_base);
EXPORT_SYMBOL_GPL(tod_clock_base);

u64 __bootdata_preserved(clock_comparator_max);
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;

	/* Initialize TOD steering parameters */
	tod_steering_end = tod_clock_base.tod;
	vdso_k_time_data->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;

	/* 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);
	vdso_k_time_data->arch_data.tod_steering_end = tod_steering_end;
	vdso_k_time_data->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);
		timer_delete_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);
