Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit affee2b2 authored by Michael Hennerich's avatar Michael Hennerich Committed by Bryan Wu
Browse files

[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: default avatarMichael Hennerich <michael.hennerich@analog.com>
Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
parent a086ee22
Loading
Loading
Loading
Loading
+17 −28
Original line number Diff line number Diff line
@@ -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)
+13 −39
Original line number Diff line number Diff line
@@ -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