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,6 +47,9 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm)
struct timex t;
int ret;
t.modes = 0;
if (freq_ppm) {
if (freq_ppm > PP_ADJ_FREQ_MAX)
freq_ppm = PP_ADJ_FREQ_MAX;
if (freq_ppm < -PP_ADJ_FREQ_MAX)
......@@ -54,6 +57,7 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm)
t.freq = freq_ppm * ((1 << 16) / 1000);
t.modes = MOD_FREQUENCY;
}
if (offset_ns) {
t.offset = offset_ns / 1000;
......@@ -65,6 +69,16 @@ int posix_time_adjust(struct pp_instance *ppi, long offset_ns, long freq_ppm)
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)
{
struct timespec now;
......@@ -84,5 +98,7 @@ struct pp_time_operations posix_time_ops = {
.get = posix_time_get,
.set = posix_time_set,
.adjust = posix_time_adjust,
.adjust_offset = posix_time_adjust_offset,
.adjust_freq = posix_time_adjust_freq,
.calc_timeout = posix_calc_timeout,
};
......@@ -36,16 +36,24 @@ static int wrpc_time_set(struct pp_instance *ppi, TimeInternal *t)
return 0;
}
static int wrpc_time_adjust(struct pp_instance *ppi, long offset_ns,
long freq_ppm)
static int wrpc_time_adjust_offset(struct pp_instance *ppi, long offset_ns)
{
pp_diag(ppi, time, 1, "%s: %li %li\n",
__func__, offset_ns, freq_ppm);
pp_diag(ppi, time, 1, "%s: %li\n",
__func__, offset_ns);
if (offset_ns)
shw_pps_gen_adjust(PPSG_ADJUST_NSEC, offset_ns);
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)
{
unsigned long now_ms = timer_get_tics();
......@@ -58,5 +66,7 @@ struct pp_time_operations wrpc_time_ops = {
.get = wrpc_time_get,
.set = wrpc_time_set,
.adjust = wrpc_time_adjust,
.adjust_offset = wrpc_time_adjust_offset,
.adjust_freq = NULL,
.calc_timeout = wrpc_calc_timeout,
};
......@@ -153,6 +153,8 @@ struct pp_time_operations {
int (*set)(struct pp_instance *ppi, TimeInternal *t);
/* 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_offset)(struct pp_instance *ppi, long offset_ns);
int (*adjust_freq)(struct pp_instance *ppi, long freq_ppm);
/* calc_timeout cannot return zero */
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,
struct bare_timex t;
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)
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,
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)
{
struct bare_timespec now;
......@@ -75,5 +88,7 @@ struct pp_time_operations bare_time_ops = {
.get = bare_time_get,
.set = bare_time_set,
.adjust = bare_time_adjust,
.adjust_offset = bare_time_adjust_offset,
.adjust_freq = bare_time_adjust_freq,
.calc_timeout = bare_calc_timeout,
};
......@@ -196,7 +196,11 @@ static void __pp_update_clock(struct pp_instance *ppi)
} else {
adj = DSCUR(ppi)->offsetFromMaster.nanoseconds
> 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;
......@@ -218,9 +222,14 @@ static void __pp_update_clock(struct pp_instance *ppi)
adj = DSCUR(ppi)->offsetFromMaster.nanoseconds / OPTS(ppi)->ap +
SRV(ppi)->obs_drift;
/* apply controller output as a clock tick rate adjustment */
if (!OPTS(ppi)->no_adjust)
ppi->t_ops->adjust(ppi, 0, -adj);
/* apply controller output as a clock tick rate adjustment, if
* provided by arch, or as a raw offset otherwise */
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 */
......
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