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: NNicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: NLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: NJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
上级 e4541ff2
...@@ -9,6 +9,10 @@ Required properties: ...@@ -9,6 +9,10 @@ Required properties:
unused). unused).
- gpio-controller: Marks the device node as a GPIO controller. - gpio-controller: Marks the device node as a GPIO controller.
optional properties:
- #gpio-lines: Number of gpio if absent 32.
Example: Example:
pioA: gpio@fffff200 { pioA: gpio@fffff200 {
compatible = "atmel,at91rm9200-gpio"; compatible = "atmel,at91rm9200-gpio";
...@@ -16,5 +20,6 @@ Example: ...@@ -16,5 +20,6 @@ Example:
interrupts = <2 4>; interrupts = <2 4>;
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
#gpio-lines = <19>;
}; };
...@@ -133,6 +133,7 @@ ...@@ -133,6 +133,7 @@
interrupts = <2 4 1>; interrupts = <2 4 1>;
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
#gpio-lines = <19>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <2>; #interrupt-cells = <2>;
}; };
...@@ -153,6 +154,7 @@ ...@@ -153,6 +154,7 @@
interrupts = <3 4 1>; interrupts = <3 4 1>;
#gpio-cells = <2>; #gpio-cells = <2>;
gpio-controller; gpio-controller;
#gpio-lines = <22>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <2>; #interrupt-cells = <2>;
}; };
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include "generic.h" #include "generic.h"
#define MAX_NB_GPIO_PER_BANK 32
struct at91_gpio_chip { struct at91_gpio_chip {
struct gpio_chip chip; struct gpio_chip chip;
struct at91_gpio_chip *next; /* Bank sharing same clock */ struct at91_gpio_chip *next; /* Bank sharing same clock */
...@@ -56,7 +58,7 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, ...@@ -56,7 +58,7 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset); unsigned offset);
static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset);
#define AT91_GPIO_CHIP(name, nr_gpio) \ #define AT91_GPIO_CHIP(name) \
{ \ { \
.chip = { \ .chip = { \
.label = name, \ .label = name, \
...@@ -67,16 +69,16 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); ...@@ -67,16 +69,16 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset);
.set = at91_gpiolib_set, \ .set = at91_gpiolib_set, \
.dbg_show = at91_gpiolib_dbg_show, \ .dbg_show = at91_gpiolib_dbg_show, \
.to_irq = at91_gpiolib_to_irq, \ .to_irq = at91_gpiolib_to_irq, \
.ngpio = nr_gpio, \ .ngpio = MAX_NB_GPIO_PER_BANK, \
}, \ }, \
} }
static struct at91_gpio_chip gpio_chip[] = { static struct at91_gpio_chip gpio_chip[] = {
AT91_GPIO_CHIP("pioA", 32), AT91_GPIO_CHIP("pioA"),
AT91_GPIO_CHIP("pioB", 32), AT91_GPIO_CHIP("pioB"),
AT91_GPIO_CHIP("pioC", 32), AT91_GPIO_CHIP("pioC"),
AT91_GPIO_CHIP("pioD", 32), AT91_GPIO_CHIP("pioD"),
AT91_GPIO_CHIP("pioE", 32), AT91_GPIO_CHIP("pioE"),
}; };
static int gpio_banks; static int gpio_banks;
...@@ -91,7 +93,7 @@ static unsigned long at91_gpio_caps; ...@@ -91,7 +93,7 @@ static unsigned long at91_gpio_caps;
static inline void __iomem *pin_to_controller(unsigned pin) static inline void __iomem *pin_to_controller(unsigned pin)
{ {
pin /= 32; pin /= MAX_NB_GPIO_PER_BANK;
if (likely(pin < gpio_banks)) if (likely(pin < gpio_banks))
return gpio_chip[pin].regbase; return gpio_chip[pin].regbase;
...@@ -100,7 +102,7 @@ static inline void __iomem *pin_to_controller(unsigned pin) ...@@ -100,7 +102,7 @@ static inline void __iomem *pin_to_controller(unsigned pin)
static inline unsigned pin_to_mask(unsigned pin) static inline unsigned pin_to_mask(unsigned pin)
{ {
return 1 << (pin % 32); return 1 << (pin % MAX_NB_GPIO_PER_BANK);
} }
...@@ -992,6 +994,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np) ...@@ -992,6 +994,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np)
{ {
int alias_idx; int alias_idx;
struct at91_gpio_chip *at91_gpio; struct at91_gpio_chip *at91_gpio;
uint32_t ngpio;
if (!np) if (!np)
return; return;
...@@ -1004,7 +1007,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np) ...@@ -1004,7 +1007,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np)
} }
at91_gpio = &gpio_chip[alias_idx]; at91_gpio = &gpio_chip[alias_idx];
at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; at91_gpio->chip.base = alias_idx * MAX_NB_GPIO_PER_BANK;
at91_gpio->regbase = of_iomap(np, 0); at91_gpio->regbase = of_iomap(np, 0);
if (!at91_gpio->regbase) { if (!at91_gpio->regbase) {
...@@ -1024,6 +1027,14 @@ static void __init of_at91_gpio_init_one(struct device_node *np) ...@@ -1024,6 +1027,14 @@ static void __init of_at91_gpio_init_one(struct device_node *np)
if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio"))
at91_gpio_caps |= AT91_GPIO_CAP_PIO3; at91_gpio_caps |= AT91_GPIO_CAP_PIO3;
if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) {
if (ngpio >= MAX_NB_GPIO_PER_BANK)
pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n",
alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK);
else
at91_gpio->chip.ngpio = ngpio;
}
/* Setup clock */ /* Setup clock */
if (at91_gpio_setup_clk(alias_idx)) if (at91_gpio_setup_clk(alias_idx))
goto ioremap_err; goto ioremap_err;
...@@ -1061,7 +1072,7 @@ static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) ...@@ -1061,7 +1072,7 @@ static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq)
{ {
struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; struct at91_gpio_chip *at91_gpio = &gpio_chip[idx];
at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK;
at91_gpio->pioc_hwirq = pioc_hwirq; at91_gpio->pioc_hwirq = pioc_hwirq;
at91_gpio->pioc_idx = idx; at91_gpio->pioc_idx = idx;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册