diff options
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.patch | 151 |
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 + |