From ba6cecb3ef248735f33f53b86cdd2e588b872d45 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 26 May 2022 20:06:18 +0800 Subject: [PATCH] gpio: tegra186: Fix chip_data type confusion stable inclusion from stable-v5.10.103 commit 4185b788d3adc9e66b5b9c959b91ae17b8488fc3 bugzilla: https://gitee.com/openeuler/kernel/issues/I56NE7 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4185b788d3adc9e66b5b9c959b91ae17b8488fc3 -------------------------------- commit d1e972ace42390de739cde87d96043dcbe502286 upstream. The tegra186 GPIO driver makes the assumption that the pointer returned by irq_data_get_irq_chip_data() is a pointer to a tegra_gpio structure. Unfortunately, it is actually a pointer to the inner gpio_chip structure, as mandated by the gpiolib infrastructure. Nice try. The saving grace is that the gpio_chip is the first member of tegra_gpio, so the bug has gone undetected since... forever. Fix it by performing a container_of() on the pointer. This results in no additional code, and makes it possible to understand how the whole thing works. Fixes: 5b2b135a87fc ("gpio: Add Tegra186 support") Signed-off-by: Marc Zyngier Cc: Thierry Reding Cc: Linus Walleij Cc: Bartosz Golaszewski Link: https://lore.kernel.org/r/20220211093904.1112679-1-maz@kernel.org Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman Signed-off-by: Yu Liao Reviewed-by: Wei Li Signed-off-by: Zheng Zengkai --- drivers/gpio/gpio-tegra186.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 9500074b1f1b..7fbe5f0681b9 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -337,9 +337,12 @@ static int tegra186_gpio_of_xlate(struct gpio_chip *chip, return offset + pin; } +#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio) + static void tegra186_irq_ack(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; base = tegra186_gpio_get_base(gpio, data->hwirq); @@ -351,7 +354,8 @@ static void tegra186_irq_ack(struct irq_data *data) static void tegra186_irq_mask(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; u32 value; @@ -366,7 +370,8 @@ static void tegra186_irq_mask(struct irq_data *data) static void tegra186_irq_unmask(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; u32 value; @@ -381,7 +386,8 @@ static void tegra186_irq_unmask(struct irq_data *data) static int tegra186_irq_set_type(struct irq_data *data, unsigned int type) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; u32 value; -- GitLab