diff options
author | Olof Johansson <olof@lixom.net> | 2012-04-05 13:41:49 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-04-05 13:41:49 -0400 |
commit | 98f0ec0dd4e0c96fcc7bc6dae08007820b1134a8 (patch) | |
tree | 170a3f52ce95c07bb2438f3ccf744d30ffdf4411 /drivers | |
parent | cfe2da5347950cf2c581ced7285dcafaa44aa626 (diff) | |
parent | 4a3398ee9d7d8008ee9bfc8a600b734a1b22af23 (diff) |
Merge branch 'for-3.4/fixes-for-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into fixes
* 'for-3.4/fixes-for-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra:
gpio: tegra: Iterate over the correct number of banks
gpio: tegra: fix register address calculations for Tegra30
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/gpio-tegra.c | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 32de6707e3c4..12f349b3830d 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/of.h> | 25 | #include <linux/of_device.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/irqdomain.h> | 28 | #include <linux/irqdomain.h> |
@@ -37,7 +37,8 @@ | |||
37 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) | 37 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) |
38 | #define GPIO_BIT(x) ((x) & 0x7) | 38 | #define GPIO_BIT(x) ((x) & 0x7) |
39 | 39 | ||
40 | #define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4) | 40 | #define GPIO_REG(x) (GPIO_BANK(x) * tegra_gpio_bank_stride + \ |
41 | GPIO_PORT(x) * 4) | ||
41 | 42 | ||
42 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) | 43 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) |
43 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) | 44 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) |
@@ -48,12 +49,12 @@ | |||
48 | #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) | 49 | #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) |
49 | #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) | 50 | #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) |
50 | 51 | ||
51 | #define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) | 52 | #define GPIO_MSK_CNF(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x00) |
52 | #define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) | 53 | #define GPIO_MSK_OE(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x10) |
53 | #define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) | 54 | #define GPIO_MSK_OUT(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0X20) |
54 | #define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) | 55 | #define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x40) |
55 | #define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) | 56 | #define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x50) |
56 | #define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) | 57 | #define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x60) |
57 | 58 | ||
58 | #define GPIO_INT_LVL_MASK 0x010101 | 59 | #define GPIO_INT_LVL_MASK 0x010101 |
59 | #define GPIO_INT_LVL_EDGE_RISING 0x000101 | 60 | #define GPIO_INT_LVL_EDGE_RISING 0x000101 |
@@ -78,6 +79,8 @@ struct tegra_gpio_bank { | |||
78 | static struct irq_domain *irq_domain; | 79 | static struct irq_domain *irq_domain; |
79 | static void __iomem *regs; | 80 | static void __iomem *regs; |
80 | static u32 tegra_gpio_bank_count; | 81 | static u32 tegra_gpio_bank_count; |
82 | static u32 tegra_gpio_bank_stride; | ||
83 | static u32 tegra_gpio_upper_offset; | ||
81 | static struct tegra_gpio_bank *tegra_gpio_banks; | 84 | static struct tegra_gpio_bank *tegra_gpio_banks; |
82 | 85 | ||
83 | static inline void tegra_gpio_writel(u32 val, u32 reg) | 86 | static inline void tegra_gpio_writel(u32 val, u32 reg) |
@@ -333,6 +336,26 @@ static struct irq_chip tegra_gpio_irq_chip = { | |||
333 | #endif | 336 | #endif |
334 | }; | 337 | }; |
335 | 338 | ||
339 | struct tegra_gpio_soc_config { | ||
340 | u32 bank_stride; | ||
341 | u32 upper_offset; | ||
342 | }; | ||
343 | |||
344 | static struct tegra_gpio_soc_config tegra20_gpio_config = { | ||
345 | .bank_stride = 0x80, | ||
346 | .upper_offset = 0x800, | ||
347 | }; | ||
348 | |||
349 | static struct tegra_gpio_soc_config tegra30_gpio_config = { | ||
350 | .bank_stride = 0x100, | ||
351 | .upper_offset = 0x80, | ||
352 | }; | ||
353 | |||
354 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
355 | { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, | ||
356 | { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, | ||
357 | { }, | ||
358 | }; | ||
336 | 359 | ||
337 | /* This lock class tells lockdep that GPIO irqs are in a different | 360 | /* This lock class tells lockdep that GPIO irqs are in a different |
338 | * category than their parents, so it won't report false recursion. | 361 | * category than their parents, so it won't report false recursion. |
@@ -341,6 +364,8 @@ static struct lock_class_key gpio_lock_class; | |||
341 | 364 | ||
342 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) | 365 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) |
343 | { | 366 | { |
367 | const struct of_device_id *match; | ||
368 | struct tegra_gpio_soc_config *config; | ||
344 | int irq_base; | 369 | int irq_base; |
345 | struct resource *res; | 370 | struct resource *res; |
346 | struct tegra_gpio_bank *bank; | 371 | struct tegra_gpio_bank *bank; |
@@ -348,6 +373,15 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
348 | int i; | 373 | int i; |
349 | int j; | 374 | int j; |
350 | 375 | ||
376 | match = of_match_device(tegra_gpio_of_match, &pdev->dev); | ||
377 | if (match) | ||
378 | config = (struct tegra_gpio_soc_config *)match->data; | ||
379 | else | ||
380 | config = &tegra20_gpio_config; | ||
381 | |||
382 | tegra_gpio_bank_stride = config->bank_stride; | ||
383 | tegra_gpio_upper_offset = config->upper_offset; | ||
384 | |||
351 | for (;;) { | 385 | for (;;) { |
352 | res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); | 386 | res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); |
353 | if (!res) | 387 | if (!res) |
@@ -402,7 +436,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
402 | return -ENODEV; | 436 | return -ENODEV; |
403 | } | 437 | } |
404 | 438 | ||
405 | for (i = 0; i < 7; i++) { | 439 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
406 | for (j = 0; j < 4; j++) { | 440 | for (j = 0; j < 4; j++) { |
407 | int gpio = tegra_gpio_compose(i, j, 0); | 441 | int gpio = tegra_gpio_compose(i, j, 0); |
408 | tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); | 442 | tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); |
@@ -441,11 +475,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
441 | return 0; | 475 | return 0; |
442 | } | 476 | } |
443 | 477 | ||
444 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
445 | { .compatible = "nvidia,tegra20-gpio", }, | ||
446 | { }, | ||
447 | }; | ||
448 | |||
449 | static struct platform_driver tegra_gpio_driver = { | 478 | static struct platform_driver tegra_gpio_driver = { |
450 | .driver = { | 479 | .driver = { |
451 | .name = "tegra-gpio", | 480 | .name = "tegra-gpio", |
@@ -485,7 +514,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
485 | int i; | 514 | int i; |
486 | int j; | 515 | int j; |
487 | 516 | ||
488 | for (i = 0; i < 7; i++) { | 517 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
489 | for (j = 0; j < 4; j++) { | 518 | for (j = 0; j < 4; j++) { |
490 | int gpio = tegra_gpio_compose(i, j, 0); | 519 | int gpio = tegra_gpio_compose(i, j, 0); |
491 | seq_printf(s, | 520 | seq_printf(s, |