diff options
author | Steve Kuo <stevek@nvidia.com> | 2012-03-30 15:00:38 +0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2012-05-03 19:25:01 -0700 |
commit | d5252b48f3c2c0a4be383311cae25752bcdc07b7 (patch) | |
tree | 6532ed16cadbd234cb38628876bf4896898eaf99 /drivers/mfd | |
parent | f16614d48a3025789df16d1d060efd581933f198 (diff) |
mfd: tps80031: fix missed irq issue
We found missed irq could be happened if clear all INT_STS_x register in one time.
Shadow register pushes the irq status after the first byte of INT_STS_x was cleared
The proposed way to clear interrupt is to write only one INT_STS_x register.
It will also clear the other two ones.
Bug 952476
Reviewed-on: http://git-master/r/93453
Signed-off-by: Steve Kuo <stevek@nvidia.com>
(cherry picked from commit 0c92f32e9e03defaeac991518b26134e59ef4db6)
Change-Id: I76179be4847f59a1687926b9b0dde6ebd3f58aa4
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/100306
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/tps80031.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index e8ea75c424c6..94ba777bcdb3 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c @@ -874,8 +874,22 @@ static irqreturn_t tps80031_irq(int irq, void *data) acks = (tmp[2] << 16) | (tmp[1] << 8) | tmp[0]; if (acks) { - ret = tps80031_writes(tps80031->dev, SLAVE_ID2, - TPS80031_INT_STS_A, 3, tmp); + /* + * Hardware behavior: hardware have the shadow register for + * interrupt status register which is updated if interrupt + * comes just after the interrupt status read. This shadow + * register gets written to main status register and cleared + * if any byte write happens in any of status register like + * STS_A, STS_B or STS_C. + * Hence here to clear the original interrupt status and + * updating the STS register with the shadow register, it is + * require to write only one byte in any of STS register. + * Having multiple register write can cause the STS register + * to clear without handling those interrupt and can cause + * interrupt miss. + */ + ret = tps80031_write(tps80031->dev, SLAVE_ID2, + TPS80031_INT_STS_A, 0); if (ret < 0) { dev_err(tps80031->dev, "failed to write " "interrupt status\n"); |