summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch')
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch182
1 files changed, 182 insertions, 0 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch
new file mode 100644
index 0000000..1c9be85
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0087-spi-slave-Add-SPI-slave-handler-reporting-uptime-at-.patch
@@ -0,0 +1,182 @@
+From 8b3a09269db92be56455d98bc8cb01f779733f0a Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Fri, 17 Jun 2016 17:00:25 +0200
+Subject: [PATCH 5/7] spi: slave: Add SPI slave handler reporting uptime at
+ previous message
+
+Add an example SPI slave handler responding with the uptime at the time
+of reception of the last SPI message.
+
+This can be used by an external microcontroller as a dead man's switch.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+---
+ drivers/spi/Kconfig | 6 ++
+ drivers/spi/Makefile | 1 +
+ drivers/spi/spi-slave-time.c | 129 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 136 insertions(+)
+ create mode 100644 drivers/spi/spi-slave-time.c
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 8c97790..267bedf 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -793,6 +793,12 @@ config SPI_SLAVE
+
+ if SPI_SLAVE
+
++config SPI_SLAVE_TIME
++ tristate "SPI slave handler reporting boot up time"
++ help
++ SPI slave handler responding with the time of reception of the last
++ SPI message.
++
+ endif # SPI_SLAVE
+
+ endif # SPI
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 2428b0f..5e2e537 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -104,3 +104,4 @@ obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o
+ obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o
+
+ # SPI slave protocol handlers
++obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o
+diff --git a/drivers/spi/spi-slave-time.c b/drivers/spi/spi-slave-time.c
+new file mode 100644
+index 0000000..fbeaa5b
+--- /dev/null
++++ b/drivers/spi/spi-slave-time.c
+@@ -0,0 +1,129 @@
++/*
++ * SPI slave handler reporting uptime at reception of previous SPI message
++ *
++ * This SPI slave handler sends the time of reception of the last SPI message
++ * as two 32-bit unsigned integers in binary format and in network byte order,
++ * representing the number of seconds and fractional seconds (in microseconds)
++ * since boot up.
++ *
++ * Copyright (C) 2016-2017 Glider bvba
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Usage (assuming /dev/spidev2.0 corresponds to the SPI master on the remote
++ * system):
++ *
++ * # spidev_test -D /dev/spidev2.0 -p dummy-8B
++ * spi mode: 0x0
++ * bits per word: 8
++ * max speed: 500000 Hz (500 KHz)
++ * RX | 00 00 04 6D 00 09 5B BB ...
++ * ^^^^^ ^^^^^^^^
++ * seconds microseconds
++ */
++
++#include <linux/completion.h>
++#include <linux/module.h>
++#include <linux/sched.h>
++#include <linux/spi/spi.h>
++
++
++struct spi_slave_time_priv {
++ struct spi_device *spi;
++ struct completion finished;
++ struct spi_transfer xfer;
++ struct spi_message msg;
++ __be32 buf[2];
++};
++
++static int spi_slave_time_submit(struct spi_slave_time_priv *priv);
++
++static void spi_slave_time_complete(void *arg)
++{
++ struct spi_slave_time_priv *priv = arg;
++ int ret;
++
++ ret = priv->msg.status;
++ if (ret)
++ goto terminate;
++
++ ret = spi_slave_time_submit(priv);
++ if (ret)
++ goto terminate;
++
++ return;
++
++terminate:
++ dev_info(&priv->spi->dev, "Terminating\n");
++ complete(&priv->finished);
++}
++
++static int spi_slave_time_submit(struct spi_slave_time_priv *priv)
++{
++ u32 rem_us;
++ int ret;
++ u64 ts;
++
++ ts = local_clock();
++ rem_us = do_div(ts, 1000000000) / 1000;
++
++ priv->buf[0] = cpu_to_be32(ts);
++ priv->buf[1] = cpu_to_be32(rem_us);
++
++ spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1);
++
++ priv->msg.complete = spi_slave_time_complete;
++ priv->msg.context = priv;
++
++ ret = spi_async(priv->spi, &priv->msg);
++ if (ret)
++ dev_err(&priv->spi->dev, "spi_async() failed %d\n", ret);
++
++ return ret;
++}
++
++static int spi_slave_time_probe(struct spi_device *spi)
++{
++ struct spi_slave_time_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->spi = spi;
++ init_completion(&priv->finished);
++ priv->xfer.tx_buf = priv->buf;
++ priv->xfer.len = sizeof(priv->buf);
++
++ ret = spi_slave_time_submit(priv);
++ if (ret)
++ return ret;
++
++ spi_set_drvdata(spi, priv);
++ return 0;
++}
++
++static int spi_slave_time_remove(struct spi_device *spi)
++{
++ struct spi_slave_time_priv *priv = spi_get_drvdata(spi);
++
++ spi_slave_abort(spi);
++ wait_for_completion(&priv->finished);
++ return 0;
++}
++
++static struct spi_driver spi_slave_time_driver = {
++ .driver = {
++ .name = "spi-slave-time",
++ },
++ .probe = spi_slave_time_probe,
++ .remove = spi_slave_time_remove,
++};
++module_spi_driver(spi_slave_time_driver);
++
++MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>");
++MODULE_DESCRIPTION("SPI slave reporting uptime at previous SPI message");
++MODULE_LICENSE("GPL v2");
+--
+1.7.10.4