in ptp_clockmatrix.c [1573:1614]
static int do_phase_pull_in_sw(struct idtcm_channel *channel,
s32 delta_ns,
u32 max_ffo_ppb)
{
s32 current_ppm = channel->current_freq_scaled_ppm;
u32 duration_ms = MSEC_PER_SEC;
s32 delta_ppm;
s32 ppb;
int err;
/* If the ToD correction is less than PHASE_PULL_IN_MIN_THRESHOLD_NS,
* skip. The error introduced by the ToD adjustment procedure would
* be bigger than the required ToD correction
*/
if (abs(delta_ns) < PHASE_PULL_IN_MIN_THRESHOLD_NS)
return 0;
if (max_ffo_ppb == 0)
max_ffo_ppb = PHASE_PULL_IN_MAX_PPB;
/* For most cases, keep phase pull-in duration 1 second */
ppb = delta_ns;
while (abs(ppb) > max_ffo_ppb) {
duration_ms *= 2;
ppb /= 2;
}
delta_ppm = phase_pull_in_scaled_ppm(current_ppm, ppb);
err = _idtcm_adjfine(channel, delta_ppm);
if (err)
return err;
/* schedule the worker to cancel phase pull-in */
ptp_schedule_worker(channel->ptp_clock,
msecs_to_jiffies(duration_ms) - 1);
channel->phase_pull_in = true;
return 0;
}