aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2008-04-24 08:10:10 +0800
committerBryan Wu <cooloney@kernel.org>2008-04-24 08:10:10 +0800
commitaffee2b2613ada262eecea354b6c60696ca5d482 (patch)
treebc8b5b7a11416f565635b0b135a4438e17e64230 /arch
parenta086ee2268abcfcbf80a114f4602e5b26aa80bf0 (diff)
downloadkernel_samsung_smdk4412-affee2b2613ada262eecea354b6c60696ca5d482.zip
kernel_samsung_smdk4412-affee2b2613ada262eecea354b6c60696ca5d482.tar.gz
kernel_samsung_smdk4412-affee2b2613ada262eecea354b6c60696ca5d482.tar.bz2
[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 <michael.hennerich@analog.com> Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c45
-rw-r--r--arch/blackfin/mach-common/ints-priority.c52
2 files changed, 30 insertions, 67 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index fcb2f6c..7e8eaf4 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 a2a1171..5448230 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