diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-07-14 03:26:08 -0400 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-10-12 21:09:29 -0400 |
commit | fc33ff43134790ef3cb997ed90048a50b4d1b15e (patch) | |
tree | 695135416a900b44ede49372b531e6c47383ef5b | |
parent | e4541ff21284e5f2208473b39b535fcd50318c92 (diff) |
arm: at91: at91sam9x5: fix gpio number per bank
On the at91sam9x5 SoC series, GPIO banks B and D only have 19 and 22
pins. So add a property to set this parameter.
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
-rw-r--r-- | Documentation/devicetree/bindings/gpio/gpio_atmel.txt | 5 | ||||
-rw-r--r-- | arch/arm/boot/dts/at91sam9x5.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/gpio.c | 33 |
3 files changed, 29 insertions, 11 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt index 66efc804806a..85f8c0d084fa 100644 --- a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt +++ b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt | |||
@@ -9,6 +9,10 @@ Required properties: | |||
9 | unused). | 9 | unused). |
10 | - gpio-controller: Marks the device node as a GPIO controller. | 10 | - gpio-controller: Marks the device node as a GPIO controller. |
11 | 11 | ||
12 | optional properties: | ||
13 | - #gpio-lines: Number of gpio if absent 32. | ||
14 | |||
15 | |||
12 | Example: | 16 | Example: |
13 | pioA: gpio@fffff200 { | 17 | pioA: gpio@fffff200 { |
14 | compatible = "atmel,at91rm9200-gpio"; | 18 | compatible = "atmel,at91rm9200-gpio"; |
@@ -16,5 +20,6 @@ Example: | |||
16 | interrupts = <2 4>; | 20 | interrupts = <2 4>; |
17 | #gpio-cells = <2>; | 21 | #gpio-cells = <2>; |
18 | gpio-controller; | 22 | gpio-controller; |
23 | #gpio-lines = <19>; | ||
19 | }; | 24 | }; |
20 | 25 | ||
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 507a84d2a5d7..065698ac4deb 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi | |||
@@ -133,6 +133,7 @@ | |||
133 | interrupts = <2 4 1>; | 133 | interrupts = <2 4 1>; |
134 | #gpio-cells = <2>; | 134 | #gpio-cells = <2>; |
135 | gpio-controller; | 135 | gpio-controller; |
136 | #gpio-lines = <19>; | ||
136 | interrupt-controller; | 137 | interrupt-controller; |
137 | #interrupt-cells = <2>; | 138 | #interrupt-cells = <2>; |
138 | }; | 139 | }; |
@@ -153,6 +154,7 @@ | |||
153 | interrupts = <3 4 1>; | 154 | interrupts = <3 4 1>; |
154 | #gpio-cells = <2>; | 155 | #gpio-cells = <2>; |
155 | gpio-controller; | 156 | gpio-controller; |
157 | #gpio-lines = <22>; | ||
156 | interrupt-controller; | 158 | interrupt-controller; |
157 | #interrupt-cells = <2>; | 159 | #interrupt-cells = <2>; |
158 | }; | 160 | }; |
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 3b8f463bfa1d..a34f0ed291c0 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -33,6 +33,8 @@ | |||
33 | 33 | ||
34 | #include "generic.h" | 34 | #include "generic.h" |
35 | 35 | ||
36 | #define MAX_NB_GPIO_PER_BANK 32 | ||
37 | |||
36 | struct at91_gpio_chip { | 38 | struct at91_gpio_chip { |
37 | struct gpio_chip chip; | 39 | struct gpio_chip chip; |
38 | struct at91_gpio_chip *next; /* Bank sharing same clock */ | 40 | struct at91_gpio_chip *next; /* Bank sharing same clock */ |
@@ -56,7 +58,7 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, | |||
56 | unsigned offset); | 58 | unsigned offset); |
57 | static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); | 59 | static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); |
58 | 60 | ||
59 | #define AT91_GPIO_CHIP(name, nr_gpio) \ | 61 | #define AT91_GPIO_CHIP(name) \ |
60 | { \ | 62 | { \ |
61 | .chip = { \ | 63 | .chip = { \ |
62 | .label = name, \ | 64 | .label = name, \ |
@@ -67,16 +69,16 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); | |||
67 | .set = at91_gpiolib_set, \ | 69 | .set = at91_gpiolib_set, \ |
68 | .dbg_show = at91_gpiolib_dbg_show, \ | 70 | .dbg_show = at91_gpiolib_dbg_show, \ |
69 | .to_irq = at91_gpiolib_to_irq, \ | 71 | .to_irq = at91_gpiolib_to_irq, \ |
70 | .ngpio = nr_gpio, \ | 72 | .ngpio = MAX_NB_GPIO_PER_BANK, \ |
71 | }, \ | 73 | }, \ |
72 | } | 74 | } |
73 | 75 | ||
74 | static struct at91_gpio_chip gpio_chip[] = { | 76 | static struct at91_gpio_chip gpio_chip[] = { |
75 | AT91_GPIO_CHIP("pioA", 32), | 77 | AT91_GPIO_CHIP("pioA"), |
76 | AT91_GPIO_CHIP("pioB", 32), | 78 | AT91_GPIO_CHIP("pioB"), |
77 | AT91_GPIO_CHIP("pioC", 32), | 79 | AT91_GPIO_CHIP("pioC"), |
78 | AT91_GPIO_CHIP("pioD", 32), | 80 | AT91_GPIO_CHIP("pioD"), |
79 | AT91_GPIO_CHIP("pioE", 32), | 81 | AT91_GPIO_CHIP("pioE"), |
80 | }; | 82 | }; |
81 | 83 | ||
82 | static int gpio_banks; | 84 | static int gpio_banks; |
@@ -91,7 +93,7 @@ static unsigned long at91_gpio_caps; | |||
91 | 93 | ||
92 | static inline void __iomem *pin_to_controller(unsigned pin) | 94 | static inline void __iomem *pin_to_controller(unsigned pin) |
93 | { | 95 | { |
94 | pin /= 32; | 96 | pin /= MAX_NB_GPIO_PER_BANK; |
95 | if (likely(pin < gpio_banks)) | 97 | if (likely(pin < gpio_banks)) |
96 | return gpio_chip[pin].regbase; | 98 | return gpio_chip[pin].regbase; |
97 | 99 | ||
@@ -100,7 +102,7 @@ static inline void __iomem *pin_to_controller(unsigned pin) | |||
100 | 102 | ||
101 | static inline unsigned pin_to_mask(unsigned pin) | 103 | static inline unsigned pin_to_mask(unsigned pin) |
102 | { | 104 | { |
103 | return 1 << (pin % 32); | 105 | return 1 << (pin % MAX_NB_GPIO_PER_BANK); |
104 | } | 106 | } |
105 | 107 | ||
106 | 108 | ||
@@ -992,6 +994,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np) | |||
992 | { | 994 | { |
993 | int alias_idx; | 995 | int alias_idx; |
994 | struct at91_gpio_chip *at91_gpio; | 996 | struct at91_gpio_chip *at91_gpio; |
997 | uint32_t ngpio; | ||
995 | 998 | ||
996 | if (!np) | 999 | if (!np) |
997 | return; | 1000 | return; |
@@ -1004,7 +1007,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np) | |||
1004 | } | 1007 | } |
1005 | 1008 | ||
1006 | at91_gpio = &gpio_chip[alias_idx]; | 1009 | at91_gpio = &gpio_chip[alias_idx]; |
1007 | at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; | 1010 | at91_gpio->chip.base = alias_idx * MAX_NB_GPIO_PER_BANK; |
1008 | 1011 | ||
1009 | at91_gpio->regbase = of_iomap(np, 0); | 1012 | at91_gpio->regbase = of_iomap(np, 0); |
1010 | if (!at91_gpio->regbase) { | 1013 | if (!at91_gpio->regbase) { |
@@ -1024,6 +1027,14 @@ static void __init of_at91_gpio_init_one(struct device_node *np) | |||
1024 | if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) | 1027 | if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) |
1025 | at91_gpio_caps |= AT91_GPIO_CAP_PIO3; | 1028 | at91_gpio_caps |= AT91_GPIO_CAP_PIO3; |
1026 | 1029 | ||
1030 | if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { | ||
1031 | if (ngpio >= MAX_NB_GPIO_PER_BANK) | ||
1032 | pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", | ||
1033 | alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); | ||
1034 | else | ||
1035 | at91_gpio->chip.ngpio = ngpio; | ||
1036 | } | ||
1037 | |||
1027 | /* Setup clock */ | 1038 | /* Setup clock */ |
1028 | if (at91_gpio_setup_clk(alias_idx)) | 1039 | if (at91_gpio_setup_clk(alias_idx)) |
1029 | goto ioremap_err; | 1040 | goto ioremap_err; |
@@ -1061,7 +1072,7 @@ static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) | |||
1061 | { | 1072 | { |
1062 | struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; | 1073 | struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; |
1063 | 1074 | ||
1064 | at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; | 1075 | at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK; |
1065 | at91_gpio->pioc_hwirq = pioc_hwirq; | 1076 | at91_gpio->pioc_hwirq = pioc_hwirq; |
1066 | at91_gpio->pioc_idx = idx; | 1077 | at91_gpio->pioc_idx = idx; |
1067 | 1078 | ||