mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
gpio: Prevent an integer overflow in the pca953x driver
Interrupts were missed if an 8-bit integer overflow occurred. This was observed when bank0,pin7 and bank1,pin7 changed simultaniously. As the 8-bit totals were only checked against zero, replace them with booleans. Name the booleans so that their purpose is clear. Signed-off-by: Joshua Scott <joshua.scott@alliedtelesis.co.nz> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
121dcb7604
commit
b6ac1280b6
@ -443,12 +443,13 @@ static struct irq_chip pca953x_irq_chip = {
|
|||||||
.irq_set_type = pca953x_irq_set_type,
|
.irq_set_type = pca953x_irq_set_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
static u8 pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
|
static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
|
||||||
{
|
{
|
||||||
u8 cur_stat[MAX_BANK];
|
u8 cur_stat[MAX_BANK];
|
||||||
u8 old_stat[MAX_BANK];
|
u8 old_stat[MAX_BANK];
|
||||||
u8 pendings = 0;
|
bool pending_seen = false;
|
||||||
u8 trigger[MAX_BANK], triggers = 0;
|
bool trigger_seen = false;
|
||||||
|
u8 trigger[MAX_BANK];
|
||||||
int ret, i, offset = 0;
|
int ret, i, offset = 0;
|
||||||
|
|
||||||
switch (chip->chip_type) {
|
switch (chip->chip_type) {
|
||||||
@ -461,7 +462,7 @@ static u8 pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
|
|||||||
}
|
}
|
||||||
ret = pca953x_read_regs(chip, offset, cur_stat);
|
ret = pca953x_read_regs(chip, offset, cur_stat);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
/* Remove output pins from the equation */
|
/* Remove output pins from the equation */
|
||||||
for (i = 0; i < NBANK(chip); i++)
|
for (i = 0; i < NBANK(chip); i++)
|
||||||
@ -471,11 +472,12 @@ static u8 pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
|
|||||||
|
|
||||||
for (i = 0; i < NBANK(chip); i++) {
|
for (i = 0; i < NBANK(chip); i++) {
|
||||||
trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i];
|
trigger[i] = (cur_stat[i] ^ old_stat[i]) & chip->irq_mask[i];
|
||||||
triggers += trigger[i];
|
if (trigger[i])
|
||||||
|
trigger_seen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!triggers)
|
if (!trigger_seen)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
memcpy(chip->irq_stat, cur_stat, NBANK(chip));
|
memcpy(chip->irq_stat, cur_stat, NBANK(chip));
|
||||||
|
|
||||||
@ -483,10 +485,11 @@ static u8 pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
|
|||||||
pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) |
|
pending[i] = (old_stat[i] & chip->irq_trig_fall[i]) |
|
||||||
(cur_stat[i] & chip->irq_trig_raise[i]);
|
(cur_stat[i] & chip->irq_trig_raise[i]);
|
||||||
pending[i] &= trigger[i];
|
pending[i] &= trigger[i];
|
||||||
pendings += pending[i];
|
if (pending[i])
|
||||||
|
pending_seen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pendings;
|
return pending_seen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t pca953x_irq_handler(int irq, void *devid)
|
static irqreturn_t pca953x_irq_handler(int irq, void *devid)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user