]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch
Linux 4.14.108
[thirdparty/kernel/stable-queue.git] / queue-4.19 / gpio-pca953x-fix-dereference-of-irq-data-in-shutdown.patch
1 From c378b3aa015931a46c91d6ccc2fe04d97801d060 Mon Sep 17 00:00:00 2001
2 From: Mark Walton <mark.walton@serialtek.com>
3 Date: Thu, 28 Feb 2019 15:46:36 +0000
4 Subject: gpio: pca953x: Fix dereference of irq data in shutdown
5
6 From: Mark Walton <mark.walton@serialtek.com>
7
8 commit c378b3aa015931a46c91d6ccc2fe04d97801d060 upstream.
9
10 If a PCA953x gpio was used as an interrupt and then released,
11 the shutdown function was trying to extract the pca953x_chip
12 pointer directly from the irq_data, but in reality was getting
13 the gpio_chip structure.
14
15 The net effect was that the subsequent writes to the data
16 structure corrupted data in the gpio_chip structure, which wasn't
17 immediately obvious until attempting to use the GPIO again in the
18 future, at which point the kernel panics.
19
20 This fix correctly extracts the pca953x_chip structure via the
21 gpio_chip structure, as is correctly done in the other irq
22 functions.
23
24 Fixes: 0a70fe00efea ("gpio: pca953x: Clear irq trigger type on irq shutdown")
25 Cc: stable@vger.kernel.org
26 Signed-off-by: Mark Walton <mark.walton@serialtek.com>
27 Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
28 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30
31 ---
32 drivers/gpio/gpio-pca953x.c | 3 ++-
33 1 file changed, 2 insertions(+), 1 deletion(-)
34
35 --- a/drivers/gpio/gpio-pca953x.c
36 +++ b/drivers/gpio/gpio-pca953x.c
37 @@ -543,7 +543,8 @@ static int pca953x_irq_set_type(struct i
38
39 static void pca953x_irq_shutdown(struct irq_data *d)
40 {
41 - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
42 + struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
43 + struct pca953x_chip *chip = gpiochip_get_data(gc);
44 u8 mask = 1 << (d->hwirq % BANK_SZ);
45
46 chip->irq_trig_raise[d->hwirq / BANK_SZ] &= ~mask;