diff --git a/patch.sh b/patch.sh index 44ba7eca6..1e1949ae2 100644 --- a/patch.sh +++ b/patch.sh @@ -617,6 +617,7 @@ drivers () { dir 'drivers/uio_pruss_shmem' dir 'drivers/greybus' dir 'RPi' + dir 'gsoc' dir 'fixes' } diff --git a/patches/defconfig b/patches/defconfig index 1e51e4015..3fe4ca702 100644 --- a/patches/defconfig +++ b/patches/defconfig @@ -5493,6 +5493,7 @@ CONFIG_RPMSG=y CONFIG_RPMSG_VIRTIO=m CONFIG_RPMSG_RPC=m CONFIG_RPMSG_PRU=m +CONFIG_CONFIG_RPMSG_GPIOHIP_INTERFACE=m # # Rpmsg virtual device drivers diff --git a/patches/gsoc/0001-Added-driver-to-use-rpmsg-with-gpiochip-interface.Re.patch b/patches/gsoc/0001-Added-driver-to-use-rpmsg-with-gpiochip-interface.Re.patch new file mode 100644 index 000000000..85e899873 --- /dev/null +++ b/patches/gsoc/0001-Added-driver-to-use-rpmsg-with-gpiochip-interface.Re.patch @@ -0,0 +1,278 @@ +From 50ad0fc3083890661113180aa3a849958d0c0787 Mon Sep 17 00:00:00 2001 +From: deebot +Date: Sun, 23 Aug 2020 13:40:44 +0200 +Subject: [PATCH] - Added driver to use rpmsg with gpiochip interface.Requires + PRU firmware Please follow instructions to load PRU firmware + https://github.com/deebot/Beaglebone-BidirectionBus/blob/dev/bidirec_299/README.md + - Added rule to compile rpmsg-gpio driver in Make and Kconfig + +--- + drivers/rpmsg/Kconfig | 12 ++ + drivers/rpmsg/Makefile | 2 + + drivers/rpmsg/rpmsg_gpio.c | 222 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 236 insertions(+) + create mode 100644 drivers/rpmsg/rpmsg_gpio.c + +diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig +index c41d8157b079..ef2c47c017bb 100644 +--- a/drivers/rpmsg/Kconfig ++++ b/drivers/rpmsg/Kconfig +@@ -81,4 +81,16 @@ config RPMSG_PRU + + If unsure, say N. + ++config CONFIG_RPMSG_GPIOHIP_INTERFACE ++ tristate "A rpmsg driver with gpiochip interface" ++ default m ++ depends on RPMSG_VIRTIO ++ depends on REMOTEPROC ++ help ++ This driver provides provides gpiochip inteface which can be accessed ++ in userspace using libgpiod. You would see a char dev interface in ++ "/dev" using this driver. Follow the README from the following ++ repo for more info. ++ https://github.com/deebot/Beaglebone-BidirectionBus ++ + endmenu +diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile +index 6666c8d6327e..3b93ea58ae36 100644 +--- a/drivers/rpmsg/Makefile ++++ b/drivers/rpmsg/Makefile +@@ -9,4 +9,6 @@ obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o + obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o + + obj-$(CONFIG_RPMSG_RPC) += rpmsg-rpc.o ++obj-$(CONFIG_RPMSG_GPIOCHIP_INTERFACE) += rpmsg_gpio.o + rpmsg-rpc-y := rpmsg_rpc.o rpmsg_rpc_sysfs.o rpmsg_rpc_dmabuf.o ++ +diff --git a/drivers/rpmsg/rpmsg_gpio.c b/drivers/rpmsg/rpmsg_gpio.c +new file mode 100644 +index 000000000000..92fd7e517c3c +--- /dev/null ++++ b/drivers/rpmsg/rpmsg_gpio.c +@@ -0,0 +1,222 @@ ++/* ++ * PRU Remote Processor Messaging Driver with gpiochip interface ++ * copyright (c) 2020 Deepankar Maithani ++ * Codes examples from Lab no 5 from TI and has been used as boiler plate for rpmsg communication ++ * https://processors.wiki.ti.com/index.php/PRU_Training:_Hands-on_Labs ++ * ++ * For learn more about the complete project visit: ++ * https://github.com/deebot/Beaglebone-BidirectionBus/tree/dev ++ * Steps to test the driver. ++ * https://github.com/deebot/Beaglebone-BidirectionBus/blob/dev/bidirec_299/README.md ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define PRU_MAX_DEVICES (16) ++/* Matches the definition in virtio_rpmsg_bus.c */ ++#define RPMSG_BUF_SIZE (512) ++#define MAX_FIFO_MSG (32) ++#define FIFO_MSG_SIZE RPMSG_BUF_SIZE ++#define GPIO_NUM 9 ++static DEFINE_MUTEX(rpmsg_pru_lock); ++static char rpmsg_pru_buf[RPMSG_BUF_SIZE]; ++static struct gpio_chip chip; ++struct rpmsg_pru_dev { ++ struct rpmsg_device *rpdev; ++ struct device *dev; ++ bool locked; ++ dev_t devt; ++ struct kfifo msg_fifo; ++ u32 msg_len[MAX_FIFO_MSG]; ++ int msg_idx_rd; ++ int msg_idx_wr; ++ wait_queue_head_t wait_list; ++ uint32_t gpio_state; ++ long input_state; ++ ++}; ++ ++struct rpmsg_pru_dev *prudev; ++/*Reads the lines which are set as input*/ ++static int mygpio_get_value(struct gpio_chip *gc, unsigned offset) ++{ ++ uint32_t value; ++ struct rpmsg_device *rpdev = container_of(gc->parent, ++ struct rpmsg_device, dev); ++ unsigned int mask = BIT(offset % 8); ++ prudev = dev_get_drvdata(&rpdev->dev); ++ ++ value = (prudev->input_state & mask)>>offset; ++ return value; ++} ++/* Writes to the lines and creates the gpio_state which is then sent as RPmsg */ ++static void mygpio_set_value(struct gpio_chip *gc, unsigned offset, int val) ++{ ++ int ret; ++ struct rpmsg_device *rpdev = container_of(gc->parent, struct rpmsg_device, dev); ++ pr_info("set_value function triggered"); ++ pr_info("The bit number %d is set to value: %d", offset, val); ++ ++ prudev = dev_get_drvdata(&rpdev->dev); ++ if (val == 0) { ++ prudev->gpio_state &= ~(1<gpio_state |= (1<gpio_state), ++ sizeof(&(prudev->gpio_state))); ++ pr_info("A check for checking gpio_state: %d", ++ prudev->gpio_state); ++ /* This line actually sends the data to the other side*/ ++ ret = rpmsg_send(rpdev->ept, (void *)rpmsg_pru_buf, 2); ++ if (ret) ++ dev_err(gc->parent, "rpmsg_send failed: %d\n", ret); ++ } ++ ++} ++ ++/*sets the pin to output. Will be called when user sets one ++ * of the gpiochip line as output which can be done manually ++ * in sysfs or using libgpiod */ ++ ++static int mygpio_direction_output(struct gpio_chip *gc, ++ unsigned offset, int val) ++{ ++ pr_info("Direction of GPIO set to: out\n"); ++ return 0; ++} ++/*Runs When direction of a line is set as output*/ ++static int mygpio_direction_input(struct gpio_chip *gc, ++ unsigned offset) ++{ ++ ++ pr_info("Direction of GPIO set to: in \n"); ++ return 0; ++} ++/*This function gets called every time ++ *an rpmsg_channel is created with a name that matches the .name ++ *attribute of the rpmsg_driver_sample_id_table. It sets up suitable memory ++ *and the gpiochip interface that can be seen in /sys/class/gpio and /dev. ++ */ ++static int mygpio_rpmsg_pru_probe (struct rpmsg_device *rpdev) ++{ ++ int ret; ++ struct rpmsg_pru_dev *prudev; ++ prudev = devm_kzalloc(&rpdev->dev, sizeof(*prudev), GFP_KERNEL); ++ if (!prudev) ++ return -ENOMEM; ++ prudev->rpdev = rpdev; ++ ret = kfifo_alloc(&prudev->msg_fifo, MAX_FIFO_MSG * FIFO_MSG_SIZE, ++ GFP_KERNEL); ++ if (ret) { ++ dev_err(&rpdev->dev, "Unable to allocate fifo for the rpmsg_pru device\n"); ++ return -ENOMEM; ++ } ++ init_waitqueue_head(&prudev->wait_list); ++ dev_set_drvdata(&rpdev->dev, prudev); ++ chip.label = rpdev->desc; ++ chip.base = -1; ++ chip.parent = &rpdev->dev; ++ chip.owner = THIS_MODULE; ++ chip.ngpio = GPIO_NUM; ++ chip.can_sleep = 1; ++ chip.get = mygpio_get_value; ++ chip.set = mygpio_set_value; ++ chip.direction_output = mygpio_direction_output; ++ chip.direction_input = mygpio_direction_input; ++ return gpiochip_add(&chip); ++} ++/* Callback function which gets called whenever a new rpmsg is received ++ * The data received from the PRU is converted into long and then assigned to ++ * input_state ++ * @msg_fifo: kernel fifo used to buffer the messages between userspace and PRU ++ * @msg_len: array storing the lengths of each message in the kernel fifo ++ * @msg_idx_rd: kernel fifo read index ++ * @msg_idx_wr: kernel fifo write index ++ * */ ++static int mygpio_rpmsg_pru_cb(struct rpmsg_device *rpdev, void *data, int len, ++ void *priv, u32 src) ++{ int ret; ++ u32 length; ++ struct rpmsg_pru_dev *prudev; ++ ++ prudev = dev_get_drvdata(&rpdev->dev); ++ ++ if (kfifo_avail(&prudev->msg_fifo) < len) { ++ dev_err(&rpdev->dev, "Not enough space on the FIFO\n"); ++ return -ENOSPC; ++ } ++ ++ if ((prudev->msg_idx_wr + 1) % MAX_FIFO_MSG == ++ prudev->msg_idx_rd) { ++ dev_err(&rpdev->dev, "Message length table is full\n"); ++ return -ENOSPC; ++ } ++ /* adds the data received into a fifo*/ ++ length = kfifo_in(&prudev->msg_fifo, data, len); ++ prudev->msg_len[prudev->msg_idx_wr] = length; ++ prudev->msg_idx_wr = (prudev->msg_idx_wr + 1) % MAX_FIFO_MSG; ++ ++ wake_up_interruptible(&prudev->wait_list); ++ ret = kstrtol((char *) data, 10, &prudev->input_state); ++ if (ret) { ++ return ret; ++ } ++ pr_info("The shift register port state is: %ld", prudev->input_state); ++ return 0; ++} ++static void mygpio_rpmsg_pru_remove(struct rpmsg_device *rpdev) ++{ ++ struct rpmsg_pru_dev *prudev; ++ prudev = dev_get_drvdata(&rpdev->dev); ++ ++ kfifo_free(&prudev->msg_fifo); ++ gpiochip_remove(&chip); ++ ++} ++/* ++ * Matches this tag:If you change .name ++ * PRU firmware should also be updated with same channel name ++ */ ++static const struct rpmsg_device_id rpmsg_driver_pru_id_table[] = { ++ { .name = "rpmsg-pru-gpio" }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_pru_id_table); ++ ++static struct rpmsg_driver rpmsg_pru_driver = { ++ .drv.name = KBUILD_MODNAME, ++ .id_table = rpmsg_driver_pru_id_table, ++ .probe = mygpio_rpmsg_pru_probe, ++ .callback = mygpio_rpmsg_pru_cb, ++ .remove = mygpio_rpmsg_pru_remove, ++}; ++ ++module_rpmsg_driver(rpmsg_pru_driver); ++MODULE_AUTHOR("DeepankarMaithani "); ++MODULE_DESCRIPTION("A driver to send rpmsg data using sysfs and chardev interface"); ++MODULE_VERSION("0.1"); ++MODULE_LICENSE("GPL"); ++ +-- +2.28.0 + diff --git a/version.sh b/version.sh index 430d0462e..1e209dd37 100644 --- a/version.sh +++ b/version.sh @@ -39,7 +39,7 @@ KERNEL_REL=4.19 KERNEL_TAG=${KERNEL_REL}.94 kernel_rt=".94-rt39" #Kernel Build -BUILD=${build_prefix}50 +BUILD=${build_prefix}50.1 #v5.X-rcX + upto SHA #prev_KERNEL_SHA=""