diff options
Diffstat (limited to 'arch/arm/mach-at91/gpio.c')
| -rw-r--r-- | arch/arm/mach-at91/gpio.c | 33 | 
1 files changed, 22 insertions, 11 deletions
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 3b8f463bfa1..a34f0ed291c 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -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;  |