All of lore.kernel.org
 help / color / mirror / Atom feed
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 18:29:16 -0700	[thread overview]
Message-ID: <20120718182916.59dd3b6a@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

  parent reply	other threads:[~2012-07-19  1:29 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 ` Andres Salomon [this message]
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 ` [PATCH 5/9] Platform: OLPC: add a suspended flag to the EC driver Andres Salomon
2012-07-19  4:28   ` 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=20120718182916.59dd3b6a@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.