diff options
author | Jean Delvare <jdelvare@suse.de> | 2014-11-12 04:20:40 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2014-11-12 10:06:38 -0500 |
commit | b3b8df97723d84c826d7419bf727a711a4efa068 (patch) | |
tree | 6764c08e2fe71343364fc916e287fdc3854277b6 /drivers/i2c/busses/i2c-i801.c | |
parent | 0285f8f5fd7cf7f458e13d9189eb735dacc244b5 (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.c | 25 |
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 | ||