diff options
Diffstat (limited to 'drivers/gpio')
| -rw-r--r-- | drivers/gpio/gpio-tegra.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index d3f15314e340..8253665eafcc 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -85,15 +85,10 @@ struct tegra_gpio_bank { static struct irq_domain *irq_domain; static void __iomem *regs; -#ifdef CONFIG_ARCH_TEGRA_2x_SOC -static struct tegra_gpio_bank tegra_gpio_banks[7]; -#else -static struct tegra_gpio_bank tegra_gpio_banks[8]; -#endif - static u32 tegra_gpio_bank_count; static u32 tegra_gpio_bank_stride; static u32 tegra_gpio_upper_offset; +static struct tegra_gpio_bank *tegra_gpio_banks; static inline void tegra_gpio_writel(u32 val, u32 reg) { @@ -354,7 +349,7 @@ void tegra_gpio_resume(void) local_irq_save(flags); - for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { + for (b = 0; b < tegra_gpio_bank_count; b++) { struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { @@ -377,7 +372,7 @@ int tegra_gpio_suspend(void) int p; local_irq_save(flags); - for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) { + for (b = 0; b < tegra_gpio_bank_count; b++) { struct tegra_gpio_bank *bank = &tegra_gpio_banks[b]; for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { @@ -487,18 +482,39 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) tegra_gpio_bank_stride = config->bank_stride; tegra_gpio_upper_offset = config->upper_offset; - tegra_gpio_chip.ngpio = ARRAY_SIZE(tegra_gpio_banks) * 32; + + for (;;) { + res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); + if (!res) + break; + tegra_gpio_bank_count++; + } + if (!tegra_gpio_bank_count) { + dev_err(&pdev->dev, "Missing IRQ resource\n"); + return -ENODEV; + } + + tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32; + + tegra_gpio_banks = devm_kzalloc(&pdev->dev, + tegra_gpio_bank_count * sizeof(*tegra_gpio_banks), + GFP_KERNEL); + if (!tegra_gpio_banks) { + dev_err(&pdev->dev, "Couldn't allocate bank structure\n"); + return -ENODEV; + } irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); return -ENODEV; } + irq_domain = irq_domain_add_legacy(pdev->dev.of_node, tegra_gpio_chip.ngpio, irq_base, 0, &irq_domain_simple_ops, NULL); - for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { + for (i = 0; i < tegra_gpio_bank_count; i++) { res = platform_get_resource(pdev, IORESOURCE_IRQ, i); if (!res) { dev_err(&pdev->dev, "Missing IRQ resource\n"); @@ -549,7 +565,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) set_irq_flags(irq, IRQF_VALID); } - for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { + for (i = 0; i < tegra_gpio_bank_count; i++) { bank = &tegra_gpio_banks[i]; for (j = 0; j < 4; j++) |
