diff options
Diffstat (limited to 'meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch')
-rw-r--r-- | meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch new file mode 100644 index 0000000..3752e98 --- /dev/null +++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0088-spi-slave-Add-SPI-slave-handler-controlling-system-s.patch @@ -0,0 +1,205 @@ +From 6acf67e94cbd406b57315f03937a8d4d37a2952c Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven <geert+renesas@glider.be> +Date: Fri, 17 Jun 2016 17:05:45 +0200 +Subject: [PATCH 6/7] spi: slave: Add SPI slave handler controlling system + state + +Add an example SPI slave handler to allow remote control of system +reboot, power off, halt, and suspend. + +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + drivers/spi/Kconfig | 6 ++ + drivers/spi/Makefile | 1 + + drivers/spi/spi-slave-system-control.c | 154 ++++++++++++++++++++++++++++++++ + 3 files changed, 161 insertions(+) + create mode 100644 drivers/spi/spi-slave-system-control.c + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 267bedf..45208ec 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -799,6 +799,12 @@ config SPI_SLAVE_TIME + SPI slave handler responding with the time of reception of the last + SPI message. + ++config SPI_SLAVE_SYSTEM_CONTROL ++ tristate "SPI slave handler controlling system state" ++ help ++ SPI slave handler to allow remote control of system reboot, power ++ off, halt, and suspend. ++ + endif # SPI_SLAVE + + endif # SPI +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index 5e2e537..d4d5050 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -105,3 +105,4 @@ obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o + + # SPI slave protocol handlers + obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o ++obj-$(CONFIG_SPI_SLAVE_SYSTEM_CONTROL) += spi-slave-system-control.o +diff --git a/drivers/spi/spi-slave-system-control.c b/drivers/spi/spi-slave-system-control.c +new file mode 100644 +index 0000000..c0257e9 +--- /dev/null ++++ b/drivers/spi/spi-slave-system-control.c +@@ -0,0 +1,154 @@ ++/* ++ * SPI slave handler controlling system state ++ * ++ * This SPI slave handler allows remote control of system reboot, power off, ++ * halt, and suspend. ++ * ++ * 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): ++ * ++ * # reboot='\x7c\x50' ++ * # poweroff='\x71\x3f' ++ * # halt='\x38\x76' ++ * # suspend='\x1b\x1b' ++ * # spidev_test -D /dev/spidev2.0 -p $suspend # or $reboot, $poweroff, $halt ++ */ ++ ++#include <linux/completion.h> ++#include <linux/module.h> ++#include <linux/reboot.h> ++#include <linux/suspend.h> ++#include <linux/spi/spi.h> ++ ++/* ++ * The numbers are chosen to display something human-readable on two 7-segment ++ * displays connected to two 74HC595 shift registers ++ */ ++#define CMD_REBOOT 0x7c50 /* rb */ ++#define CMD_POWEROFF 0x713f /* OF */ ++#define CMD_HALT 0x3876 /* HL */ ++#define CMD_SUSPEND 0x1b1b /* ZZ */ ++ ++struct spi_slave_system_control_priv { ++ struct spi_device *spi; ++ struct completion finished; ++ struct spi_transfer xfer; ++ struct spi_message msg; ++ __be16 cmd; ++}; ++ ++static ++int spi_slave_system_control_submit(struct spi_slave_system_control_priv *priv); ++ ++static void spi_slave_system_control_complete(void *arg) ++{ ++ struct spi_slave_system_control_priv *priv = arg; ++ u16 cmd; ++ int ret; ++ ++ if (priv->msg.status) ++ goto terminate; ++ ++ cmd = be16_to_cpu(priv->cmd); ++ switch (cmd) { ++ case CMD_REBOOT: ++ dev_info(&priv->spi->dev, "Rebooting system...\n"); ++ kernel_restart(NULL); ++ ++ case CMD_POWEROFF: ++ dev_info(&priv->spi->dev, "Powering off system...\n"); ++ kernel_power_off(); ++ break; ++ ++ case CMD_HALT: ++ dev_info(&priv->spi->dev, "Halting system...\n"); ++ kernel_halt(); ++ break; ++ ++ case CMD_SUSPEND: ++ dev_info(&priv->spi->dev, "Suspending system...\n"); ++ pm_suspend(PM_SUSPEND_MEM); ++ break; ++ ++ default: ++ dev_warn(&priv->spi->dev, "Unknown command 0x%x\n", cmd); ++ break; ++ } ++ ++ ret = spi_slave_system_control_submit(priv); ++ if (ret) ++ goto terminate; ++ ++ return; ++ ++terminate: ++ dev_info(&priv->spi->dev, "Terminating\n"); ++ complete(&priv->finished); ++} ++ ++static ++int spi_slave_system_control_submit(struct spi_slave_system_control_priv *priv) ++{ ++ int ret; ++ ++ spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); ++ ++ priv->msg.complete = spi_slave_system_control_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_system_control_probe(struct spi_device *spi) ++{ ++ struct spi_slave_system_control_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.rx_buf = &priv->cmd; ++ priv->xfer.len = sizeof(priv->cmd); ++ ++ ret = spi_slave_system_control_submit(priv); ++ if (ret) ++ return ret; ++ ++ spi_set_drvdata(spi, priv); ++ return 0; ++} ++ ++static int spi_slave_system_control_remove(struct spi_device *spi) ++{ ++ struct spi_slave_system_control_priv *priv = spi_get_drvdata(spi); ++ ++ spi_slave_abort(spi); ++ wait_for_completion(&priv->finished); ++ return 0; ++} ++ ++static struct spi_driver spi_slave_system_control_driver = { ++ .driver = { ++ .name = "spi-slave-system-control", ++ }, ++ .probe = spi_slave_system_control_probe, ++ .remove = spi_slave_system_control_remove, ++}; ++module_spi_driver(spi_slave_system_control_driver); ++ ++MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>"); ++MODULE_DESCRIPTION("SPI slave handler controlling system state"); ++MODULE_LICENSE("GPL v2"); +-- +1.7.10.4 |