From: Michael Hennerich Date: Thu, 24 Apr 2008 00:10:10 +0000 (+0800) Subject: [Blackfin] arch: Allow concurrent use of GPIO and GPIO IRQ X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=affee2b2613ada262eecea354b6c60696ca5d482;p=linux-2.6 [Blackfin] arch: Allow concurrent use of GPIO and GPIO IRQ The irq setup code no longer calls gpio request and free. This patch also changes the default gpio_free behavior on Blackfin. A freed GPIO keeps it's last state, and is not defaulted back to an input. This is also what all other architectures do. Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu --- diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index fcb2f6cf43..7e8eaf4a31 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -395,32 +395,6 @@ inline void portmux_setup(unsigned short portno, unsigned short function) # define portmux_setup(...) do { } while (0) #endif -#ifndef BF548_FAMILY -static void default_gpio(unsigned gpio) -{ - unsigned short bank, bitmask; - unsigned long flags; - - bank = gpio_bank(gpio); - bitmask = gpio_bit(gpio); - - local_irq_save(flags); - - gpio_bankb[bank]->maska_clear = bitmask; - gpio_bankb[bank]->maskb_clear = bitmask; - SSYNC(); - gpio_bankb[bank]->inen &= ~bitmask; - gpio_bankb[bank]->dir &= ~bitmask; - gpio_bankb[bank]->polar &= ~bitmask; - gpio_bankb[bank]->both &= ~bitmask; - gpio_bankb[bank]->edge &= ~bitmask; - AWA_DUMMY_READ(edge); - local_irq_restore(flags); -} -#else -# define default_gpio(...) do { } while (0) -#endif - static int __init bfin_gpio_init(void) { printk(KERN_INFO "Blackfin GPIO Controller\n"); @@ -1080,8 +1054,6 @@ void gpio_free(unsigned gpio) return; } - default_gpio(gpio); - reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); set_label(gpio, "free"); @@ -1144,6 +1116,18 @@ int gpio_get_value(unsigned gpio) } EXPORT_SYMBOL(gpio_get_value); +void bfin_gpio_irq_prepare(unsigned gpio) +{ + unsigned long flags; + + port_setup(gpio, GPIO_USAGE); + + local_irq_save(flags); + gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); + local_irq_restore(flags); +} + #else int gpio_direction_input(unsigned gpio) @@ -1210,6 +1194,11 @@ void bfin_gpio_reset_spi0_ssel1(void) udelay(1); } +void bfin_gpio_irq_prepare(unsigned gpio) +{ + port_setup(gpio, GPIO_USAGE); +} + #endif /*BF548_FAMILY */ #if defined(CONFIG_PROC_FS) diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index a2a11717bf..5448230c0e 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -326,6 +326,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq, static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; +extern void bfin_gpio_irq_prepare(unsigned gpio); static void bfin_gpio_ack_irq(unsigned int irq) { @@ -364,35 +365,25 @@ static void bfin_gpio_unmask_irq(unsigned int irq) static unsigned int bfin_gpio_irq_startup(unsigned int irq) { - unsigned int ret; u16 gpionr = irq - IRQ_PF0; - char buf[8]; - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - snprintf(buf, sizeof buf, "IRQ %d", irq); - ret = gpio_request(gpionr, buf); - if (ret) - return ret; - } + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) + bfin_gpio_irq_prepare(gpionr); gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); bfin_gpio_unmask_irq(irq); - return ret; + return 0; } static void bfin_gpio_irq_shutdown(unsigned int irq) { bfin_gpio_mask_irq(irq); - gpio_free(irq - IRQ_PF0); gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); } static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) { - - unsigned int ret; - char buf[8]; u16 gpionr = irq - IRQ_PF0; if (type == IRQ_TYPE_PROBE) { @@ -404,12 +395,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - snprintf(buf, sizeof buf, "IRQ %d", irq); - ret = gpio_request(gpionr, buf); - if (ret) - return ret; - } + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) + bfin_gpio_irq_prepare(gpionr); gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); } else { @@ -595,6 +582,8 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { (struct pin_int_t *)PINT3_MASK_SET, }; +extern void bfin_gpio_irq_prepare(unsigned gpio); + inline unsigned short get_irq_base(u8 bank, u8 bmap) { @@ -697,8 +686,6 @@ static void bfin_gpio_unmask_irq(unsigned int irq) static unsigned int bfin_gpio_irq_startup(unsigned int irq) { - unsigned int ret; - char buf[8]; u16 gpionr = irq_to_gpio(irq); u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; @@ -709,17 +696,13 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq) return -ENODEV; } - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - snprintf(buf, sizeof buf, "IRQ %d", irq); - ret = gpio_request(gpionr, buf); - if (ret) - return ret; - } + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) + bfin_gpio_irq_prepare(gpionr); gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); bfin_gpio_unmask_irq(irq); - return ret; + return 0; } static void bfin_gpio_irq_shutdown(unsigned int irq) @@ -727,15 +710,12 @@ static void bfin_gpio_irq_shutdown(unsigned int irq) u16 gpionr = irq_to_gpio(irq); bfin_gpio_mask_irq(irq); - gpio_free(gpionr); gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); } static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) { - unsigned int ret; - char buf[8]; u16 gpionr = irq_to_gpio(irq); u8 pint_val = irq2pint_lut[irq - SYS_IRQS]; u32 pintbit = PINT_BIT(pint_val); @@ -753,12 +733,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - snprintf(buf, sizeof buf, "IRQ %d", irq); - ret = gpio_request(gpionr, buf); - if (ret) - return ret; - } + if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) + bfin_gpio_irq_prepare(gpionr); gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); } else { @@ -766,8 +742,6 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) return 0; } - gpio_direction_input(gpionr); - if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) pint[bank]->invert_set = pintbit; /* low or falling edge denoted by one */ else