From: Andres Salomon <dilinger@queued.net>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Paul Fox <pgf@laptop.org>, Daniel Drake <dsd@laptop.org>,
"Richard A. Smith" <richard@laptop.org>,
linux-kernel@vger.kernel.org, libertas-dev@lists.infradead.org,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
platform-driver-x86@vger.kernel.org, devel@driverdev.osuosl.org,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
x86@kernel.org, Dan Williams <dcbw@redhat.com>,
"John W. Linville" <linville@tuxdriver.com>,
Matthew Garrett <mjg@redhat.com>, Anton Vorontsov <cbou@mail.ru>,
David Woodhouse <dwmw2@infradead.org>,
Chris Ball <cjb@laptop.org>,
Jon Nettleton <jon.nettleton@gmail.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: [PATCH 5/9] Platform: OLPC: add a suspended flag to the EC driver
Date: Wed, 18 Jul 2012 21:28:24 -0700 [thread overview]
Message-ID: <20120718212824.70ee6466@dev.queued.net> (raw)
In-Reply-To: <20120718182144.2d7b0b50@dev.queued.net>
A problem we've noticed on XO-1.75 is when we suspend in the middle of
an EC command. Don't allow that.
In the process, create a private object for the generic EC driver to
use; we have a framework for passing around a struct, use that rather
than a proliferation of global variables.
Signed-off-by: Andres Salomon <dilinger@queued.net>
---
drivers/platform/olpc/olpc-ec.c | 46
++++++++++++++++++++++++++++++++++++++- 1 files changed, 45
insertions(+), 1 deletions(-)
diff --git a/drivers/platform/olpc/olpc-ec.c
b/drivers/platform/olpc/olpc-ec.c index d00523c..cfba41f 100644
--- a/drivers/platform/olpc/olpc-ec.c
+++ b/drivers/platform/olpc/olpc-ec.c
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/list.h>
@@ -27,6 +28,21 @@ struct ec_cmd_desc {
void *priv;
};
+struct olpc_ec_priv {
+ struct olpc_ec_driver *drv;
+
+ /*
+ * Running an EC command while suspending means we don't
always finish
+ * the command before the machine suspends. This means that
the EC
+ * is expecting the command protocol to finish, but we after a
period
+ * of time (while the OS is asleep) the EC times out and
restarts its
+ * idle loop. Meanwhile, the OS wakes up, thinks it's still
in the
+ * middle of the command protocol, starts throwing random
things at
+ * the EC... and everyone's uphappy.
+ */
+ bool suspended;
+};
+
static void olpc_ec_worker(struct work_struct *w);
static DECLARE_WORK(ec_worker, olpc_ec_worker);
@@ -34,6 +50,7 @@ static LIST_HEAD(ec_cmd_q);
static DEFINE_SPINLOCK(ec_cmd_q_lock);
static struct olpc_ec_driver *ec_driver;
+static struct olpc_ec_priv *ec_priv;
static void *ec_cb_arg;
static DEFINE_MUTEX(ec_cb_lock);
@@ -93,6 +110,7 @@ static void queue_ec_descriptor(struct ec_cmd_desc
*desc)
int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, size_t
outlen) {
+ struct olpc_ec_priv *ec = ec_priv;
struct ec_cmd_desc desc;
/* XXX: this will be removed in later patches */
@@ -104,6 +122,13 @@ int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen,
u8 *outbuf, size_t outlen) if (WARN_ON(!ec_driver
|| !ec_driver->ec_cmd)) return -ENODEV;
+ if (!ec)
+ return -ENOMEM;
+
+ /* Suspending in the middle of a command hoses things really
badly */
+ if (WARN_ON(ec->suspended))
+ return -EBUSY;
+
might_sleep();
desc.cmd = cmd;
@@ -126,11 +151,19 @@ EXPORT_SYMBOL_GPL(olpc_ec_cmd);
static int olpc_ec_probe(struct platform_device *pdev)
{
+ struct olpc_ec_priv *ec;
int err;
if (!ec_driver)
return -ENODEV;
+ ec = kzalloc(sizeof(*ec), GFP_KERNEL);
+ if (!ec)
+ return -ENOMEM;
+ ec->drv = ec_driver;
+ ec_priv = ec;
+ platform_set_drvdata(pdev, ec);
+
err = ec_driver->probe ? ec_driver->probe(pdev) : 0;
return err;
@@ -139,12 +172,23 @@ static int olpc_ec_probe(struct platform_device
*pdev) static int olpc_ec_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- return ec_driver->suspend ? ec_driver->suspend(pdev) : 0;
+ struct olpc_ec_priv *ec = platform_get_drvdata(pdev);
+ int err = 0;
+
+ if (ec_driver->suspend)
+ err = ec_driver->suspend(pdev);
+ if (!err)
+ ec->suspended = true;
+
+ return err;
}
static int olpc_ec_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
+ struct olpc_ec_priv *ec = platform_get_drvdata(pdev);
+
+ ec->suspended = false;
return ec_driver->resume ? ec_driver->resume(pdev) : 0;
}
--
1.7.2.5
WARNING: multiple messages have this Message-ID (diff)
From: Andres Salomon <dilinger@queued.net>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: devel@driverdev.osuosl.org, Daniel Drake <dsd@laptop.org>,
libertas-dev@lists.infradead.org, Dan Williams <dcbw@redhat.com>,
netdev@vger.kernel.org, Jon Nettleton <jon.nettleton@gmail.com>,
x86@kernel.org, linux-wireless@vger.kernel.org,
linux-kernel@vger.kernel.org,
platform-driver-x86@vger.kernel.org,
"Richard A. Smith" <richard@laptop.org>,
Paul Fox <pgf@laptop.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Anton Vorontsov <cbou@mail.ru>, "H. Peter Anvin" <hpa@zytor.com>,
Thomas Gleixner <tglx@linutronix.de>, Chris Ball <cjb@laptop.org>,
David Woodhouse <dwmw2@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
"John W. Linville" <linville@tuxdriver.com>,
Matthew Garrett <mjg@redhat.com>
Subject: [PATCH 5/9] Platform: OLPC: add a suspended flag to the EC driver
Date: Wed, 18 Jul 2012 21:28:24 -0700 [thread overview]
Message-ID: <20120718212824.70ee6466@dev.queued.net> (raw)
In-Reply-To: <20120718182144.2d7b0b50@dev.queued.net>
A problem we've noticed on XO-1.75 is when we suspend in the middle of
an EC command. Don't allow that.
In the process, create a private object for the generic EC driver to
use; we have a framework for passing around a struct, use that rather
than a proliferation of global variables.
Signed-off-by: Andres Salomon <dilinger@queued.net>
---
drivers/platform/olpc/olpc-ec.c | 46
++++++++++++++++++++++++++++++++++++++- 1 files changed, 45
insertions(+), 1 deletions(-)
diff --git a/drivers/platform/olpc/olpc-ec.c
b/drivers/platform/olpc/olpc-ec.c index d00523c..cfba41f 100644
--- a/drivers/platform/olpc/olpc-ec.c
+++ b/drivers/platform/olpc/olpc-ec.c
@@ -9,6 +9,7 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/list.h>
@@ -27,6 +28,21 @@ struct ec_cmd_desc {
void *priv;
};
+struct olpc_ec_priv {
+ struct olpc_ec_driver *drv;
+
+ /*
+ * Running an EC command while suspending means we don't
always finish
+ * the command before the machine suspends. This means that
the EC
+ * is expecting the command protocol to finish, but we after a
period
+ * of time (while the OS is asleep) the EC times out and
restarts its
+ * idle loop. Meanwhile, the OS wakes up, thinks it's still
in the
+ * middle of the command protocol, starts throwing random
things at
+ * the EC... and everyone's uphappy.
+ */
+ bool suspended;
+};
+
static void olpc_ec_worker(struct work_struct *w);
static DECLARE_WORK(ec_worker, olpc_ec_worker);
@@ -34,6 +50,7 @@ static LIST_HEAD(ec_cmd_q);
static DEFINE_SPINLOCK(ec_cmd_q_lock);
static struct olpc_ec_driver *ec_driver;
+static struct olpc_ec_priv *ec_priv;
static void *ec_cb_arg;
static DEFINE_MUTEX(ec_cb_lock);
@@ -93,6 +110,7 @@ static void queue_ec_descriptor(struct ec_cmd_desc
*desc)
int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, size_t
outlen) {
+ struct olpc_ec_priv *ec = ec_priv;
struct ec_cmd_desc desc;
/* XXX: this will be removed in later patches */
@@ -104,6 +122,13 @@ int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen,
u8 *outbuf, size_t outlen) if (WARN_ON(!ec_driver
|| !ec_driver->ec_cmd)) return -ENODEV;
+ if (!ec)
+ return -ENOMEM;
+
+ /* Suspending in the middle of a command hoses things really
badly */
+ if (WARN_ON(ec->suspended))
+ return -EBUSY;
+
might_sleep();
desc.cmd = cmd;
@@ -126,11 +151,19 @@ EXPORT_SYMBOL_GPL(olpc_ec_cmd);
static int olpc_ec_probe(struct platform_device *pdev)
{
+ struct olpc_ec_priv *ec;
int err;
if (!ec_driver)
return -ENODEV;
+ ec = kzalloc(sizeof(*ec), GFP_KERNEL);
+ if (!ec)
+ return -ENOMEM;
+ ec->drv = ec_driver;
+ ec_priv = ec;
+ platform_set_drvdata(pdev, ec);
+
err = ec_driver->probe ? ec_driver->probe(pdev) : 0;
return err;
@@ -139,12 +172,23 @@ static int olpc_ec_probe(struct platform_device
*pdev) static int olpc_ec_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
- return ec_driver->suspend ? ec_driver->suspend(pdev) : 0;
+ struct olpc_ec_priv *ec = platform_get_drvdata(pdev);
+ int err = 0;
+
+ if (ec_driver->suspend)
+ err = ec_driver->suspend(pdev);
+ if (!err)
+ ec->suspended = true;
+
+ return err;
}
static int olpc_ec_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
+ struct olpc_ec_priv *ec = platform_get_drvdata(pdev);
+
+ ec->suspended = false;
return ec_driver->resume ? ec_driver->resume(pdev) : 0;
}
--
1.7.2.5
next prev parent reply other threads:[~2012-07-19 4:28 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-19 1:21 [PATCH 0/9] OLPC: create a generic OLPC EC driver Andres Salomon
2012-07-19 1:25 ` [PATCH 1/9] Platform: OLPC: add a stub to drivers/platform/ for the " Andres Salomon
2012-07-19 1:26 ` [PATCH 2/9] drivers: OLPC: update various drivers to include olpc-ec.h Andres Salomon
2012-07-19 1:26 ` [PATCH 3/9] Platform: OLPC: allow EC cmd to be overridden, and create a workqueue to call it Andres Salomon
2012-07-19 1:27 ` [PATCH 4/9] Platform: OLPC: turn EC driver into a platform_driver Andres Salomon
2012-07-19 1:29 ` [PATCH 5/9] Platform: OLPC: add a suspended flag to the EC driver Andres Salomon
2012-07-19 1:31 ` [PATCH 6/9] x86: OLPC: switch over to using new EC driver on x86 Andres Salomon
2012-07-19 1:31 ` [PATCH 7/9] Platform: OLPC: move debugfs support from x86 EC driver Andres Salomon
2012-07-19 1:32 ` [PATCH 8/9] Platform: OLPC: move global variables into priv struct Andres Salomon
2012-07-19 1:32 ` [PATCH 9/9] x86: OLPC: move s/r-related EC cmds to EC driver Andres Salomon
2012-07-19 4:26 ` [PATCH 1/9] Platform: OLPC: add a stub to drivers/platform/ for the OLPC " Andres Salomon
2012-07-19 4:26 ` [PATCH 2/9] drivers: OLPC: update various drivers to include olpc-ec.h Andres Salomon
2012-07-19 4:28 ` [PATCH 3/9] Platform: OLPC: allow EC cmd to be overridden, and create a workqueue to call it Andres Salomon
2012-07-19 4:28 ` Andres Salomon
2012-07-19 4:28 ` [PATCH 4/9] Platform: OLPC: turn EC driver into a platform_driver Andres Salomon
2012-07-19 4:28 ` Andres Salomon
2012-07-19 4:28 ` Andres Salomon [this message]
2012-07-19 4:28 ` [PATCH 5/9] Platform: OLPC: add a suspended flag to the EC driver Andres Salomon
2012-07-19 4:28 ` [PATCH 6/9] x86: OLPC: switch over to using new EC driver on x86 Andres Salomon
2012-07-19 4:28 ` Andres Salomon
2012-07-19 4:36 ` Andres Salomon
2012-07-19 4:28 ` [PATCH 7/9] Platform: OLPC: move debugfs support from x86 EC driver Andres Salomon
2012-07-19 4:28 ` Andres Salomon
2012-07-19 4:29 ` [PATCH 8/9] Platform: OLPC: move global variables into priv struct Andres Salomon
2012-07-19 4:29 ` Andres Salomon
2012-07-19 4:29 ` [PATCH 9/9] x86: OLPC: move s/r-related EC cmds to EC driver Andres Salomon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120718212824.70ee6466@dev.queued.net \
--to=dilinger@queued.net \
--cc=akpm@linux-foundation.org \
--cc=cbou@mail.ru \
--cc=cjb@laptop.org \
--cc=dcbw@redhat.com \
--cc=devel@driverdev.osuosl.org \
--cc=dsd@laptop.org \
--cc=dwmw2@infradead.org \
--cc=gregkh@linuxfoundation.org \
--cc=hpa@zytor.com \
--cc=jon.nettleton@gmail.com \
--cc=libertas-dev@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=mingo@redhat.com \
--cc=mjg@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pgf@laptop.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=richard@laptop.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.