On Mon, Jul 01, 2019 at 12:03:27PM +0200, Antoine Tenart wrote: > +void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts) > +{ > + /* Read current PTP time to get seconds */ > + u32 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
This register is protected by ocelot->ptp_clock_lock from other code paths, but not in this one! > + val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM); > + val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE); > + ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN); > + ts->tv_sec = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN); ... > +} > +static int ocelot_init_timestamp(struct ocelot *ocelot) > +{ > + ocelot->ptp_info = ocelot_ptp_clock_info; > + > + ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); > + if (IS_ERR(ocelot->ptp_clock)) > + return PTR_ERR(ocelot->ptp_clock); You need to handle the NULL case: ptp_clock_register() - register a PTP hardware clock driver @info: Structure describing the new clock. @parent: Pointer to the parent device of the new clock. Returns a valid pointer on success or PTR_ERR on failure. If PHC support is missing at the configuration level, this function returns NULL, and drivers are expected to gracefully handle that case separately. > + > + ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); > + ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); > + ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); > + > + ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC); > + > + return 0; > +} Thanks, Richard