From 3deac046e2883686a732960050ab74fca0db11fa Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 20 Feb 2007 13:58:15 -0800 Subject: [PATCH] [PATCH] GPIO API: PXA wrapper cleanup Based on the discussion last december (http://lkml.org/lkml/2006/12/20/242), this patch: - moves the PXA_LAST_GPIO check into pxa_gpio_mode - fixes comment and includes in gpio.h - replaces the gpio_set/get_value macros with inline functions and adds a non-inline version to avoid code explosion when gpio is not a constant. Signed-off-by: Philipp Zabel Signed-off-by: David Brownell Signed-off-by: Nicolas Pitre Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-pxa/generic.c | 28 ++++++++++++++++++- include/asm-arm/arch-pxa/gpio.h | 42 +++++++++++++++++------------ include/asm-arm/arch-pxa/hardware.h | 12 ++++++++- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 390524c4710f..b8cb79f899d5 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -106,13 +107,16 @@ unsigned long long sched_clock(void) * Handy function to set GPIO alternate functions */ -void pxa_gpio_mode(int gpio_mode) +int pxa_gpio_mode(int gpio_mode) { unsigned long flags; int gpio = gpio_mode & GPIO_MD_MASK_NR; int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; int gafr; + if (gpio > PXA_LAST_GPIO) + return -EINVAL; + local_irq_save(flags); if (gpio_mode & GPIO_DFLT_LOW) GPCR(gpio) = GPIO_bit(gpio); @@ -125,10 +129,32 @@ void pxa_gpio_mode(int gpio_mode) gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); local_irq_restore(flags); + + return 0; } EXPORT_SYMBOL(pxa_gpio_mode); +/* + * Return GPIO level + */ +int pxa_gpio_get_value(unsigned gpio) +{ + return __gpio_get_value(gpio); +} + +EXPORT_SYMBOL(pxa_gpio_get_value); + +/* + * Set output GPIO level + */ +void pxa_gpio_set_value(unsigned gpio, int value) +{ + __gpio_set_value(gpio, value); +} + +EXPORT_SYMBOL(pxa_gpio_set_value); + /* * Routine to safely enable or disable a clock in the CKEN */ diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h index e67c23821017..3d348a351157 100644 --- a/include/asm-arm/arch-pxa/gpio.h +++ b/include/asm-arm/arch-pxa/gpio.h @@ -25,10 +25,8 @@ #define __ASM_ARCH_PXA_GPIO_H #include -#include -#include - -#include +#include +#include static inline int gpio_request(unsigned gpio, const char *label) { @@ -42,26 +40,36 @@ static inline void gpio_free(unsigned gpio) static inline int gpio_direction_input(unsigned gpio) { - if (gpio > PXA_LAST_GPIO) - return -EINVAL; - pxa_gpio_mode(gpio | GPIO_IN); + return pxa_gpio_mode(gpio | GPIO_IN); } static inline int gpio_direction_output(unsigned gpio) { - if (gpio > PXA_LAST_GPIO) - return -EINVAL; - pxa_gpio_mode(gpio | GPIO_OUT); + return pxa_gpio_mode(gpio | GPIO_OUT); } -/* REVISIT these macros are correct, but suffer code explosion - * for non-constant parameters. Provide out-line versions too. - */ -#define gpio_get_value(gpio) \ - (GPLR(gpio) & GPIO_bit(gpio)) +static inline int __gpio_get_value(unsigned gpio) +{ + return GPLR(gpio) & GPIO_bit(gpio); +} + +#define gpio_get_value(gpio) \ + (__builtin_constant_p(gpio) ? \ + __gpio_get_value(gpio) : \ + pxa_gpio_get_value(gpio)) + +static inline void __gpio_set_value(unsigned gpio, int value) +{ + if (value) + GPSR(gpio) = GPIO_bit(gpio); + else + GPCR(gpio) = GPIO_bit(gpio); +} -#define gpio_set_value(gpio,value) \ - ((value) ? (GPSR(gpio) = GPIO_bit(gpio)):(GPCR(gpio) = GPIO_bit(gpio))) +#define gpio_set_value(gpio,value) \ + (__builtin_constant_p(gpio) ? \ + __gpio_set_value(gpio, value) : \ + pxa_gpio_set_value(gpio, value)) #include /* cansleep wrappers */ diff --git a/include/asm-arm/arch-pxa/hardware.h b/include/asm-arm/arch-pxa/hardware.h index 3e70bd95472c..e2bdc2fbede1 100644 --- a/include/asm-arm/arch-pxa/hardware.h +++ b/include/asm-arm/arch-pxa/hardware.h @@ -65,7 +65,17 @@ /* * Handy routine to set GPIO alternate functions */ -extern void pxa_gpio_mode( int gpio_mode ); +extern int pxa_gpio_mode( int gpio_mode ); + +/* + * Return GPIO level, nonzero means high, zero is low + */ +extern int pxa_gpio_get_value(unsigned gpio); + +/* + * Set output GPIO level + */ +extern void pxa_gpio_set_value(unsigned gpio, int value); /* * Routine to enable or disable CKEN -- GitLab