diff options
author | Vadim Fedorenko | 2022-03-02 13:34:57 -0800 |
---|---|---|
committer | David S. Miller | 2022-03-03 14:42:46 +0000 |
commit | 44a412d13b31fdfdb79e76f9c959e83f86dfe578 (patch) | |
tree | add5bbb6efd53f3abd62f6f257856c9b74052b8e /drivers/ptp | |
parent | 2f23f486cf626a9a2ea70da0dac93c63e89f6595 (diff) |
ptp: ocp: add tod_correction attribute
TOD correction register is used to compensate for leap seconds in
different domains. Export it as an attribute with write access.
Signed-off-by: Vadim Fedorenko <vadfed@fb.com>
Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ptp')
-rw-r--r-- | drivers/ptp/ptp_ocp.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index e9094dee78a4..bd872a616b94 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -1967,6 +1967,46 @@ clock_status_offset_show(struct device *dev, } static DEVICE_ATTR_RO(clock_status_offset); +static ssize_t +tod_correction_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + u32 val; + int res; + + val = ioread32(&bp->tod->adj_sec); + res = (val & ~INT_MAX) ? -1 : 1; + res *= (val & INT_MAX); + return sysfs_emit(buf, "%d\n", res); +} + +static ssize_t +tod_correction_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ptp_ocp *bp = dev_get_drvdata(dev); + unsigned long flags; + int err, res; + u32 val = 0; + + err = kstrtos32(buf, 0, &res); + if (err) + return err; + if (res < 0) { + res *= -1; + val |= BIT(31); + } + val |= res; + + spin_lock_irqsave(&bp->lock, flags); + iowrite32(val, &bp->tod->adj_sec); + spin_unlock_irqrestore(&bp->lock, flags); + + return count; +} +static DEVICE_ATTR_RW(tod_correction); + static struct attribute *timecard_attrs[] = { &dev_attr_serialnum.attr, &dev_attr_gnss_sync.attr, @@ -1983,6 +2023,7 @@ static struct attribute *timecard_attrs[] = { &dev_attr_irig_b_mode.attr, &dev_attr_utc_tai_offset.attr, &dev_attr_ts_window_adjust.attr, + &dev_attr_tod_correction.attr, NULL, }; ATTRIBUTE_GROUPS(timecard); |