All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alan Cox <alan-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 3/3] MID I2C runtime PM
Date: Tue, 25 Jan 2011 14:22:20 +0000	[thread overview]
Message-ID: <20110125142131.9472.27410.stgit@bob.linux.org.uk> (raw)
In-Reply-To: <20110125142040.9472.88734.stgit-Z/y2cZnRghHXmaaqVzeoHQ@public.gmane.org>

From: Bin Yang <bin.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

The MID I2C driver does now allow runtime pm by default it goes into
suspend after every access. This is not efficient for continual I2C access.

This patch allows auto suspend by default. It add a delay to the suspend which
keeps I2C active for at least 500ms after every access. If a device driver
accesses I2C frequently, it will not go to suspend and will keep high
performance. After a long time idle, it will go to suspend auto.

Signed-off-by: Bin Yang <bin.yang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
[Ported to upstream driver version]
Signed-off-by: Alan Cox <alan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---

 drivers/i2c/busses/i2c-intel-mid.c |   34 +++++++++++++++++++++++-----------
 1 files changed, 23 insertions(+), 11 deletions(-)


diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c
index 2dba2e3..3975736 100644
--- a/drivers/i2c/busses/i2c-intel-mid.c
+++ b/drivers/i2c/busses/i2c-intel-mid.c
@@ -753,7 +753,7 @@ static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
 	if (num == 0)
 		return 0;
 
-	pm_runtime_get(i2c->dev);
+	pm_runtime_get_sync(i2c->dev);
 
 	mutex_lock(&i2c->lock);
 	dev_dbg(&adap->dev, "intel_mid_i2c_xfer, process %d msg(s)\n", num);
@@ -763,9 +763,8 @@ static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
 	if (i2c->status != STATUS_IDLE) {
 		dev_err(&adap->dev, "Adapter %d in transfer/standby\n",
 								adap->nr);
-		mutex_unlock(&i2c->lock);
-		pm_runtime_put(i2c->dev);
-		return -1;
+		err = -EIO;
+		goto err_1;
 	}
 
 
@@ -773,16 +772,14 @@ static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
 		/* Message address equal? */
 		if (unlikely(intel_mid_i2c_address_neq(&pmsg[0], &pmsg[i]))) {
 			dev_err(&adap->dev, "Invalid address in msg[%d]\n", i);
-			mutex_unlock(&i2c->lock);
-			pm_runtime_put(i2c->dev);
-			return -EINVAL;
+			err = -EINVAL;
+			goto err_1;
 		}
 	}
 
 	if (intel_mid_i2c_setup(adap, pmsg)) {
-		mutex_unlock(&i2c->lock);
-		pm_runtime_put(i2c->dev);
-		return -EINVAL;
+		err = -EINVAL;
+		goto err_1;
 	}
 
 	for (i = 0; i < num; i++) {
@@ -808,6 +805,8 @@ static int intel_mid_i2c_xfer(struct i2c_adapter *adap,
 	readl(i2c->base + IC_CLR_INTR);
 
 	i2c->status = STATUS_IDLE;
+
+err_1:
 	mutex_unlock(&i2c->lock);
 	pm_runtime_put(i2c->dev);
 
@@ -865,6 +864,14 @@ static int intel_mid_i2c_runtime_resume(struct device *dev)
 	return err;
 }
 
+static int mrst_i2c_runtime_idle(struct device *dev)
+{
+	int err = pm_schedule_suspend(dev, 500);
+	if(err != 0)
+		return 0;
+	return -EBUSY;
+}
+
 static void i2c_isr_read(struct intel_mid_i2c_private *i2c)
 {
 	struct i2c_msg *msg = i2c->msg;
@@ -957,6 +964,7 @@ static struct i2c_algorithm intel_mid_i2c_algorithm = {
 static const struct dev_pm_ops intel_mid_i2c_pm_ops = {
 	.runtime_suspend = intel_mid_i2c_runtime_suspend,
 	.runtime_resume = intel_mid_i2c_runtime_resume,
+	.runtime_idle = mrst_i2c_runtime_idle,
 };
 
 /**
@@ -1094,7 +1102,10 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
 		(mrst->platform == MOORESTOWN) ? "Moorestown" : "Medfield",
 		busnum);
 
+	pm_runtime_set_active(&dev->dev);
 	pm_runtime_enable(&dev->dev);
+	pm_runtime_allow(&dev->dev);
+
 	return 0;
 
 fail3:
@@ -1113,10 +1124,11 @@ exit:
 static void __devexit intel_mid_i2c_remove(struct pci_dev *dev)
 {
 	struct intel_mid_i2c_private *mrst = pci_get_drvdata(dev);
+	pm_runtime_forbid(&dev->dev);
+	pm_runtime_disable(&dev->dev);
 	intel_mid_i2c_disable(&mrst->adap);
 	if (i2c_del_adapter(&mrst->adap))
 		dev_err(&dev->dev, "Failed to delete i2c adapter");
-
 	free_irq(dev->irq, mrst);
 	pci_set_drvdata(dev, NULL);
 	iounmap(mrst->base);

  parent reply	other threads:[~2011-01-25 14:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-25 14:20 [PATCH 1/3] i2c_intel_mid: Improve error reporting Alan Cox
     [not found] ` <20110125142040.9472.88734.stgit-Z/y2cZnRghHXmaaqVzeoHQ@public.gmane.org>
2011-01-25 14:21   ` [PATCH 2/3] i2c-intel-mid: improve timeout handling Alan Cox
2011-01-25 14:22   ` Alan Cox [this message]
2011-01-27  0:44   ` [PATCH 1/3] i2c_intel_mid: Improve error reporting Ben Dooks
     [not found]     ` <20110127004422.GI15795-SMNkleLxa3Z6Wcw2j4pizdi2O/JbrIOy@public.gmane.org>
2011-01-27 11:33       ` Alan Cox

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=20110125142131.9472.27410.stgit@bob.linux.org.uk \
    --to=alan-qbu/x9rampvanceybjwyrvxrex20p6io@public.gmane.org \
    --cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.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.