Commit 3deac046 authored by Philipp Zabel's avatar Philipp Zabel Committed by Linus Torvalds

[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: default avatarPhilipp Zabel <philipp.zabel@gmail.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5d4675a8
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#include <asm/arch/gpio.h>
#include <asm/arch/udc.h> #include <asm/arch/udc.h>
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h> #include <asm/arch/mmc.h>
...@@ -106,13 +107,16 @@ unsigned long long sched_clock(void) ...@@ -106,13 +107,16 @@ unsigned long long sched_clock(void)
* Handy function to set GPIO alternate functions * Handy function to set GPIO alternate functions
*/ */
void pxa_gpio_mode(int gpio_mode) int pxa_gpio_mode(int gpio_mode)
{ {
unsigned long flags; unsigned long flags;
int gpio = gpio_mode & GPIO_MD_MASK_NR; int gpio = gpio_mode & GPIO_MD_MASK_NR;
int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
int gafr; int gafr;
if (gpio > PXA_LAST_GPIO)
return -EINVAL;
local_irq_save(flags); local_irq_save(flags);
if (gpio_mode & GPIO_DFLT_LOW) if (gpio_mode & GPIO_DFLT_LOW)
GPCR(gpio) = GPIO_bit(gpio); GPCR(gpio) = GPIO_bit(gpio);
...@@ -125,10 +129,32 @@ void pxa_gpio_mode(int gpio_mode) ...@@ -125,10 +129,32 @@ void pxa_gpio_mode(int gpio_mode)
gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
local_irq_restore(flags); local_irq_restore(flags);
return 0;
} }
EXPORT_SYMBOL(pxa_gpio_mode); 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 * Routine to safely enable or disable a clock in the CKEN
*/ */
......
...@@ -25,10 +25,8 @@ ...@@ -25,10 +25,8 @@
#define __ASM_ARCH_PXA_GPIO_H #define __ASM_ARCH_PXA_GPIO_H
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#include <asm/arch/irqs.h> #include <asm/irq.h>
#include <asm/arch/hardware.h> #include <asm/hardware.h>
#include <asm/errno.h>
static inline int gpio_request(unsigned gpio, const char *label) static inline int gpio_request(unsigned gpio, const char *label)
{ {
...@@ -42,26 +40,36 @@ static inline void gpio_free(unsigned gpio) ...@@ -42,26 +40,36 @@ static inline void gpio_free(unsigned gpio)
static inline int gpio_direction_input(unsigned gpio) static inline int gpio_direction_input(unsigned gpio)
{ {
if (gpio > PXA_LAST_GPIO) return pxa_gpio_mode(gpio | GPIO_IN);
return -EINVAL;
pxa_gpio_mode(gpio | GPIO_IN);
} }
static inline int gpio_direction_output(unsigned gpio) static inline int gpio_direction_output(unsigned gpio)
{ {
if (gpio > PXA_LAST_GPIO) return pxa_gpio_mode(gpio | GPIO_OUT);
return -EINVAL;
pxa_gpio_mode(gpio | GPIO_OUT);
} }
/* REVISIT these macros are correct, but suffer code explosion static inline int __gpio_get_value(unsigned gpio)
* for non-constant parameters. Provide out-line versions too. {
*/ return GPLR(gpio) & GPIO_bit(gpio);
#define gpio_get_value(gpio) \ }
(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) \ #define gpio_set_value(gpio,value) \
((value) ? (GPSR(gpio) = GPIO_bit(gpio)):(GPCR(gpio) = GPIO_bit(gpio))) (__builtin_constant_p(gpio) ? \
__gpio_set_value(gpio, value) : \
pxa_gpio_set_value(gpio, value))
#include <asm-generic/gpio.h> /* cansleep wrappers */ #include <asm-generic/gpio.h> /* cansleep wrappers */
......
...@@ -65,7 +65,17 @@ ...@@ -65,7 +65,17 @@
/* /*
* Handy routine to set GPIO alternate functions * 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 * Routine to enable or disable CKEN
......
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