diff options
Diffstat (limited to 'meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-1-3-drivers-fsi-sbefifo-Add-in-kernel-API.patch')
-rw-r--r-- | meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-1-3-drivers-fsi-sbefifo-Add-in-kernel-API.patch | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-1-3-drivers-fsi-sbefifo-Add-in-kernel-API.patch b/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-1-3-drivers-fsi-sbefifo-Add-in-kernel-API.patch deleted file mode 100644 index 70a11f265..000000000 --- a/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-1-3-drivers-fsi-sbefifo-Add-in-kernel-API.patch +++ /dev/null @@ -1,338 +0,0 @@ -From patchwork Fri May 12 19:38:18 2017 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [linux,dev-4.10,1/3] drivers: fsi: sbefifo: Add in-kernel API -From: eajames@linux.vnet.ibm.com -X-Patchwork-Id: 761836 -Message-Id: <1494617900-32369-2-git-send-email-eajames@linux.vnet.ibm.com> -To: openbmc@lists.ozlabs.org -Cc: "Edward A. James" <eajames@us.ibm.com>, bradleyb@fuzziesquirrel.com, - cbostic@linux.vnet.ibm.com -Date: Fri, 12 May 2017 14:38:18 -0500 - -From: "Edward A. James" <eajames@us.ibm.com> - -Add exported functions to the SBEFIFO driver to open/write/read/close -from within the kernel. - -Signed-off-by: Edward A. James <eajames@us.ibm.com> ---- - drivers/fsi/fsi-sbefifo.c | 161 +++++++++++++++++++++++++++++++++++--------- - include/linux/fsi-sbefifo.h | 30 +++++++++ - 2 files changed, 161 insertions(+), 30 deletions(-) - create mode 100644 include/linux/fsi-sbefifo.h - -diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c -index b49aec2..56e6331 100644 ---- a/drivers/fsi/fsi-sbefifo.c -+++ b/drivers/fsi/fsi-sbefifo.c -@@ -15,9 +15,12 @@ - #include <linux/errno.h> - #include <linux/idr.h> - #include <linux/fsi.h> -+#include <linux/fsi-sbefifo.h> - #include <linux/list.h> - #include <linux/miscdevice.h> - #include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_platform.h> - #include <linux/poll.h> - #include <linux/sched.h> - #include <linux/slab.h> -@@ -82,6 +85,7 @@ struct sbefifo_client { - struct list_head xfrs; - struct sbefifo *dev; - struct kref kref; -+ unsigned long f_flags; - }; - - static struct list_head sbefifo_fifos; -@@ -506,6 +510,7 @@ static int sbefifo_open(struct inode *inode, struct file *file) - return -ENOMEM; - - file->private_data = client; -+ client->f_flags = file->f_flags; - - return 0; - } -@@ -530,24 +535,18 @@ static unsigned int sbefifo_poll(struct file *file, poll_table *wait) - return mask; - } - --static ssize_t sbefifo_read(struct file *file, char __user *buf, -- size_t len, loff_t *offset) -+static ssize_t sbefifo_read_common(struct sbefifo_client *client, -+ char __user *ubuf, char *kbuf, size_t len) - { -- struct sbefifo_client *client = file->private_data; - struct sbefifo *sbefifo = client->dev; - struct sbefifo_xfr *xfr; -- ssize_t ret = 0; - size_t n; -- -- WARN_ON(*offset); -- -- if (!access_ok(VERIFY_WRITE, buf, len)) -- return -EFAULT; -+ ssize_t ret = 0; - - if ((len >> 2) << 2 != len) - return -EINVAL; - -- if ((file->f_flags & O_NONBLOCK) && !sbefifo_xfr_rsp_pending(client)) -+ if ((client->f_flags & O_NONBLOCK) && !sbefifo_xfr_rsp_pending(client)) - return -EAGAIN; - - sbefifo_get_client(client); -@@ -566,10 +565,13 @@ static ssize_t sbefifo_read(struct file *file, char __user *buf, - - n = min_t(size_t, n, len); - -- if (copy_to_user(buf, READ_ONCE(client->rbuf.rpos), n)) { -- sbefifo_put_client(client); -- return -EFAULT; -- } -+ if (ubuf) { -+ if (copy_to_user(ubuf, READ_ONCE(client->rbuf.rpos), n)) { -+ sbefifo_put_client(client); -+ return -EFAULT; -+ } -+ } else -+ memcpy(kbuf, READ_ONCE(client->rbuf.rpos), n); - - if (sbefifo_buf_readnb(&client->rbuf, n)) { - xfr = sbefifo_client_next_xfr(client); -@@ -592,20 +594,28 @@ static ssize_t sbefifo_read(struct file *file, char __user *buf, - return n; - } - --static ssize_t sbefifo_write(struct file *file, const char __user *buf, -+static ssize_t sbefifo_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) - { - struct sbefifo_client *client = file->private_data; -- struct sbefifo *sbefifo = client->dev; -- struct sbefifo_xfr *xfr; -- ssize_t ret = 0; -- size_t n; - - WARN_ON(*offset); - -- if (!access_ok(VERIFY_READ, buf, len)) -+ if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - -+ return sbefifo_read_common(client, buf, NULL, len); -+} -+ -+static ssize_t sbefifo_write_common(struct sbefifo_client *client, -+ const char __user *ubuf, const char *kbuf, -+ size_t len) -+{ -+ struct sbefifo *sbefifo = client->dev; -+ struct sbefifo_xfr *xfr; -+ ssize_t ret = 0; -+ size_t n; -+ - if ((len >> 2) << 2 != len) - return -EINVAL; - -@@ -617,7 +627,7 @@ static ssize_t sbefifo_write(struct file *file, const char __user *buf, - spin_lock_irq(&sbefifo->lock); - xfr = sbefifo_next_xfr(sbefifo); - -- if ((file->f_flags & O_NONBLOCK) && xfr && n < len) { -+ if ((client->f_flags & O_NONBLOCK) && xfr && n < len) { - spin_unlock_irq(&sbefifo->lock); - return -EAGAIN; - } -@@ -657,18 +667,25 @@ static ssize_t sbefifo_write(struct file *file, const char __user *buf, - - n = min_t(size_t, n, len); - -- if (copy_from_user(READ_ONCE(client->wbuf.wpos), buf, n)) { -- set_bit(SBEFIFO_XFR_CANCEL, &xfr->flags); -- sbefifo_get(sbefifo); -- if (mod_timer(&sbefifo->poll_timer, jiffies)) -- sbefifo_put(sbefifo); -- sbefifo_put_client(client); -- return -EFAULT; -+ if (ubuf) { -+ if (copy_from_user(READ_ONCE(client->wbuf.wpos), ubuf, -+ n)) { -+ set_bit(SBEFIFO_XFR_CANCEL, &xfr->flags); -+ sbefifo_get(sbefifo); -+ if (mod_timer(&sbefifo->poll_timer, jiffies)) -+ sbefifo_put(sbefifo); -+ sbefifo_put_client(client); -+ return -EFAULT; -+ } -+ -+ ubuf += n; -+ } else { -+ memcpy(READ_ONCE(client->wbuf.wpos), kbuf, n); -+ kbuf += n; - } - - sbefifo_buf_wrotenb(&client->wbuf, n); - len -= n; -- buf += n; - ret += n; - - /* -@@ -685,6 +702,19 @@ static ssize_t sbefifo_write(struct file *file, const char __user *buf, - return ret; - } - -+static ssize_t sbefifo_write(struct file *file, const char __user *buf, -+ size_t len, loff_t *offset) -+{ -+ struct sbefifo_client *client = file->private_data; -+ -+ WARN_ON(*offset); -+ -+ if (!access_ok(VERIFY_READ, buf, len)) -+ return -EFAULT; -+ -+ return sbefifo_write_common(client, buf, NULL, len); -+} -+ - static int sbefifo_release(struct inode *inode, struct file *file) - { - struct sbefifo_client *client = file->private_data; -@@ -704,12 +734,68 @@ static int sbefifo_release(struct inode *inode, struct file *file) - .release = sbefifo_release, - }; - -+struct sbefifo_client *sbefifo_drv_open(struct device *dev, -+ unsigned long flags) -+{ -+ struct sbefifo_client *client = NULL; -+ struct sbefifo *sbefifo; -+ struct fsi_device *fsi_dev = to_fsi_dev(dev); -+ -+ list_for_each_entry(sbefifo, &sbefifo_fifos, link) { -+ if (sbefifo->fsi_dev != fsi_dev) -+ continue; -+ -+ client = sbefifo_new_client(sbefifo); -+ if (client) -+ client->f_flags = flags; -+ } -+ -+ return client; -+} -+EXPORT_SYMBOL_GPL(sbefifo_drv_open); -+ -+int sbefifo_drv_read(struct sbefifo_client *client, char *buf, size_t len) -+{ -+ return sbefifo_read_common(client, NULL, buf, len); -+} -+EXPORT_SYMBOL_GPL(sbefifo_drv_read); -+ -+int sbefifo_drv_write(struct sbefifo_client *client, const char *buf, -+ size_t len) -+{ -+ return sbefifo_write_common(client, NULL, buf, len); -+} -+EXPORT_SYMBOL_GPL(sbefifo_drv_write); -+ -+void sbefifo_drv_release(struct sbefifo_client *client) -+{ -+ if (!client) -+ return; -+ -+ sbefifo_put_client(client); -+} -+EXPORT_SYMBOL_GPL(sbefifo_drv_release); -+ -+static int sbefifo_unregister_child(struct device *dev, void *data) -+{ -+ struct platform_device *child = to_platform_device(dev); -+ -+ of_device_unregister(child); -+ if (dev->of_node) -+ of_node_clear_flag(dev->of_node, OF_POPULATED); -+ -+ return 0; -+} -+ - static int sbefifo_probe(struct device *dev) - { - struct fsi_device *fsi_dev = to_fsi_dev(dev); - struct sbefifo *sbefifo; -+ struct device_node *np; -+ struct platform_device *child; -+ char child_name[32]; - u32 sts; -- int ret; -+ int ret, child_idx = 0; - - dev_info(dev, "Found sbefifo device\n"); - sbefifo = kzalloc(sizeof(*sbefifo), GFP_KERNEL); -@@ -750,6 +836,18 @@ static int sbefifo_probe(struct device *dev) - init_waitqueue_head(&sbefifo->wait); - INIT_LIST_HEAD(&sbefifo->xfrs); - -+ if (dev->of_node) { -+ /* create platform devs for dts child nodes (occ, etc) */ -+ for_each_child_of_node(dev->of_node, np) { -+ snprintf(child_name, sizeof(child_name), "%s-dev%d", -+ sbefifo->name, child_idx++); -+ child = of_platform_device_create(np, child_name, dev); -+ if (!child) -+ dev_warn(&sbefifo->fsi_dev->dev, -+ "failed to create child node dev\n"); -+ } -+ } -+ - /* This bit of silicon doesn't offer any interrupts... */ - setup_timer(&sbefifo->poll_timer, sbefifo_poll_timer, - (unsigned long)sbefifo); -@@ -767,6 +865,9 @@ static int sbefifo_remove(struct device *dev) - list_for_each_entry_safe(sbefifo, sbefifo_tmp, &sbefifo_fifos, link) { - if (sbefifo->fsi_dev != fsi_dev) - continue; -+ -+ device_for_each_child(dev, NULL, sbefifo_unregister_child); -+ - misc_deregister(&sbefifo->mdev); - list_del(&sbefifo->link); - ida_simple_remove(&sbefifo_ida, sbefifo->idx); -diff --git a/include/linux/fsi-sbefifo.h b/include/linux/fsi-sbefifo.h -new file mode 100644 -index 0000000..1b46c63 ---- /dev/null -+++ b/include/linux/fsi-sbefifo.h -@@ -0,0 +1,30 @@ -+/* -+ * SBEFIFO FSI Client device driver -+ * -+ * Copyright (C) IBM Corporation 2017 -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERGCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __FSI_SBEFIFO_H__ -+#define __FSI_SBEFIFO_H__ -+ -+struct device; -+struct sbefifo_client; -+ -+extern struct sbefifo_client *sbefifo_drv_open(struct device *dev, -+ unsigned long flags); -+extern int sbefifo_drv_read(struct sbefifo_client *client, char *buf, -+ size_t len); -+extern int sbefifo_drv_write(struct sbefifo_client *client, const char *buf, -+ size_t len); -+extern void sbefifo_drv_release(struct sbefifo_client *client); -+ -+#endif /* __FSI_SBEFIFO_H__ */ |