FILE
mcp251xfd-timestamp.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
1// SPDX-License-Identifier: GPL-2.0 2// 3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4// 5// Copyright (c) 2021, 2023 Pengutronix, 6// Marc Kleine-Budde <kernel@pengutronix.de> 7// 8 9#include <linux/clocksource.h> 10#include <linux/workqueue.h> 11 12#include "mcp251xfd.h" 13 14static u64 mcp251xfd_timestamp_raw_read(struct cyclecounter *cc) 15{ 16 const struct mcp251xfd_priv *priv; 17 u32 ts_raw = 0; 18 int err; 19 20 priv = container_of(cc, struct mcp251xfd_priv, cc); 21 err = mcp251xfd_get_timestamp_raw(priv, &ts_raw); 22 if (err) 23 netdev_err(priv->ndev, 24 "Error %d while reading timestamp. HW timestamps may be inaccurate.", 25 err); 26 27 return ts_raw; 28} 29 30static void mcp251xfd_timestamp_work(struct work_struct *work) 31{ 32 struct delayed_work *delayed_work = to_delayed_work(work); 33 struct mcp251xfd_priv *priv; 34 35 priv = container_of(delayed_work, struct mcp251xfd_priv, timestamp); 36 timecounter_read(&priv->tc); 37 38 schedule_delayed_work(&priv->timestamp, 39 MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); 40} 41 42void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv) 43{ 44 struct cyclecounter *cc = &priv->cc; 45 46 cc->read = mcp251xfd_timestamp_raw_read; 47 cc->mask = CYCLECOUNTER_MASK(32); 48 cc->shift = 1; 49 cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift); 50 51 INIT_DELAYED_WORK(&priv->timestamp, mcp251xfd_timestamp_work); 52} 53 54void mcp251xfd_timestamp_start(struct mcp251xfd_priv *priv) 55{ 56 timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns()); 57 schedule_delayed_work(&priv->timestamp, 58 MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ); 59} 60 61void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv) 62{ 63 cancel_delayed_work_sync(&priv->timestamp); 64}
~/
Read-only file preview.