|
@@ -33,6 +33,8 @@
|
|
|
|
|
|
#include "generic.h"
|
|
|
|
|
|
+#define MAX_NB_GPIO_PER_BANK 32
|
|
|
+
|
|
|
struct at91_gpio_chip {
|
|
|
struct gpio_chip chip;
|
|
|
struct at91_gpio_chip *next; /* Bank sharing same clock */
|
|
@@ -56,7 +58,7 @@ static int at91_gpiolib_direction_input(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 = { \
|
|
|
.label = name, \
|
|
@@ -67,16 +69,16 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset);
|
|
|
.set = at91_gpiolib_set, \
|
|
|
.dbg_show = at91_gpiolib_dbg_show, \
|
|
|
.to_irq = at91_gpiolib_to_irq, \
|
|
|
- .ngpio = nr_gpio, \
|
|
|
+ .ngpio = MAX_NB_GPIO_PER_BANK, \
|
|
|
}, \
|
|
|
}
|
|
|
|
|
|
static struct at91_gpio_chip gpio_chip[] = {
|
|
|
- AT91_GPIO_CHIP("pioA", 32),
|
|
|
- AT91_GPIO_CHIP("pioB", 32),
|
|
|
- AT91_GPIO_CHIP("pioC", 32),
|
|
|
- AT91_GPIO_CHIP("pioD", 32),
|
|
|
- AT91_GPIO_CHIP("pioE", 32),
|
|
|
+ AT91_GPIO_CHIP("pioA"),
|
|
|
+ AT91_GPIO_CHIP("pioB"),
|
|
|
+ AT91_GPIO_CHIP("pioC"),
|
|
|
+ AT91_GPIO_CHIP("pioD"),
|
|
|
+ AT91_GPIO_CHIP("pioE"),
|
|
|
};
|
|
|
|
|
|
static int gpio_banks;
|
|
@@ -91,7 +93,7 @@ static unsigned long at91_gpio_caps;
|
|
|
|
|
|
static inline void __iomem *pin_to_controller(unsigned pin)
|
|
|
{
|
|
|
- pin /= 32;
|
|
|
+ pin /= MAX_NB_GPIO_PER_BANK;
|
|
|
if (likely(pin < gpio_banks))
|
|
|
return gpio_chip[pin].regbase;
|
|
|
|
|
@@ -100,7 +102,7 @@ static inline void __iomem *pin_to_controller(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)
|
|
|
{
|
|
|
int alias_idx;
|
|
|
struct at91_gpio_chip *at91_gpio;
|
|
|
+ uint32_t ngpio;
|
|
|
|
|
|
if (!np)
|
|
|
return;
|
|
@@ -1004,7 +1007,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np)
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
if (!at91_gpio->regbase) {
|
|
@@ -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"))
|
|
|
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 */
|
|
|
if (at91_gpio_setup_clk(alias_idx))
|
|
|
goto ioremap_err;
|
|
@@ -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];
|
|
|
|
|
|
- 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_idx = idx;
|
|
|
|