From: Hans de Goede <hdegoede@redhat.com>
To: Wolfram Sang <wsa@the-dreams.de>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>, linux-i2c@vger.kernel.org
Subject: [PATCH 2/3] i2c-cht-wc: Ack read irqs after reading the data register
Date: Mon, 14 Aug 2017 22:17:25 +0200 [thread overview]
Message-ID: <20170814201726.21045-3-hdegoede@redhat.com> (raw)
In-Reply-To: <20170814201726.21045-1-hdegoede@redhat.com>
Testing has shown that writing 1 to clear the read-complete irq does
not work until the data register has been read first.
This commit fixes the driver to read the data register first, halving the
amount of interrupts in most cases since we mostly read on this i2c bus.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/i2c/busses/i2c-cht-wc.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
index 09e0df49df6b..11f7e516f1b1 100644
--- a/drivers/i2c/busses/i2c-cht-wc.c
+++ b/drivers/i2c/busses/i2c-cht-wc.c
@@ -55,7 +55,8 @@ struct cht_wc_i2c_adap {
int client_irq;
u8 irq_mask;
u8 old_irq_mask;
- bool nack;
+ int read_data;
+ bool io_error;
bool done;
};
@@ -76,6 +77,11 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
reg &= ~adap->irq_mask;
+ /* Reads must be acked after reading the received data. */
+ ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, &adap->read_data);
+ if (ret)
+ adap->io_error = true;
+
/*
* Immediately ack IRQs, so that if new IRQs arrives while we're
* handling the previous ones our irq will re-trigger when we're done.
@@ -85,7 +91,7 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
dev_err(&adap->adapter.dev, "Error writing extchgrirq reg\n");
if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK) {
- adap->nack = !!(reg & CHT_WC_EXTCHGRIRQ_NACK_IRQ);
+ adap->io_error |= !!(reg & CHT_WC_EXTCHGRIRQ_NACK_IRQ);
adap->done = true;
}
@@ -125,10 +131,10 @@ static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
union i2c_smbus_data *data)
{
struct cht_wc_i2c_adap *adap = i2c_get_adapdata(_adap);
- int ret, reg;
+ int ret;
mutex_lock(&adap->adap_lock);
- adap->nack = false;
+ adap->io_error = false;
adap->done = false;
mutex_unlock(&adap->adap_lock);
@@ -159,12 +165,10 @@ static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
ret = 0;
mutex_lock(&adap->adap_lock);
- if (adap->nack)
+ if (adap->io_error)
ret = -EIO;
- else if (read_write == I2C_SMBUS_READ) {
- ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, ®);
- data->byte = reg;
- }
+ else if (read_write == I2C_SMBUS_READ)
+ data->byte = adap->read_data;
mutex_unlock(&adap->adap_lock);
return ret;
@@ -238,7 +242,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
.addr = 0x6b,
.properties = bq24190_props,
};
- int ret, irq;
+ int ret, reg, irq;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
@@ -264,6 +268,11 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
/* Clear and activate i2c-adapter interrupts, disable client IRQ */
adap->old_irq_mask = adap->irq_mask = ~CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK;
+
+ ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, ®);
+ if (ret)
+ return ret;
+
ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, ~adap->irq_mask);
if (ret)
return ret;
--
2.13.4
next prev parent reply other threads:[~2017-08-14 20:17 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-14 20:17 [PATCH 0/3] i2c-cht-wc: Various fixes Hans de Goede
2017-08-14 20:17 ` [PATCH 1/3] i2c-cht-wc: Add locking to interrupt / smbus_xfer functions Hans de Goede
2017-08-14 20:35 ` Andy Shevchenko
2017-08-14 20:55 ` Hans de Goede
2017-08-17 16:16 ` Wolfram Sang
2017-08-14 20:17 ` Hans de Goede [this message]
2017-08-17 16:16 ` [PATCH 2/3] i2c-cht-wc: Ack read irqs after reading the data register Wolfram Sang
2017-08-14 20:17 ` [PATCH 3/3] i2c-cht-wc: Workaround CHT GPIO controller IRQ issues Hans de Goede
2017-08-17 16:16 ` Wolfram Sang
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=20170814201726.21045-3-hdegoede@redhat.com \
--to=hdegoede@redhat.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=linux-i2c@vger.kernel.org \
--cc=wsa@the-dreams.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).