summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorDavid Schalig <dschalig@nvidia.com>2011-12-14 16:01:30 +0900
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-22 11:32:03 +0530
commit1cdb02ea9f18af3a810d50fe1370bd744fe37537 (patch)
tree7e37e3b215c6cdb646af164c85679b9e43809023 /drivers/mfd
parent51a3974d0c5272ce8ab48d3370dd3debe76747e8 (diff)
mfd: tps80031: fix irq status clear sequence
According to tps80031 datasheet, all 3 interrupt status registers should be read, before writing to clear them. The old code used interleaved status read/clear, which may drop interrupts. Bug 914740 Change-Id: I4c9c0b7c623ea0fe01d90e9a531ff2e9d34f125c Signed-off-by: David Schalig <dschalig@nvidia.com> Reviewed-on: http://git-master/r/69941 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/tps80031.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c
index 6fe80dc51931..e6bfd475f668 100644
--- a/drivers/mfd/tps80031.c
+++ b/drivers/mfd/tps80031.c
@@ -801,35 +801,35 @@ static irqreturn_t tps80031_irq(int irq, void *data)
{
struct tps80031 *tps80031 = data;
int ret = 0;
- u8 tmp[3];
u32 acks;
int i;
+ uint8_t tmp[3];
- for (i = 0; i < 3; i++) {
- ret = tps80031_read(tps80031->dev, SLAVE_ID2,
- TPS80031_INT_STS_A + i, &tmp[i]);
+ ret = tps80031_reads(tps80031->dev, SLAVE_ID2,
+ TPS80031_INT_STS_A, 3, tmp);
+ if (ret < 0) {
+ dev_err(tps80031->dev, "failed to read interrupt status\n");
+ return IRQ_NONE;
+ }
+ acks = (tmp[2] << 16) | (tmp[1] << 8) | tmp[0];
+
+ if (acks) {
+ ret = tps80031_writes(tps80031->dev, SLAVE_ID2,
+ TPS80031_INT_STS_A, 3, tmp);
if (ret < 0) {
- dev_err(tps80031->dev, "failed to read interrupt "
- "status\n");
+ dev_err(tps80031->dev, "failed to write "
+ "interrupt status\n");
return IRQ_NONE;
}
- if (tmp[i]) {
- ret = tps80031_write(tps80031->dev, SLAVE_ID2,
- TPS80031_INT_STS_A + i, tmp[i]);
- if (ret < 0) {
- dev_err(tps80031->dev, "failed to write "
- "interrupt status\n");
- return IRQ_NONE;
- }
+
+ while (acks) {
+ i = __ffs(acks);
+ if (tps80031->irq_en & (1 << i))
+ handle_nested_irq(tps80031->irq_base + i);
+ acks &= ~(1 << i);
}
}
- acks = (tmp[2] << 16) | (tmp[1] << 8) | tmp[0];
- while (acks) {
- i = __ffs(acks);
- if (tps80031->irq_en & (1 << i))
- handle_nested_irq(tps80031->irq_base + i);
- acks &= ~(1 << i);
- }
+
return IRQ_HANDLED;
}