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

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

Blackfin arch: Convert Blackfin GPIO driver to use common gpiolib/gpiochip infrastructure



 - This patch adds support for ARCH_WANT_OPTIONAL_GPIOLIB.
 - It may be changed in future to ARCH_REQUIRE_GPIOLIB.
 - Change GPIO_BANK_NUM use DIV_ROUND_UP( , ) macro

Signed-off-by: default avatarMichael Hennerich <michael.hennerich@analog.com>
Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
parent 8d022374
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ config BLACKFIN
	default y
	select HAVE_IDE
	select HAVE_OPROFILE
	select ARCH_WANT_OPTIONAL_GPIOLIB

config ZONE_DMA
	bool
+67 −12
Original line number Diff line number Diff line
@@ -85,12 +85,11 @@
#define __ARCH_BLACKFIN_GPIO_H__

#define gpio_bank(x) 	((x) >> 4)
#define gpio_bank_n(x) ((x) & 0xF ? ((x) >> 4) + 1 : (x) >> 4)
#define gpio_bit(x)  	(1<<((x) & 0xF))
#define gpio_sub_n(x) 	((x) & 0xF)
#define GPIO_BANK_NUM 	DIV_ROUND_UP(MAX_BLACKFIN_GPIOS, 16)

#define GPIO_BANKSIZE 16
#define GPIO_BANK_NUM gpio_bank_n(MAX_BLACKFIN_GPIOS)

