diff options
Diffstat (limited to 'arch/blackfin/kernel/bfin_gpio.c')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 111 |
1 files changed, 58 insertions, 53 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 42833ee2b30..dc07ed08b37 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -108,11 +108,7 @@ static unsigned short * const port_fer[] = { }; #endif -static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; -static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)]; -static unsigned short reserved_gpio_irq_map[GPIO_BANK_NUM]; - -#define RESOURCE_LABEL_SIZE 16 +#define RESOURCE_LABEL_SIZE 16 static struct str_ident { char name[RESOURCE_LABEL_SIZE]; @@ -122,19 +118,6 @@ static struct str_ident { static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; #endif -inline int check_gpio(unsigned gpio) -{ -#if defined(CONFIG_BF54x) - if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 - || gpio == GPIO_PH14 || gpio == GPIO_PH15 - || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) - return -EINVAL; -#endif - if (gpio >= MAX_BLACKFIN_GPIOS) - return -EINVAL; - return 0; -} - static void gpio_error(unsigned gpio) { printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio); @@ -167,6 +150,29 @@ static int cmp_label(unsigned short ident, const char *label) return -EINVAL; } +#define map_entry(m, i) reserved_##m##_map[gpio_bank(i)] +#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i)) +#define reserve(m, i) (map_entry(m, i) |= gpio_bit(i)) +#define unreserve(m, i) (map_entry(m, i) &= ~gpio_bit(i)) +#define DECLARE_RESERVED_MAP(m, c) static unsigned short reserved_##m##_map[c] + +DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM); +DECLARE_RESERVED_MAP(peri, DIV_ROUND_UP(MAX_RESOURCES, GPIO_BANKSIZE)); +DECLARE_RESERVED_MAP(gpio_irq, GPIO_BANK_NUM); + +inline int check_gpio(unsigned gpio) +{ +#if defined(CONFIG_BF54x) + if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 + || gpio == GPIO_PH14 || gpio == GPIO_PH15 + || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) + return -EINVAL; +#endif + if (gpio >= MAX_BLACKFIN_GPIOS) + return -EINVAL; + return 0; +} + static void port_setup(unsigned gpio, unsigned short usage) { #if defined(BF538_FAMILY) @@ -475,7 +481,7 @@ GET_GPIO_P(maskb) #ifdef CONFIG_PM -static unsigned short wakeup_map[GPIO_BANK_NUM]; +DECLARE_RESERVED_MAP(wakeup, GPIO_BANK_NUM); static const unsigned int sic_iwr_irqs[] = { #if defined(BF533_FAMILY) @@ -521,9 +527,9 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) local_irq_save_hw(flags); if (ctrl) - wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); + reserve(wakeup, gpio); else - wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + unreserve(wakeup, gpio); set_gpio_maskb(gpio, ctrl); local_irq_restore_hw(flags); @@ -536,7 +542,7 @@ int bfin_pm_standby_ctrl(unsigned ctrl) u16 bank, mask, i; for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - mask = wakeup_map[gpio_bank(i)]; + mask = map_entry(wakeup, i); bank = gpio_bank(i); if (mask) @@ -653,7 +659,7 @@ EXPORT_SYMBOL(get_gpio_dir); /*********************************************************** * -* FUNCTIONS: Blackfin Peripheral Resource Allocation +* FUNCTIONS: Blackfin Peripheral Resource Allocation * and PortMux Setup * * INPUTS/OUTPUTS: @@ -689,8 +695,7 @@ int peripheral_request(unsigned short per, const char *label) /* If a pin can be muxed as either GPIO or peripheral, make * sure it is not already a GPIO pin when we request it. */ - if (unlikely(!check_gpio(ident) && - reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) { + if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) { if (system_state == SYSTEM_BOOTING) dump_stack(); printk(KERN_ERR @@ -700,7 +705,7 @@ int peripheral_request(unsigned short per, const char *label) return -EBUSY; } - if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) { + if (unlikely(is_reserved(peri, ident, 1))) { /* * Pin functions like AMC address strobes my @@ -731,7 +736,7 @@ int peripheral_request(unsigned short per, const char *label) } anyway: - reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); + reserve(peri, ident); portmux_setup(per); port_setup(ident, PERIPHERAL_USAGE); @@ -777,7 +782,7 @@ void peripheral_free(unsigned short per) local_irq_save_hw(flags); - if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { + if (unlikely(!is_reserved(peri, ident, 0))) { local_irq_restore_hw(flags); return; } @@ -785,7 +790,7 @@ void peripheral_free(unsigned short per) if (!(per & P_MAYSHARE)) port_setup(ident, GPIO_USAGE); - reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident); + unreserve(peri, ident); set_label(ident, "free"); @@ -836,7 +841,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) return 0; } - if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(is_reserved(gpio, gpio, 1))) { if (system_state == SYSTEM_BOOTING) dump_stack(); printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", @@ -844,7 +849,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) local_irq_restore_hw(flags); return -EBUSY; } - if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(is_reserved(peri, gpio, 1))) { if (system_state == SYSTEM_BOOTING) dump_stack(); printk(KERN_ERR @@ -853,7 +858,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) local_irq_restore_hw(flags); return -EBUSY; } - if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(is_reserved(gpio_irq, gpio, 1))) { printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); } @@ -863,7 +868,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) } #endif - reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); + reserve(gpio, gpio); set_label(gpio, label); local_irq_restore_hw(flags); @@ -885,7 +890,7 @@ void bfin_gpio_free(unsigned gpio) local_irq_save_hw(flags); - if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { + if (unlikely(!is_reserved(gpio, gpio, 0))) { if (system_state == SYSTEM_BOOTING) dump_stack(); gpio_error(gpio); @@ -893,7 +898,7 @@ void bfin_gpio_free(unsigned gpio) return; } - reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + unreserve(gpio, gpio); set_label(gpio, "free"); @@ -902,7 +907,7 @@ void bfin_gpio_free(unsigned gpio) EXPORT_SYMBOL(bfin_gpio_free); #ifdef BFIN_SPECIAL_GPIO_BANKS -static unsigned short reserved_special_gpio_map[gpio_bank(MAX_RESOURCES)]; +DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES)); int bfin_special_gpio_request(unsigned gpio, const char *label) { @@ -921,14 +926,14 @@ int bfin_special_gpio_request(unsigned gpio, const char *label) return 0; } - if (unlikely(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(is_reserved(special_gpio, gpio, 1))) { local_irq_restore_hw(flags); printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", gpio, get_label(gpio)); return -EBUSY; } - if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(is_reserved(peri, gpio, 1))) { local_irq_restore_hw(flags); printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", @@ -937,8 +942,8 @@ int bfin_special_gpio_request(unsigned gpio, const char *label) return -EBUSY; } - reserved_special_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); - reserved_peri_map[gpio_bank(gpio)] |= gpio_bit(gpio); + reserve(special_gpio, gpio); + reserve(peri, gpio); set_label(gpio, label); local_irq_restore_hw(flags); @@ -956,14 +961,14 @@ void bfin_special_gpio_free(unsigned gpio) local_irq_save_hw(flags); - if (unlikely(!(reserved_special_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { + if (unlikely(!is_reserved(special_gpio, gpio, 0))) { gpio_error(gpio); local_irq_restore_hw(flags); return; } - reserved_special_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); - reserved_peri_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + unreserve(special_gpio, gpio); + unreserve(peri, gpio); set_label(gpio, "free"); local_irq_restore_hw(flags); } @@ -980,7 +985,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) local_irq_save_hw(flags); - if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(is_reserved(peri, gpio, 1))) { if (system_state == SYSTEM_BOOTING) dump_stack(); printk(KERN_ERR @@ -989,12 +994,12 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) local_irq_restore_hw(flags); return -EBUSY; } - if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) + if (unlikely(is_reserved(gpio, gpio, 1))) printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved by %s! " "(Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio, get_label(gpio)); - reserved_gpio_irq_map[gpio_bank(gpio)] |= gpio_bit(gpio); + reserve(gpio_irq, gpio); set_label(gpio, label); local_irq_restore_hw(flags); @@ -1013,7 +1018,7 @@ void bfin_gpio_irq_free(unsigned gpio) local_irq_save_hw(flags); - if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { + if (unlikely(!is_reserved(gpio_irq, gpio, 0))) { if (system_state == SYSTEM_BOOTING) dump_stack(); gpio_error(gpio); @@ -1021,7 +1026,7 @@ void bfin_gpio_irq_free(unsigned gpio) return; } - reserved_gpio_irq_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); + unreserve(gpio_irq, gpio); set_label(gpio, "free"); @@ -1042,7 +1047,7 @@ int bfin_gpio_direction_input(unsigned gpio) { unsigned long flags; - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(!is_reserved(gpio, gpio, 0))) { gpio_error(gpio); return -EINVAL; } @@ -1084,7 +1089,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value) { unsigned long flags; - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + if (unlikely(!is_reserved(gpio, gpio, 0))) { gpio_error(gpio); return -EINVAL; } @@ -1153,13 +1158,13 @@ static int gpio_proc_read(char *buf, char **start, off_t offset, int c, irq, gpio, outlen = 0; for (c = 0; c < MAX_RESOURCES; c++) { - irq = reserved_gpio_irq_map[gpio_bank(c)] & gpio_bit(c); - gpio = reserved_gpio_map[gpio_bank(c)] & gpio_bit(c); + irq = is_reserved(gpio_irq, c, 1); + gpio = is_reserved(gpio, c, 1); if (!check_gpio(c) && (gpio || irq)) len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c, get_label(c), (gpio && irq) ? " *" : "", get_gpio_dir(c) ? "OUTPUT" : "INPUT"); - else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c)) + else if (is_reserved(peri, c, 1)) len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c)); else continue; |