0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <linux/completion.h>
0028 #include <linux/module.h>
0029 #include <linux/sched/clock.h>
0030 #include <linux/spi/spi.h>
0031
0032
0033 struct spi_slave_time_priv {
0034 struct spi_device *spi;
0035 struct completion finished;
0036 struct spi_transfer xfer;
0037 struct spi_message msg;
0038 __be32 buf[2];
0039 };
0040
0041 static int spi_slave_time_submit(struct spi_slave_time_priv *priv);
0042
0043 static void spi_slave_time_complete(void *arg)
0044 {
0045 struct spi_slave_time_priv *priv = arg;
0046 int ret;
0047
0048 ret = priv->msg.status;
0049 if (ret)
0050 goto terminate;
0051
0052 ret = spi_slave_time_submit(priv);
0053 if (ret)
0054 goto terminate;
0055
0056 return;
0057
0058 terminate:
0059 dev_info(&priv->spi->dev, "Terminating\n");
0060 complete(&priv->finished);
0061 }
0062
0063 static int spi_slave_time_submit(struct spi_slave_time_priv *priv)
0064 {
0065 u32 rem_us;
0066 int ret;
0067 u64 ts;
0068
0069 ts = local_clock();
0070 rem_us = do_div(ts, 1000000000) / 1000;
0071
0072 priv->buf[0] = cpu_to_be32(ts);
0073 priv->buf[1] = cpu_to_be32(rem_us);
0074
0075 spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1);
0076
0077 priv->msg.complete = spi_slave_time_complete;
0078 priv->msg.context = priv;
0079
0080 ret = spi_async(priv->spi, &priv->msg);
0081 if (ret)
0082 dev_err(&priv->spi->dev, "spi_async() failed %d\n", ret);
0083
0084 return ret;
0085 }
0086
0087 static int spi_slave_time_probe(struct spi_device *spi)
0088 {
0089 struct spi_slave_time_priv *priv;
0090 int ret;
0091
0092 priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
0093 if (!priv)
0094 return -ENOMEM;
0095
0096 priv->spi = spi;
0097 init_completion(&priv->finished);
0098 priv->xfer.tx_buf = priv->buf;
0099 priv->xfer.len = sizeof(priv->buf);
0100
0101 ret = spi_slave_time_submit(priv);
0102 if (ret)
0103 return ret;
0104
0105 spi_set_drvdata(spi, priv);
0106 return 0;
0107 }
0108
0109 static void spi_slave_time_remove(struct spi_device *spi)
0110 {
0111 struct spi_slave_time_priv *priv = spi_get_drvdata(spi);
0112
0113 spi_slave_abort(spi);
0114 wait_for_completion(&priv->finished);
0115 }
0116
0117 static struct spi_driver spi_slave_time_driver = {
0118 .driver = {
0119 .name = "spi-slave-time",
0120 },
0121 .probe = spi_slave_time_probe,
0122 .remove = spi_slave_time_remove,
0123 };
0124 module_spi_driver(spi_slave_time_driver);
0125
0126 MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>");
0127 MODULE_DESCRIPTION("SPI slave reporting uptime at previous SPI message");
0128 MODULE_LICENSE("GPL v2");