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

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
...@@ -26,6 +26,7 @@ config BLACKFIN ...@@ -26,6 +26,7 @@ config BLACKFIN
default y default y
select HAVE_IDE select HAVE_IDE
select HAVE_OPROFILE select HAVE_OPROFILE
select ARCH_WANT_OPTIONAL_GPIOLIB
config ZONE_DMA config ZONE_DMA
bool bool
......
...@@ -85,12 +85,11 @@ ...@@ -85,12 +85,11 @@
#define __ARCH_BLACKFIN_GPIO_H__ #define __ARCH_BLACKFIN_GPIO_H__
#define gpio_bank(x) ((x) >> 4) #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_bit(x) (1<<((x) & 0xF))
#define gpio_sub_n(x) ((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_BANKSIZE 16
#define GPIO_BANK_NUM gpio_bank_n(MAX_BLACKFIN_GPIOS)
#define GPIO_0 0 #define GPIO_0 0
#define GPIO_1 1 #define GPIO_1 1
...@@ -546,20 +545,76 @@ struct gpio_port_s { ...@@ -546,20 +545,76 @@ struct gpio_port_s {
* MODIFICATION HISTORY : * MODIFICATION HISTORY :
**************************************************************/ **************************************************************/
int gpio_request(unsigned, const char *);
void gpio_free(unsigned);
void gpio_set_value(unsigned gpio, int arg); int bfin_gpio_request(unsigned gpio, const char *label);
int gpio_get_value(unsigned gpio); 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 #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 #endif
int gpio_direction_input(unsigned gpio); #ifdef CONFIG_GPIOLIB
int gpio_direction_output(unsigned gpio, int value); #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 */ #include <asm-generic/gpio.h> /* cansleep wrappers */
#endif /* !CONFIG_GPIOLIB */
#include <asm/irq.h> #include <asm/irq.h>
static inline int gpio_to_irq(unsigned gpio) static inline int gpio_to_irq(unsigned gpio)
......
...@@ -1020,7 +1020,7 @@ EXPORT_SYMBOL(peripheral_free_list); ...@@ -1020,7 +1020,7 @@ EXPORT_SYMBOL(peripheral_free_list);
* MODIFICATION HISTORY : * MODIFICATION HISTORY :
**************************************************************/ **************************************************************/
int gpio_request(unsigned gpio, const char *label) int bfin_gpio_request(unsigned gpio, const char *label)
{ {
unsigned long flags; unsigned long flags;
...@@ -1065,9 +1065,9 @@ int gpio_request(unsigned gpio, const char *label) ...@@ -1065,9 +1065,9 @@ int gpio_request(unsigned gpio, const char *label)
return 0; 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; unsigned long flags;
...@@ -1089,11 +1089,11 @@ void gpio_free(unsigned gpio) ...@@ -1089,11 +1089,11 @@ void gpio_free(unsigned gpio)
local_irq_restore(flags); local_irq_restore(flags);
} }
EXPORT_SYMBOL(gpio_free); EXPORT_SYMBOL(bfin_gpio_free);
#ifdef BF548_FAMILY #ifdef BF548_FAMILY
int gpio_direction_input(unsigned gpio) int bfin_gpio_direction_input(unsigned gpio)
{ {
unsigned long flags; unsigned long flags;
...@@ -1109,9 +1109,9 @@ int gpio_direction_input(unsigned gpio) ...@@ -1109,9 +1109,9 @@ int gpio_direction_input(unsigned gpio)
return 0; 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; unsigned long flags;
...@@ -1128,22 +1128,22 @@ int gpio_direction_output(unsigned gpio, int value) ...@@ -1128,22 +1128,22 @@ int gpio_direction_output(unsigned gpio, int value)
return 0; 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) if (arg)
gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
else else
gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); 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))); 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) void bfin_gpio_irq_prepare(unsigned gpio)
{ {
...@@ -1159,7 +1159,7 @@ void bfin_gpio_irq_prepare(unsigned gpio) ...@@ -1159,7 +1159,7 @@ void bfin_gpio_irq_prepare(unsigned gpio)
#else #else
int gpio_get_value(unsigned gpio) int bfin_gpio_get_value(unsigned gpio)
{ {
unsigned long flags; unsigned long flags;
int ret; int ret;
...@@ -1175,10 +1175,10 @@ int gpio_get_value(unsigned gpio) ...@@ -1175,10 +1175,10 @@ int gpio_get_value(unsigned gpio)
} else } else
return get_gpio_data(gpio); 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; unsigned long flags;
...@@ -1195,9 +1195,9 @@ int gpio_direction_input(unsigned gpio) ...@@ -1195,9 +1195,9 @@ int gpio_direction_input(unsigned gpio)
return 0; 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; unsigned long flags;
...@@ -1220,7 +1220,7 @@ int gpio_direction_output(unsigned gpio, int value) ...@@ -1220,7 +1220,7 @@ int gpio_direction_output(unsigned gpio, int value)
return 0; 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, /* 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 * the core can reset and execute the bootrom faster than the resistor can
...@@ -1280,3 +1280,57 @@ static __init int gpio_register_proc(void) ...@@ -1280,3 +1280,57 @@ static __init int gpio_register_proc(void)
} }
__initcall(gpio_register_proc); __initcall(gpio_register_proc);
#endif #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
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