summaryrefslogtreecommitdiff
path: root/meta-phosphor/common/recipes-kernel/linux/linux-obmc/linux-dev-4.10-1-3-drivers-fsi-sbefifo-Add-in-kernel-API.patch
diff options
context:
space:
mode:
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.patch338
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__ */