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 1/3] i2c-cht-wc: Add locking to interrupt / smbus_xfer functions
Date: Mon, 14 Aug 2017 22:17:24 +0200 [thread overview]
Message-ID: <20170814201726.21045-2-hdegoede@redhat.com> (raw)
In-Reply-To: <20170814201726.21045-1-hdegoede@redhat.com>
Although unlikely without locking the smbux_xfer function may miss
the nack flag and further fixes in this patch-set add some more
complex constructions which need protection.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
drivers/i2c/busses/i2c-cht-wc.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-cht-wc.c b/drivers/i2c/busses/i2c-cht-wc.c
index fe5caf70c7fe..09e0df49df6b 100644
--- a/drivers/i2c/busses/i2c-cht-wc.c
+++ b/drivers/i2c/busses/i2c-cht-wc.c
@@ -47,6 +47,7 @@ struct cht_wc_i2c_adap {
struct i2c_adapter adapter;
wait_queue_head_t wait;
struct irq_chip irqchip;
+ struct mutex adap_lock;
struct mutex irqchip_lock;
struct regmap *regmap;
struct irq_domain *irq_domain;
@@ -63,10 +64,13 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
struct cht_wc_i2c_adap *adap = data;
int ret, reg;
+ mutex_lock(&adap->adap_lock);
+
/* Read IRQs */
ret = regmap_read(adap->regmap, CHT_WC_EXTCHGRIRQ, ®);
if (ret) {
dev_err(&adap->adapter.dev, "Error reading extchgrirq reg\n");
+ mutex_unlock(&adap->adap_lock);
return IRQ_NONE;
}
@@ -80,6 +84,16 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
if (ret)
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->done = true;
+ }
+
+ mutex_unlock(&adap->adap_lock);
+
+ if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK)
+ wake_up(&adap->wait);
+
/*
* Do NOT use handle_nested_irq here, the client irq handler will
* likely want to do i2c transfers and the i2c controller uses this
@@ -96,12 +110,6 @@ static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
local_irq_enable();
}
- if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK) {
- adap->nack = !!(reg & CHT_WC_EXTCHGRIRQ_NACK_IRQ);
- adap->done = true;
- wake_up(&adap->wait);
- }
-
return IRQ_HANDLED;
}
@@ -119,8 +127,10 @@ static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
struct cht_wc_i2c_adap *adap = i2c_get_adapdata(_adap);
int ret, reg;
+ mutex_lock(&adap->adap_lock);
adap->nack = false;
adap->done = false;
+ mutex_unlock(&adap->adap_lock);
ret = regmap_write(adap->regmap, CHT_WC_I2C_CLIENT_ADDR, addr);
if (ret)
@@ -146,18 +156,18 @@ static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
ret = wait_event_timeout(adap->wait, adap->done, 3 * HZ);
if (ret == 0)
return -ETIMEDOUT;
- if (adap->nack)
- return -EIO;
- if (read_write == I2C_SMBUS_READ) {
+ ret = 0;
+ mutex_lock(&adap->adap_lock);
+ if (adap->nack)
+ ret = -EIO;
+ else if (read_write == I2C_SMBUS_READ) {
ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, ®);
- if (ret)
- return ret;
-
data->byte = reg;
}
+ mutex_unlock(&adap->adap_lock);
- return 0;
+ return ret;
}
static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
@@ -241,6 +251,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
return -ENOMEM;
init_waitqueue_head(&adap->wait);
+ mutex_init(&adap->adap_lock);
mutex_init(&adap->irqchip_lock);
adap->irqchip = cht_wc_i2c_irq_chip;
adap->regmap = pmic->regmap;
--
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 ` Hans de Goede [this message]
2017-08-14 20:35 ` [PATCH 1/3] i2c-cht-wc: Add locking to interrupt / smbus_xfer functions Andy Shevchenko
2017-08-14 20:55 ` Hans de Goede
2017-08-17 16:16 ` Wolfram Sang
2017-08-14 20:17 ` [PATCH 2/3] i2c-cht-wc: Ack read irqs after reading the data register Hans de Goede
2017-08-17 16:16 ` 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-2-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).