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

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
...@@ -320,7 +320,7 @@ struct cio_iplinfo { ...@@ -320,7 +320,7 @@ struct cio_iplinfo {
extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo); extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo);
/* Function from drivers/s390/cio/chsc.c */ /* 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); int chsc_sstpi(void *page, void *result, size_t size);
#endif #endif
...@@ -1455,7 +1455,7 @@ static void __init stp_reset(void) ...@@ -1455,7 +1455,7 @@ static void __init stp_reset(void)
int rc; int rc;
stp_page = (void *) get_zeroed_page(GFP_ATOMIC); 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) if (rc == 0)
set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags); set_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags);
else if (stp_online) { else if (stp_online) {
...@@ -1554,11 +1554,10 @@ static int stp_sync_clock(void *data) ...@@ -1554,11 +1554,10 @@ static int stp_sync_clock(void *data)
stp_info.todoff[2] || stp_info.todoff[3] || stp_info.todoff[2] || stp_info.todoff[3] ||
stp_info.tmd != 2) { stp_info.tmd != 2) {
old_clock = get_tod_clock(); 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) { if (rc == 0) {
new_clock = get_tod_clock(); new_clock = old_clock + clock_delta;
delta = adjust_time(old_clock, new_clock, 0); delta = adjust_time(old_clock, new_clock, 0);
clock_delta = new_clock - old_clock;
atomic_notifier_call_chain(&s390_epoch_delta_notifier, atomic_notifier_call_chain(&s390_epoch_delta_notifier,
0, &clock_delta); 0, &clock_delta);
fixup_clock_comparator(delta); fixup_clock_comparator(delta);
...@@ -1590,12 +1589,12 @@ static void stp_work_fn(struct work_struct *work) ...@@ -1590,12 +1589,12 @@ static void stp_work_fn(struct work_struct *work)
mutex_lock(&stp_work_mutex); mutex_lock(&stp_work_mutex);
if (!stp_online) { 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); del_timer_sync(&stp_timer);
goto out_unlock; goto out_unlock;
} }
rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0); rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0, NULL);
if (rc) if (rc)
goto out_unlock; goto out_unlock;
......
...@@ -1176,7 +1176,7 @@ chsc_determine_css_characteristics(void) ...@@ -1176,7 +1176,7 @@ chsc_determine_css_characteristics(void)
EXPORT_SYMBOL_GPL(css_general_characteristics); EXPORT_SYMBOL_GPL(css_general_characteristics);
EXPORT_SYMBOL_GPL(css_chsc_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 {
struct chsc_header request; struct chsc_header request;
...@@ -1186,7 +1186,9 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl) ...@@ -1186,7 +1186,9 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl)
unsigned int ctrl : 16; unsigned int ctrl : 16;
unsigned int rsvd2[5]; unsigned int rsvd2[5];
struct chsc_header response; struct chsc_header response;
unsigned int rsvd3[7]; unsigned int rsvd3[3];
u64 clock_delta;
unsigned int rsvd4[2];
} __attribute__ ((packed)) *rr; } __attribute__ ((packed)) *rr;
int rc; int rc;
...@@ -1200,6 +1202,8 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl) ...@@ -1200,6 +1202,8 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl)
if (rc) if (rc)
return -EIO; return -EIO;
rc = (rr->response.code == 0x0001) ? 0 : -EIO; rc = (rr->response.code == 0x0001) ? 0 : -EIO;
if (clock_delta)
*clock_delta = rr->clock_delta;
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment