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: 5b2b135a87
("gpio: Add Tegra186 support")
Signed-off-by: Marc 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: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
bb2e0a7723
commit
4185b788d3
@@ -337,9 +337,12 @@ static int tegra186_gpio_of_xlate(struct gpio_chip *chip,
|
|||||||
return offset + pin;
|
return offset + pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio)
|
||||||
|
|
||||||
static void tegra186_irq_ack(struct irq_data *data)
|
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;
|
void __iomem *base;
|
||||||
|
|
||||||
base = tegra186_gpio_get_base(gpio, data->hwirq);
|
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)
|
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;
|
void __iomem *base;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
@@ -366,7 +370,8 @@ static void tegra186_irq_mask(struct irq_data *data)
|
|||||||
|
|
||||||
static void tegra186_irq_unmask(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;
|
void __iomem *base;
|
||||||
u32 value;
|
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)
|
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;
|
void __iomem *base;
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user