#define	GPIO_0	0
#define	GPIO_1	1
@@ -546,20 +545,76 @@ struct gpio_port_s {
* MODIFICATION HISTORY :
**************************************************************/

int gpio_request(unsigned, const char *);
void gpio_free(unsigned);

void gpio_set_value(unsigned gpio, int arg);
int gpio_get_value(unsigned gpio);
int bfin_gpio_request(unsigned gpio, const char *label);
void bfin_gpio_free(unsigned gpio);
int bfin_gpio_direction_input(unsigned gpio);
int bfin_gpio_direction_output(unsigned gpio, int value);
int bfin_gpio_get_value(unsigned gpio);
void bfin_gpio_set_value(unsigned gpio, int value);

#ifndef BF548_FAMILY
#define gpio_set_value(gpio, value)	set_gpio_data(gpio, value)
#define bfin_gpio_set_value(gpio, value)    set_gpio_data(gpio, value)
#endif

int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
#ifdef CONFIG_GPIOLIB
#include <asm-generic/gpio.h>		/* cansleep wrappers */

static inline int gpio_get_value(unsigned int gpio)
{
	if (gpio < MAX_BLACKFIN_GPIOS)
		return bfin_gpio_get_value(gpio);
	else
		return __gpio_get_value(gpio);
}

static inline void gpio_set_value(unsigned int gpio, int value)
{
	if (gpio < MAX_BLACKFIN_GPIOS)
		bfin_gpio_set_value(gpio, value);
	else
		__gpio_set_value(gpio, value);
}

static inline int gpio_cansleep(unsigned int gpio)
{
	return __gpio_cansleep(gpio);
}

#else /* !CONFIG_GPIOLIB */

static inline int gpio_request(unsigned gpio, const char *label)
{
	return bfin_gpio_request(gpio, label);
}

static inline void gpio_free(unsigned gpio)
{
	return bfin_gpio_free(gpio);
}

static inline int gpio_direction_input(unsigned gpio)
{
	return bfin_gpio_direction_input(gpio);
}

static inline int gpio_direction_output(unsigned gpio, int value)
{
	return bfin_gpio_direction_output(gpio, value);
}

static inline int gpio_get_value(unsigned gpio)
{
	return bfin_gpio_get_value(gpio);
}

static inline void gpio_set_value(unsigned gpio, int value)
{
	return bfin_gpio_set_value(gpio, value);
}

#include <asm-generic/gpio.h>		/* cansleep wrappers */
#endif	/* !CONFIG_GPIOLIB */
#include <asm/irq.h>

static inline int gpio_to_irq(unsigned gpio)
+72 −18
Original line number Diff line number Diff line
@@ -1020,7 +1020,7 @@ EXPORT_SYMBOL(peripheral_free_list);
* MODIFICATION HISTORY :
**************************************************************/

int gpio_request(unsigned gpio, const char *label)
int bfin_gpio_request(unsigned gpio, const char *label)
{
	unsigned long flags;

@@ -1065,9 +1065,9 @@ int gpio_request(unsigned gpio, const char *label)

	return 0;
}
EXPORT_SYMBOL(gpio_request);
EXPORT_SYMBOL(bfin_gpio_request);

void gpio_free(unsigned gpio)
void bfin_gpio_free(unsigned gpio)
{
	unsigned long flags;

@@ -1089,11 +1089,11 @@ void gpio_free(unsigned gpio)

	local_irq_restore(flags);
}
EXPORT_SYMBOL(gpio_free);
EXPORT_SYMBOL(bfin_gpio_free);


#ifdef BF548_FAMILY
int gpio_direction_input(unsigned gpio)
int bfin_gpio_direction_input(unsigned gpio)
{
	unsigned long flags;

@@ -1109,9 +1109,9 @@ int gpio_direction_input(unsigned gpio)

	return 0;
}
EXPORT_SYMBOL(gpio_direction_input);
EXPORT_SYMBOL(bfin_gpio_direction_input);

int gpio_direction_output(unsigned gpio, int value)
int bfin_gpio_direction_output(unsigned gpio, int value)
{
	unsigned long flags;

@@ -1128,22 +1128,22 @@ int gpio_direction_output(unsigned gpio, int value)

	return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
EXPORT_SYMBOL(bfin_gpio_direction_output);

void gpio_set_value(unsigned gpio, int arg)
void bfin_gpio_set_value(unsigned gpio, int arg)
{
	if (arg)
		gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
	else
		gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
}
EXPORT_SYMBOL(gpio_set_value);
EXPORT_SYMBOL(bfin_gpio_set_value);

int gpio_get_value(unsigned gpio)
int bfin_gpio_get_value(unsigned gpio)
{
	return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
}
EXPORT_SYMBOL(gpio_get_value);
EXPORT_SYMBOL(bfin_gpio_get_value);

void bfin_gpio_irq_prepare(unsigned gpio)
{
@@ -1159,7 +1159,7 @@ void bfin_gpio_irq_prepare(unsigned gpio)

#else

int gpio_get_value(unsigned gpio)
int bfin_gpio_get_value(unsigned gpio)
{
	unsigned long flags;
	int ret;
@@ -1175,10 +1175,10 @@ int gpio_get_value(unsigned gpio)
	} else
		return get_gpio_data(gpio);
}
EXPORT_SYMBOL(gpio_get_value);
EXPORT_SYMBOL(bfin_gpio_get_value);


int gpio_direction_input(unsigned gpio)
int bfin_gpio_direction_input(unsigned gpio)
{
	unsigned long flags;

@@ -1195,9 +1195,9 @@ int gpio_direction_input(unsigned gpio)

	return 0;
}
EXPORT_SYMBOL(gpio_direction_input);
EXPORT_SYMBOL(bfin_gpio_direction_input);

int gpio_direction_output(unsigned gpio, int value)
int bfin_gpio_direction_output(unsigned gpio, int value)
{
	unsigned long flags;

@@ -1220,7 +1220,7 @@ int gpio_direction_output(unsigned gpio, int value)

	return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
EXPORT_SYMBOL(bfin_gpio_direction_output);

/* If we are booting from SPI and our board lacks a strong enough pull up,
 * the core can reset and execute the bootrom faster than the resistor can
@@ -1280,3 +1280,57 @@ static __init int gpio_register_proc(void)
}
__initcall(gpio_register_proc);
#endif

#ifdef CONFIG_GPIOLIB
int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
{
	return bfin_gpio_direction_input(gpio);
}

int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
{
	return bfin_gpio_direction_output(gpio, level);
}

int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
{
	return bfin_gpio_get_value(gpio);
}

void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
{
#ifdef BF548_FAMILY
	return bfin_gpio_set_value(gpio, value);
#else
	return set_gpio_data(gpio, value);
#endif
}

int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
{
	return bfin_gpio_request(gpio, chip->label);
}

void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
{
	return bfin_gpio_free(gpio);
}

static struct gpio_chip bfin_chip = {
	.label			= "Blackfin-GPIOlib",
	.direction_input	= bfin_gpiolib_direction_input,
	.get			= bfin_gpiolib_get_value,
	.direction_output	= bfin_gpiolib_direction_output,
	.set			= bfin_gpiolib_set_value,
	.request		= bfin_gpiolib_gpio_request,
	.free			= bfin_gpiolib_gpio_free,
	.base			= 0,
	.ngpio			= MAX_BLACKFIN_GPIOS,
};

static int __init bfin_gpiolib_setup(void)
{
	return gpiochip_add(&bfin_chip);
}
arch_initcall(bfin_gpiolib_setup);
#endif