aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-i801.c
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2014-11-12 04:20:40 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-11-12 10:06:38 -0500
commitb3b8df97723d84c826d7419bf727a711a4efa068 (patch)
tree6764c08e2fe71343364fc916e287fdc3854277b6 /drivers/i2c/busses/i2c-i801.c
parent0285f8f5fd7cf7f458e13d9189eb735dacc244b5 (diff)
i2c: i801: Use wait_event_timeout to wait for interrupts
Some systems have been reported to have trouble with interrupts. Use wait_event_timeout() instead of wait_event() so we don't get stuck in that case, and log the problem. Signed-off-by: Jean Delvare <jdelvare@suse.de> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses/i2c-i801.c')
-rw-r--r--drivers/i2c/busses/i2c-i801.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 6ab4f1cb21f3..67661bbcbdd3 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -2,7 +2,7 @@
2 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, 2 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
3 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker 3 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
4 <mdsxyz123@yahoo.com> 4 <mdsxyz123@yahoo.com>
5 Copyright (C) 2007 - 2012 Jean Delvare <jdelvare@suse.de> 5 Copyright (C) 2007 - 2014 Jean Delvare <jdelvare@suse.de>
6 Copyright (C) 2010 Intel Corporation, 6 Copyright (C) 2010 Intel Corporation,
7 David Woodhouse <dwmw2@infradead.org> 7 David Woodhouse <dwmw2@infradead.org>
8 8
@@ -371,6 +371,7 @@ static int i801_transaction(struct i801_priv *priv, int xact)
371{ 371{
372 int status; 372 int status;
373 int result; 373 int result;
374 const struct i2c_adapter *adap = &priv->adapter;
374 375
375 result = i801_check_pre(priv); 376 result = i801_check_pre(priv);
376 if (result < 0) 377 if (result < 0)
@@ -379,7 +380,14 @@ static int i801_transaction(struct i801_priv *priv, int xact)
379 if (priv->features & FEATURE_IRQ) { 380 if (priv->features & FEATURE_IRQ) {
380 outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START, 381 outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
381 SMBHSTCNT(priv)); 382 SMBHSTCNT(priv));
382 wait_event(priv->waitq, (status = priv->status)); 383 result = wait_event_timeout(priv->waitq,
384 (status = priv->status),
385 adap->timeout);
386 if (!result) {
387 status = -ETIMEDOUT;
388 dev_warn(&priv->pci_dev->dev,
389 "Timeout waiting for interrupt!\n");
390 }
383 priv->status = 0; 391 priv->status = 0;
384 return i801_check_post(priv, status); 392 return i801_check_post(priv, status);
385 } 393 }
@@ -527,6 +535,7 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
527 int smbcmd; 535 int smbcmd;
528 int status; 536 int status;
529 int result; 537 int result;
538 const struct i2c_adapter *adap = &priv->adapter;
530 539
531 result = i801_check_pre(priv); 540 result = i801_check_pre(priv);
532 if (result < 0) 541 if (result < 0)
@@ -555,7 +564,14 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
555 priv->data = &data->block[1]; 564 priv->data = &data->block[1];
556 565
557 outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv)); 566 outb_p(priv->cmd | SMBHSTCNT_START, SMBHSTCNT(priv));
558 wait_event(priv->waitq, (status = priv->status)); 567 result = wait_event_timeout(priv->waitq,
568 (status = priv->status),
569 adap->timeout);
570 if (!result) {
571 status = -ETIMEDOUT;
572 dev_warn(&priv->pci_dev->dev,
573 "Timeout waiting for interrupt!\n");
574 }
559 priv->status = 0; 575 priv->status = 0;
560 return i801_check_post(priv, status); 576 return i801_check_post(priv, status);
561 } 577 }
@@ -1212,6 +1228,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
1212 outb_p(inb_p(SMBAUXCTL(priv)) & 1228 outb_p(inb_p(SMBAUXCTL(priv)) &
1213 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv)); 1229 ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
1214 1230
1231 /* Default timeout in interrupt mode: 200 ms */
1232 priv->adapter.timeout = HZ / 5;
1233
1215 if (priv->features & FEATURE_IRQ) { 1234 if (priv->features & FEATURE_IRQ) {
1216 init_waitqueue_head(&priv->waitq); 1235 init_waitqueue_head(&priv->waitq);
1217 1236