Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f82f577 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390/time: STP sync clock correction



The sync clock operation of the channel subsystem call for STP delivers
the TOD clock difference as a result. Use this TOD clock difference
instead of the difference between the TOD timestamps before and after
the sync clock operation.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 4e042af4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -320,7 +320,7 @@ struct cio_iplinfo {
extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo);

/* Function from drivers/s390/cio/chsc.c */
int chsc_sstpc(void *page, unsigned int op, u16 ctrl);
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
int chsc_sstpi(void *page, void *result, size_t size);

#endif
+5 −6
Original line number Diff line number Diff line
@@ -1455,7 +1455,7 @@ 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);
	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) {
@@ -1554,11 +1554,10 @@ static int stp_sync_clock(void *data)
	    stp_info.todoff[2] || stp_info.todoff[3] ||
	    stp_info.tmd != 2) {
		old_clock = get_tod_clock();
		rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0);
		rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0, &clock_delta);
		if (rc == 0) {
			new_clock = get_tod_clock();
			new_clock = old_clock + clock_delta;
			delta = adjust_time(old_clock, new_clock, 0);
			clock_delta = new_clock - old_clock;
			atomic_notifier_call_chain(&s390_epoch_delta_notifier,
						   0, &clock_delta);
			fixup_clock_comparator(delta);
@@ -1590,12 +1589,12 @@ static void stp_work_fn(struct work_struct *work)
	mutex_lock(&stp_work_mutex);

	if (!stp_online) {
		chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000);
		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, 0xb0e0);
	rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0, NULL);
	if (rc)
		goto out_unlock;

+6 −2
Original line number Diff line number Diff line
@@ -1176,7 +1176,7 @@ chsc_determine_css_characteristics(void)
EXPORT_SYMBOL_GPL(css_general_characteristics);
EXPORT_SYMBOL_GPL(css_chsc_characteristics);

int chsc_sstpc(void *page, unsigned int op, u16 ctrl)
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta)
{
	struct {
		struct chsc_header request;
@@ -1186,7 +1186,9 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl)
		unsigned int ctrl : 16;
		unsigned int rsvd2[5];
		struct chsc_header response;
		unsigned int rsvd3[7];
		unsigned int rsvd3[3];
		u64 clock_delta;
		unsigned int rsvd4[2];
	} __attribute__ ((packed)) *rr;
	int rc;

@@ -1200,6 +1202,8 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl)
	if (rc)
		return -EIO;
	rc = (rr->response.code == 0x0001) ? 0 : -EIO;
	if (clock_delta)
		*clock_delta = rr->clock_delta;
	return rc;
}