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

Commit 6075a8b2 authored by Grygorii Strashko's avatar Grygorii Strashko Committed by Sekhar Nori
Browse files

gpio: davinci: don't create irq_domain in case of unbanked irqs



The system may crash if:
- there are more than 1 banks
- unbanked irqs are enabled
- someone will call gpio_to_irq() for GPIO from bank2 or above

Hence, fix it by not creating irq_domain if unbanked irqs are enabled
and correct gpio_to_irq_banked() to handle this properly.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Alexandre Courbot <gnurou@gmail.com>
Cc: Sekhar Nori <nsekhar@ti.com>

Acked-by: default avatarSantosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarLad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: default avatarSekhar Nori <nsekhar@ti.com>
parent 0d978eb7
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -351,7 +351,10 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
{
	struct davinci_gpio_controller *d = chip2controller(chip);

	if (d->irq_domain)
		return irq_create_mapping(d->irq_domain, d->chip.base + offset);
	else
		return -ENXIO;
}

static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
@@ -429,7 +432,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
	struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
	struct davinci_gpio_platform_data *pdata = dev->platform_data;
	struct davinci_gpio_regs __iomem *g;
	struct irq_domain	*irq_domain;
	struct irq_domain	*irq_domain = NULL;

	ngpio = pdata->ngpio;
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -453,6 +456,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
	}
	clk_prepare_enable(clk);

	if (!pdata->gpio_unbanked) {
		irq = irq_alloc_descs(-1, 0, ngpio, 0);
		if (irq < 0) {
			dev_err(dev, "Couldn't allocate IRQ numbers\n");
@@ -466,6 +470,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
			dev_err(dev, "Couldn't register an IRQ domain\n");
			return -ENODEV;
		}
	}

	/*
	 * Arrange gpio_to_irq() support, handling either direct IRQs or
@@ -475,7 +480,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
	 */
	for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
		chips[bank].chip.to_irq = gpio_to_irq_banked;
		if (!pdata->gpio_unbanked)
		chips[bank].irq_domain = irq_domain;
	}