Commit 332824b8 authored by Mike Frysinger's avatar Mike Frysinger

Blackfin: gpio: unify & clean up reserved map handling

The duplicated bit banging logic is getting out of hand, so unify the
local API to make management a lot easier.  This also makes the code
a lot easier to follow.
Signed-off-by: default avatarMike Frysinger <vapier@gentoo.org>
parent 74181295
...@@ -108,10 +108,6 @@ static unsigned short * const port_fer[] = { ...@@ -108,10 +108,6 @@ static unsigned short * const port_fer[] = {
}; };
#endif #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 { static struct str_ident {
...@@ -122,19 +118,6 @@ static struct str_ident { ...@@ -122,19 +118,6 @@ static struct str_ident {
static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
#endif #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) static void gpio_error(unsigned gpio)
{ {
printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", 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) ...@@ -167,6 +150,29 @@ static int cmp_label(unsigned short ident, const char *label)
return -EINVAL; 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, gpio_bank(MAX_RESOURCES));
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) static void port_setup(unsigned gpio, unsigned short usage)
{ {
#if defined(BF538_FAMILY) #if defined(BF538_FAMILY)
...@@ -475,7 +481,7 @@ GET_GPIO_P(maskb) ...@@ -475,7 +481,7 @@ GET_GPIO_P(maskb)
#ifdef CONFIG_PM #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[] = { static const unsigned int sic_iwr_irqs[] = {
#if defined(BF533_FAMILY) #if defined(BF533_FAMILY)
...@@ -521,9 +527,9 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) ...@@ -521,9 +527,9 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl)
local_irq_save_hw(flags); local_irq_save_hw(flags);
if (ctrl) if (ctrl)
wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); reserve(wakeup, gpio);
else else
wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); unreserve(wakeup, gpio);
set_gpio_maskb(gpio, ctrl); set_gpio_maskb(gpio, ctrl);
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
...@@ -536,7 +542,7 @@ int bfin_pm_standby_ctrl(unsigned ctrl) ...@@ -536,7 +542,7 @@ int bfin_pm_standby_ctrl(unsigned ctrl)
u16 bank, mask, i; u16 bank, mask, i;
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { 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); bank = gpio_bank(i);
if (mask) if (mask)
...@@ -689,8 +695,7 @@ int peripheral_request(unsigned short per, const char *label) ...@@ -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 /* If a pin can be muxed as either GPIO or peripheral, make
* sure it is not already a GPIO pin when we request it. * sure it is not already a GPIO pin when we request it.
*/ */
if (unlikely(!check_gpio(ident) && if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
if (system_state == SYSTEM_BOOTING) if (system_state == SYSTEM_BOOTING)
dump_stack(); dump_stack();
printk(KERN_ERR printk(KERN_ERR
...@@ -700,7 +705,7 @@ int peripheral_request(unsigned short per, const char *label) ...@@ -700,7 +705,7 @@ int peripheral_request(unsigned short per, const char *label)
return -EBUSY; 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 * Pin functions like AMC address strobes my
...@@ -731,7 +736,7 @@ int peripheral_request(unsigned short per, const char *label) ...@@ -731,7 +736,7 @@ int peripheral_request(unsigned short per, const char *label)
} }
anyway: anyway:
reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); reserve(peri, ident);
portmux_setup(per); portmux_setup(per);
port_setup(ident, PERIPHERAL_USAGE); port_setup(ident, PERIPHERAL_USAGE);
...@@ -777,7 +782,7 @@ void peripheral_free(unsigned short per) ...@@ -777,7 +782,7 @@ void peripheral_free(unsigned short per)
local_irq_save_hw(flags); 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); local_irq_restore_hw(flags);
return; return;
} }
...@@ -785,7 +790,7 @@ void peripheral_free(unsigned short per) ...@@ -785,7 +790,7 @@ void peripheral_free(unsigned short per)
if (!(per & P_MAYSHARE)) if (!(per & P_MAYSHARE))
port_setup(ident, GPIO_USAGE); port_setup(ident, GPIO_USAGE);
reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident); unreserve(peri, ident);
set_label(ident, "free"); set_label(ident, "free");
...@@ -836,7 +841,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) ...@@ -836,7 +841,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
return 0; 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) if (system_state == SYSTEM_BOOTING)
dump_stack(); dump_stack();
printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", 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) ...@@ -844,7 +849,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
return -EBUSY; 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) if (system_state == SYSTEM_BOOTING)
dump_stack(); dump_stack();
printk(KERN_ERR printk(KERN_ERR
...@@ -853,7 +858,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) ...@@ -853,7 +858,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
return -EBUSY; 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!" printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
" (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
} }
...@@ -863,7 +868,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) ...@@ -863,7 +868,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
} }
#endif #endif
reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); reserve(gpio, gpio);
set_label(gpio, label); set_label(gpio, label);
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
...@@ -885,7 +890,7 @@ void bfin_gpio_free(unsigned gpio) ...@@ -885,7 +890,7 @@ void bfin_gpio_free(unsigned gpio)
local_irq_save_hw(flags); 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) if (system_state == SYSTEM_BOOTING)
dump_stack(); dump_stack();
gpio_error(gpio); gpio_error(gpio);
...@@ -893,7 +898,7 @@ void bfin_gpio_free(unsigned gpio) ...@@ -893,7 +898,7 @@ void bfin_gpio_free(unsigned gpio)
return; return;
} }
reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); unreserve(gpio, gpio);
set_label(gpio, "free"); set_label(gpio, "free");
...@@ -902,7 +907,7 @@ void bfin_gpio_free(unsigned gpio) ...@@ -902,7 +907,7 @@ void bfin_gpio_free(unsigned gpio)
EXPORT_SYMBOL(bfin_gpio_free); EXPORT_SYMBOL(bfin_gpio_free);
#ifdef BFIN_SPECIAL_GPIO_BANKS #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) int bfin_special_gpio_request(unsigned gpio, const char *label)
{ {
...@@ -921,14 +926,14 @@ 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; 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); local_irq_restore_hw(flags);
printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
gpio, get_label(gpio)); gpio, get_label(gpio));
return -EBUSY; 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); local_irq_restore_hw(flags);
printk(KERN_ERR printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", "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) ...@@ -937,8 +942,8 @@ int bfin_special_gpio_request(unsigned gpio, const char *label)
return -EBUSY; return -EBUSY;
} }
reserved_special_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); reserve(special_gpio, gpio);
reserved_peri_map[gpio_bank(gpio)] |= gpio_bit(gpio); reserve(peri, gpio);
set_label(gpio, label); set_label(gpio, label);
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
...@@ -956,14 +961,14 @@ void bfin_special_gpio_free(unsigned gpio) ...@@ -956,14 +961,14 @@ void bfin_special_gpio_free(unsigned gpio)
local_irq_save_hw(flags); 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); gpio_error(gpio);
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
return; return;
} }
reserved_special_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); unreserve(special_gpio, gpio);
reserved_peri_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); unreserve(peri, gpio);
set_label(gpio, "free"); set_label(gpio, "free");
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
} }
...@@ -980,7 +985,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) ...@@ -980,7 +985,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
local_irq_save_hw(flags); 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) if (system_state == SYSTEM_BOOTING)
dump_stack(); dump_stack();
printk(KERN_ERR printk(KERN_ERR
...@@ -989,12 +994,12 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) ...@@ -989,12 +994,12 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
return -EBUSY; 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! " printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved by %s! "
"(Documentation/blackfin/bfin-gpio-notes.txt)\n", "(Documentation/blackfin/bfin-gpio-notes.txt)\n",
gpio, get_label(gpio)); gpio, get_label(gpio));
reserved_gpio_irq_map[gpio_bank(gpio)] |= gpio_bit(gpio); reserve(gpio_irq, gpio);
set_label(gpio, label); set_label(gpio, label);
local_irq_restore_hw(flags); local_irq_restore_hw(flags);
...@@ -1013,7 +1018,7 @@ void bfin_gpio_irq_free(unsigned gpio) ...@@ -1013,7 +1018,7 @@ void bfin_gpio_irq_free(unsigned gpio)
local_irq_save_hw(flags); 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) if (system_state == SYSTEM_BOOTING)
dump_stack(); dump_stack();
gpio_error(gpio); gpio_error(gpio);
...@@ -1021,7 +1026,7 @@ void bfin_gpio_irq_free(unsigned gpio) ...@@ -1021,7 +1026,7 @@ void bfin_gpio_irq_free(unsigned gpio)
return; return;
} }
reserved_gpio_irq_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); unreserve(gpio_irq, gpio);
set_label(gpio, "free"); set_label(gpio, "free");
...@@ -1042,7 +1047,7 @@ int bfin_gpio_direction_input(unsigned gpio) ...@@ -1042,7 +1047,7 @@ int bfin_gpio_direction_input(unsigned gpio)
{ {
unsigned long flags; unsigned long flags;
if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { if (unlikely(!is_reserved(gpio, gpio, 0))) {
gpio_error(gpio); gpio_error(gpio);
return -EINVAL; return -EINVAL;
} }
...@@ -1084,7 +1089,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value) ...@@ -1084,7 +1089,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
{ {
unsigned long flags; unsigned long flags;
if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { if (unlikely(!is_reserved(gpio, gpio, 0))) {
gpio_error(gpio); gpio_error(gpio);
return -EINVAL; return -EINVAL;
} }
...@@ -1153,13 +1158,13 @@ static int gpio_proc_read(char *buf, char **start, off_t offset, ...@@ -1153,13 +1158,13 @@ static int gpio_proc_read(char *buf, char **start, off_t offset,
int c, irq, gpio, outlen = 0; int c, irq, gpio, outlen = 0;
for (c = 0; c < MAX_RESOURCES; c++) { for (c = 0; c < MAX_RESOURCES; c++) {
irq = reserved_gpio_irq_map[gpio_bank(c)] & gpio_bit(c); irq = is_reserved(gpio_irq, c, 1);
gpio = reserved_gpio_map[gpio_bank(c)] & gpio_bit(c); gpio = is_reserved(gpio, c, 1);
if (!check_gpio(c) && (gpio || irq)) if (!check_gpio(c) && (gpio || irq))
len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c, len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c,
get_label(c), (gpio && irq) ? " *" : "", get_label(c), (gpio && irq) ? " *" : "",
get_gpio_dir(c) ? "OUTPUT" : "INPUT"); 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)); len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c));
else else
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment