summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0101-Add-poll-fops-in-eSPI-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0101-Add-poll-fops-in-eSPI-driver.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0101-Add-poll-fops-in-eSPI-driver.patch151
1 files changed, 151 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0101-Add-poll-fops-in-eSPI-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0101-Add-poll-fops-in-eSPI-driver.patch
new file mode 100644
index 000000000..b4118e169
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0101-Add-poll-fops-in-eSPI-driver.patch
@@ -0,0 +1,151 @@
+From 9479d8f12efc845faca4bb1aef9b6e63799a7e5c Mon Sep 17 00:00:00 2001
+From: "Arun P. Mohanan" <arun.p.m@linux.intel.com>
+Date: Wed, 18 Mar 2020 08:34:43 +0530
+Subject: [PATCH] Add poll fops in eSPI driver
+
+Modify eSPI driver to support poll fops.
+
+Signed-off-by: Arun P. Mohanan <arun.p.m@linux.intel.com>
+---
+ drivers/misc/aspeed-espi-slave.c | 85 +++++++++++++++++++++++---------
+ 1 file changed, 61 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/misc/aspeed-espi-slave.c b/drivers/misc/aspeed-espi-slave.c
+index 87bc81948694..cb8ed585c69f 100644
+--- a/drivers/misc/aspeed-espi-slave.c
++++ b/drivers/misc/aspeed-espi-slave.c
+@@ -9,6 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
++#include <linux/poll.h>
+ #include <linux/regmap.h>
+ #include <linux/reset.h>
+ #include <linux/sched/signal.h>
+@@ -95,6 +96,7 @@ struct aspeed_espi {
+ spinlock_t pltrstn_lock; /* for PLTRST_N signal sampling */
+ wait_queue_head_t pltrstn_waitq;
+ char pltrstn;
++ bool pltrstn_in_avail;
+ };
+
+ static void aspeed_espi_sys_event(struct aspeed_espi *priv)
+@@ -127,7 +129,10 @@ static void aspeed_espi_sys_event(struct aspeed_espi *priv)
+ dev_dbg(priv->dev, "SYSEVT_OOB_RST_WARN: acked\n");
+ }
+ if (sts & ASPEED_ESPI_SYSEVT_PLTRSTN || priv->pltrstn == 'U') {
++ spin_lock(&priv->pltrstn_lock);
+ priv->pltrstn = (evt & ASPEED_ESPI_SYSEVT_PLTRSTN) ? '1' : '0';
++ priv->pltrstn_in_avail = true;
++ spin_unlock(&priv->pltrstn_lock);
+ wake_up_interruptible(&priv->pltrstn_waitq);
+ dev_dbg(priv->dev, "SYSEVT_PLTRSTN: %c\n", priv->pltrstn);
+ }
+@@ -269,6 +274,8 @@ static int aspeed_espi_pltrstn_open(struct inode *inode, struct file *filp)
+ {
+ if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+ return -EACCES;
++ struct aspeed_espi *priv = to_aspeed_espi(filp);
++ priv->pltrstn_in_avail = true ; /*Setting true returns first data after file open*/
+
+ return 0;
+ }
+@@ -284,41 +291,71 @@ static ssize_t aspeed_espi_pltrstn_read(struct file *filp, char __user *buf,
+
+ spin_lock_irqsave(&priv->pltrstn_lock, flags);
+
+- add_wait_queue(&priv->pltrstn_waitq, &wait);
+- set_current_state(TASK_INTERRUPTIBLE);
+-
+- old_sample = priv->pltrstn;
+-
+- do {
+- char new_sample = priv->pltrstn;
+-
+- if (filp->f_flags & O_NONBLOCK || old_sample != new_sample) {
+- ret = put_user(new_sample, (unsigned long __user *)buf);
+- if (!ret)
+- ret = sizeof(new_sample);
+- } else if (signal_pending(current)) {
+- ret = -ERESTARTSYS;
++ if (filp->f_flags & O_NONBLOCK) {
++ if (!priv->pltrstn_in_avail) {
++ ret = -EAGAIN;
++ goto out_unlock;
+ }
+-
+- if (!ret) {
+- spin_unlock_irqrestore(&priv->pltrstn_lock, flags);
+- schedule();
+- spin_lock_irqsave(&priv->pltrstn_lock, flags);
++ char data = priv->pltrstn;
++ ret = put_user(data, (unsigned long __user *)buf);
++ if (!ret){
++ ret = sizeof(data);
++ } else{
++ ret = -EAGAIN;
+ }
+- } while (!ret);
+-
+- remove_wait_queue(&priv->pltrstn_waitq, &wait);
+- set_current_state(TASK_RUNNING);
+-
++ priv->pltrstn_in_avail = false;
++ } else {
++ add_wait_queue(&priv->pltrstn_waitq, &wait);
++ set_current_state(TASK_INTERRUPTIBLE);
++
++ old_sample = priv->pltrstn;
++
++ do {
++ char new_sample = priv->pltrstn;
++
++ if (old_sample != new_sample) {
++ ret = put_user(new_sample,
++ (unsigned long __user *)buf);
++ if (!ret)
++ ret = sizeof(new_sample);
++ } else if (signal_pending(current)) {
++ ret = -ERESTARTSYS;
++ }
++
++ if (!ret) {
++ spin_unlock_irqrestore(&priv->pltrstn_lock,
++ flags);
++ schedule();
++ spin_lock_irqsave(&priv->pltrstn_lock, flags);
++ }
++ } while (!ret);
++
++ remove_wait_queue(&priv->pltrstn_waitq, &wait);
++ set_current_state(TASK_RUNNING);
++ }
++out_unlock:
+ spin_unlock_irqrestore(&priv->pltrstn_lock, flags);
+
+ return ret;
+ }
+
++static unsigned int aspeed_espi_pltrstn_poll(struct file *file,
++ poll_table *wait)
++{
++ struct aspeed_espi *priv = to_aspeed_espi(file);
++ unsigned int mask = 0;
++ poll_wait(file, &priv->pltrstn_waitq, wait);
++
++ if (priv->pltrstn_in_avail)
++ mask |= POLLIN;
++ return mask;
++}
++
+ static const struct file_operations aspeed_espi_pltrstn_fops = {
+ .owner = THIS_MODULE,
+ .open = aspeed_espi_pltrstn_open,
+ .read = aspeed_espi_pltrstn_read,
++ .poll = aspeed_espi_pltrstn_poll,
+ };
+
+ static const struct regmap_config aspeed_espi_regmap_cfg = {
+--
+2.17.1
+