lkml.org 
[lkml]   [2011]   [Dec]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subject[PATCH 4/5] omap_hdq: handle case where isr sees a 0 status byte.
According to the documentation, when an isr happens one of the
3 bits in INT_STATUS must be set to say why.
But I sometimes see a value of zero.

The only explanation I can think of is that someone else reads the
register and so clears the bits. But I cannot find that someone.

So until we do, intuit what must have caused the interrupt.
If we were trying to write, assume it completed.
If we were trying to read and go something other than 0xFF,
assume the read completed.
If we read 0xFF, assume the read timed-out.

Signed-off-by: NeilBrown <neilb@suse.de>
---

drivers/w1/masters/omap_hdq.c | 26 +++++++++++++++++++++++++-
1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 848399b..6b82469 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -211,9 +211,33 @@ static irqreturn_t hdq_isr(int irq, void *_hdq)
{
struct hdq_data *hdq_data = _hdq;
unsigned long irqflags;
+ u8 status;

spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags);
- hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
+ status = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS);
+ if (!status) {
+ /* I sometimes see a zero status even though the read
+ * seems to have been successful. Very strange.
+ * But we did get an interrupt, so figure out what
+ * must have happened.
+ */
+ u8 ctrl = hdq_reg_in(hdq_data, OMAP_HDQ_CTRL_STATUS);
+ dev_dbg(hdq_data->dev, "hdr_isr: INT=0! CTRL=0x%02x\n", ctrl);
+ if (!(ctrl & OMAP_HDQ_CTRL_STATUS_GO)) {
+ /* It has definitely finished.. */
+ if (ctrl & OMAP_HDQ_CTRL_STATUS_DIR) {
+ /* A read finished or timed-out */
+ u8 data = hdq_reg_in(hdq_data,
+ OMAP_HDQ_RX_DATA);
+ if (data == 0xFF)
+ status = OMAP_HDQ_INT_STATUS_TIMEOUT;
+ else
+ status = OMAP_HDQ_INT_STATUS_RXCOMPLETE;
+ } else
+ status = OMAP_HDQ_INT_STATUS_TXCOMPLETE;
+ }
+ }
+ hdq_data->hdq_irqstatus = status;
spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags);
dev_dbg(hdq_data->dev, "hdq_isr: %x", hdq_data->hdq_irqstatus);




\
 
 \ /
  Last update: 2011-12-30 03:51    [W:0.088 / U:0.468 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site