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: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
4e042af463
commit
2f82f57763
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1176,7 +1176,7 @@ exit:
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user