Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fb051bb authored by Marc Zyngier's avatar Marc Zyngier Committed by Greg Kroah-Hartman
Browse files

gpio: tegra186: Fix chip_data type confusion



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: 5b2b135a ("gpio: Add Tegra186 support")
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Cc: Thierry Reding <treding@nvidia.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Link: https://lore.kernel.org/r/20220211093904.1112679-1-maz@kernel.org


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2782b05d
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -234,9 +234,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);
@@ -248,7 +251,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;

@@ -263,7 +267,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;

@@ -278,7 +283,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;