Commit e2091ede authored by Aurelio Colosimo's avatar Aurelio Colosimo

Split timex adjust functions in adjust_offset and adjust_freq operations

This fixes the correct behaviour of ppsi in arch-wrpc, where adjust_freq
is not available.
Still some more fixes may be needed in servo.c. I'm not sure about the
parameter -adj to be passed both in adjust_freq and adjust_offset case.
Anyway, this has been tested on two SPECs and reaches synchronization.
Signed-off-by: Aurelio Colosimo's avatarAurelio Colosimo <aurelio@aureliocolosimo.it>
parent feb5ed39
...@@ -47,13 +47,17 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm) ...@@ -47,13 +47,17 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm)
struct timex t; struct timex t;
int ret; int ret;
if (freq_ppm > PP_ADJ_FREQ_MAX) t.modes = 0;
freq_ppm = PP_ADJ_FREQ_MAX;
if (freq_ppm < -PP_ADJ_FREQ_MAX)
freq_ppm = -PP_ADJ_FREQ_MAX;
t.freq = freq_ppm * ((1 << 16) / 1000); if (freq_ppm) {
t.modes = MOD_FREQUENCY; if (freq_ppm > PP_ADJ_FREQ_MAX)
freq_ppm = PP_ADJ_FREQ_MAX;
if (freq_ppm < -PP_ADJ_FREQ_MAX)
freq_ppm = -PP_ADJ_FREQ_MAX;
t.freq = freq_ppm * ((1 << 16) / 1000);
t.modes = MOD_FREQUENCY;
}
if (offset_ns) { if (offset_ns) {
t.offset = offset_ns / 1000; t.offset = offset_ns / 1000;
...@@ -65,6 +69,16 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm) ...@@ -65,6 +69,16 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm)
return ret; return ret;
} }
int posix_time_adjust_offset(struct pp_instance *ppi, long offset_ns)
{
return posix_time_adjust(ppi, offset_ns, 0);
}
int posix_time_adjust_freq(struct pp_instance *ppi, long freq_ppm)
{
return posix_time_adjust(ppi, 0, freq_ppm);
}
static unsigned long posix_calc_timeout(struct pp_instance *ppi, int millisec) static unsigned long posix_calc_timeout(struct pp_instance *ppi, int millisec)
{ {
struct timespec now; struct timespec now;
...@@ -84,5 +98,7 @@ struct pp_time_operations posix_time_ops = { ...@@ -84,5 +98,7 @@ struct pp_time_operations posix_time_ops = {
.get = posix_time_get, .get = posix_time_get,
.set = posix_time_set, .set = posix_time_set,
.adjust = posix_time_adjust, .adjust = posix_time_adjust,
.adjust_offset = posix_time_adjust_offset,
.adjust_freq = posix_time_adjust_freq,
.calc_timeout = posix_calc_timeout, .calc_timeout = posix_calc_timeout,
}; };
...@@ -36,16 +36,24 @@ static int wrpc_time_set(struct pp_instance *ppi, TimeInternal *t) ...@@ -36,16 +36,24 @@ static int wrpc_time_set(struct pp_instance *ppi, TimeInternal *t)
return 0; return 0;
} }
static int wrpc_time_adjust(struct pp_instance *ppi, long offset_ns, static int wrpc_time_adjust_offset(struct pp_instance *ppi, long offset_ns)
long freq_ppm)
{ {
pp_diag(ppi, time, 1, "%s: %li %li\n", pp_diag(ppi, time, 1, "%s: %li\n",
__func__, offset_ns, freq_ppm); __func__, offset_ns);
if (offset_ns) if (offset_ns)
shw_pps_gen_adjust(PPSG_ADJUST_NSEC, offset_ns); shw_pps_gen_adjust(PPSG_ADJUST_NSEC, offset_ns);
return 0; return 0;
} }
static int wrpc_time_adjust(struct pp_instance *ppi, long offset_ns,
long freq_ppm)
{
if (freq_ppm != 0)
pp_diag(ppi, time, 1, "Warning: %s: can not adjust freq_ppm %li\n",
__func__, freq_ppm);
return wrpc_time_adjust_offset(ppi, offset_ns);
}
static unsigned long wrpc_calc_timeout(struct pp_instance *ppi, int millisec) static unsigned long wrpc_calc_timeout(struct pp_instance *ppi, int millisec)
{ {
unsigned long now_ms = timer_get_tics(); unsigned long now_ms = timer_get_tics();
...@@ -58,5 +66,7 @@ struct pp_time_operations wrpc_time_ops = { ...@@ -58,5 +66,7 @@ struct pp_time_operations wrpc_time_ops = {
.get = wrpc_time_get, .get = wrpc_time_get,
.set = wrpc_time_set, .set = wrpc_time_set,
.adjust = wrpc_time_adjust, .adjust = wrpc_time_adjust,
.adjust_offset = wrpc_time_adjust_offset,
.adjust_freq = NULL,
.calc_timeout = wrpc_calc_timeout, .calc_timeout = wrpc_calc_timeout,
}; };
...@@ -153,6 +153,8 @@ struct pp_time_operations { ...@@ -153,6 +153,8 @@ struct pp_time_operations {
int (*set)(struct pp_instance *ppi, TimeInternal *t); int (*set)(struct pp_instance *ppi, TimeInternal *t);
/* freq_ppm is "scaled-ppm" like the argument of adjtimex(2) */ /* freq_ppm is "scaled-ppm" like the argument of adjtimex(2) */
int (*adjust)(struct pp_instance *ppi, long offset_ns, long freq_ppm); int (*adjust)(struct pp_instance *ppi, long offset_ns, long freq_ppm);
int (*adjust_offset)(struct pp_instance *ppi, long offset_ns);
int (*adjust_freq)(struct pp_instance *ppi, long freq_ppm);
/* calc_timeout cannot return zero */ /* calc_timeout cannot return zero */
unsigned long (*calc_timeout)(struct pp_instance *ppi, int millisec); unsigned long (*calc_timeout)(struct pp_instance *ppi, int millisec);
}; };
......
...@@ -42,6 +42,9 @@ static int bare_time_adjust(struct pp_instance *ppi, long offset_ns, ...@@ -42,6 +42,9 @@ static int bare_time_adjust(struct pp_instance *ppi, long offset_ns,
struct bare_timex t; struct bare_timex t;
int ret; int ret;
/* FIXME: handle MOD_FREQUENCY and MOD_OFFSET separately, and
* set t.modes only for the mode having non-zero parameter.
* See posix_time_adjust in arch-gnu-linux/posix-time.c */
if (freq_ppm > PP_ADJ_FREQ_MAX) if (freq_ppm > PP_ADJ_FREQ_MAX)
freq_ppm = PP_ADJ_FREQ_MAX; freq_ppm = PP_ADJ_FREQ_MAX;
if (freq_ppm < -PP_ADJ_FREQ_MAX) if (freq_ppm < -PP_ADJ_FREQ_MAX)
...@@ -56,6 +59,16 @@ static int bare_time_adjust(struct pp_instance *ppi, long offset_ns, ...@@ -56,6 +59,16 @@ static int bare_time_adjust(struct pp_instance *ppi, long offset_ns,
return ret; return ret;
} }
int bare_time_adjust_offset(struct pp_instance *ppi, long offset_ns)
{
return bare_time_adjust(ppi, offset_ns, 0);
}
int bare_time_adjust_freq(struct pp_instance *ppi, long freq_ppm)
{
return bare_time_adjust(ppi, 0, freq_ppm);
}
static unsigned long bare_calc_timeout(struct pp_instance *ppi, int millisec) static unsigned long bare_calc_timeout(struct pp_instance *ppi, int millisec)
{ {
struct bare_timespec now; struct bare_timespec now;
...@@ -75,5 +88,7 @@ struct pp_time_operations bare_time_ops = { ...@@ -75,5 +88,7 @@ struct pp_time_operations bare_time_ops = {
.get = bare_time_get, .get = bare_time_get,
.set = bare_time_set, .set = bare_time_set,
.adjust = bare_time_adjust, .adjust = bare_time_adjust,
.adjust_offset = bare_time_adjust_offset,
.adjust_freq = bare_time_adjust_freq,
.calc_timeout = bare_calc_timeout, .calc_timeout = bare_calc_timeout,
}; };
...@@ -196,7 +196,11 @@ static void __pp_update_clock(struct pp_instance *ppi) ...@@ -196,7 +196,11 @@ static void __pp_update_clock(struct pp_instance *ppi)
} else { } else {
adj = DSCUR(ppi)->offsetFromMaster.nanoseconds adj = DSCUR(ppi)->offsetFromMaster.nanoseconds
> 0 ? PP_ADJ_FREQ_MAX:-PP_ADJ_FREQ_MAX; > 0 ? PP_ADJ_FREQ_MAX:-PP_ADJ_FREQ_MAX;
ppi->t_ops->adjust(ppi, 0, -adj);
if (ppi->t_ops->adjust_freq)
ppi->t_ops->adjust_freq(ppi, -adj);
else
ppi->t_ops->adjust_offset(ppi, -adj);
} }
} }
return; return;
...@@ -218,9 +222,14 @@ static void __pp_update_clock(struct pp_instance *ppi) ...@@ -218,9 +222,14 @@ static void __pp_update_clock(struct pp_instance *ppi)
adj = DSCUR(ppi)->offsetFromMaster.nanoseconds / OPTS(ppi)->ap + adj = DSCUR(ppi)->offsetFromMaster.nanoseconds / OPTS(ppi)->ap +
SRV(ppi)->obs_drift; SRV(ppi)->obs_drift;
/* apply controller output as a clock tick rate adjustment */ /* apply controller output as a clock tick rate adjustment, if
if (!OPTS(ppi)->no_adjust) * provided by arch, or as a raw offset otherwise */
ppi->t_ops->adjust(ppi, 0, -adj); if (!OPTS(ppi)->no_adjust) {
if (ppi->t_ops->adjust_freq)
ppi->t_ops->adjust_freq(ppi, -adj);
else
ppi->t_ops->adjust_offset(ppi, -adj);
}
} }
/* called only *exactly* after calling pp_update_offset above */ /* called only *exactly* after calling pp_update_offset above */
......
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