diff options
author | Philipp Zabel <philipp.zabel@gmail.com> | 2007-02-20 16:58:15 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-20 20:10:16 -0500 |
commit | 3deac046e2883686a732960050ab74fca0db11fa (patch) | |
tree | de8e8b19148d201147f8be4084efba156f9e6709 | |
parent | 5d4675a811fb71fd922109d7ebae3f987401ace1 (diff) |
[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 <philipp.zabel@gmail.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Nicolas Pitre <nico@cam.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/arm/mach-pxa/generic.c | 28 | ||||
-rw-r--r-- | include/asm-arm/arch-pxa/gpio.h | 42 | ||||
-rw-r--r-- | 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 @@ | |||
36 | #include <asm/mach/map.h> | 36 | #include <asm/mach/map.h> |
37 | 37 | ||
38 | #include <asm/arch/pxa-regs.h> | 38 | #include <asm/arch/pxa-regs.h> |
39 | #include <asm/arch/gpio.h> | ||
39 | #include <asm/arch/udc.h> | 40 | #include <asm/arch/udc.h> |
40 | #include <asm/arch/pxafb.h> | 41 | #include <asm/arch/pxafb.h> |
41 | #include <asm/arch/mmc.h> | 42 | #include <asm/arch/mmc.h> |
@@ -106,13 +107,16 @@ unsigned long long sched_clock(void) | |||
106 | * Handy function to set GPIO alternate functions | 107 | * Handy function to set GPIO alternate functions |
107 | */ | 108 | */ |
108 | 109 | ||
109 | void pxa_gpio_mode(int gpio_mode) | 110 | int pxa_gpio_mode(int gpio_mode) |
110 | { | 111 | { |
111 | unsigned long flags; | 112 | unsigned long flags; |
112 | int gpio = gpio_mode & GPIO_MD_MASK_NR; | 113 | int gpio = gpio_mode & GPIO_MD_MASK_NR; |
113 | int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; | 114 | int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8; |
114 | int gafr; | 115 | int gafr; |
115 | 116 | ||
117 | if (gpio > PXA_LAST_GPIO) | ||
118 | return -EINVAL; | ||
119 | |||
116 | local_irq_save(flags); | 120 | local_irq_save(flags); |
117 | if (gpio_mode & GPIO_DFLT_LOW) | 121 | if (gpio_mode & GPIO_DFLT_LOW) |
118 | GPCR(gpio) = GPIO_bit(gpio); | 122 | GPCR(gpio) = GPIO_bit(gpio); |
@@ -125,11 +129,33 @@ void pxa_gpio_mode(int gpio_mode) | |||
125 | gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); | 129 | gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2)); |
126 | GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); | 130 | GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2)); |
127 | local_irq_restore(flags); | 131 | local_irq_restore(flags); |
132 | |||
133 | return 0; | ||
128 | } | 134 | } |
129 | 135 | ||
130 | EXPORT_SYMBOL(pxa_gpio_mode); | 136 | EXPORT_SYMBOL(pxa_gpio_mode); |
131 | 137 | ||
132 | /* | 138 | /* |
139 | * Return GPIO level | ||
140 | */ | ||
141 | int pxa_gpio_get_value(unsigned gpio) | ||
142 | { | ||
143 | return __gpio_get_value(gpio); | ||
144 | } | ||
145 | |||
146 | EXPORT_SYMBOL(pxa_gpio_get_value); | ||
147 | |||
148 | /* | ||
149 | * Set output GPIO level | ||
150 | */ | ||
151 | void pxa_gpio_set_value(unsigned gpio, int value) | ||
152 | { | ||
153 | __gpio_set_value(gpio, value); | ||
154 | } | ||
155 | |||
156 | EXPORT_SYMBOL(pxa_gpio_set_value); | ||
157 | |||
158 | /* | ||
133 | * Routine to safely enable or disable a clock in the CKEN | 159 | * Routine to safely enable or disable a clock in the CKEN |
134 | */ | 160 | */ |
135 | void pxa_set_cken(int clock, int enable) | 161 | void pxa_set_cken(int clock, int enable) |
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 @@ | |||
25 | #define __ASM_ARCH_PXA_GPIO_H | 25 | #define __ASM_ARCH_PXA_GPIO_H |
26 | 26 | ||
27 | #include <asm/arch/pxa-regs.h> | 27 | #include <asm/arch/pxa-regs.h> |
28 | #include <asm/arch/irqs.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/arch/hardware.h> | 29 | #include <asm/hardware.h> |
30 | |||
31 | #include <asm/errno.h> | ||
32 | 30 | ||
33 | static inline int gpio_request(unsigned gpio, const char *label) | 31 | static inline int gpio_request(unsigned gpio, const char *label) |
34 | { | 32 | { |
@@ -42,26 +40,36 @@ static inline void gpio_free(unsigned gpio) | |||
42 | 40 | ||
43 | static inline int gpio_direction_input(unsigned gpio) | 41 | static inline int gpio_direction_input(unsigned gpio) |
44 | { | 42 | { |
45 | if (gpio > PXA_LAST_GPIO) | 43 | return pxa_gpio_mode(gpio | GPIO_IN); |
46 | return -EINVAL; | ||
47 | pxa_gpio_mode(gpio | GPIO_IN); | ||
48 | } | 44 | } |
49 | 45 | ||
50 | static inline int gpio_direction_output(unsigned gpio) | 46 | static inline int gpio_direction_output(unsigned gpio) |
51 | { | 47 | { |
52 | if (gpio > PXA_LAST_GPIO) | 48 | return pxa_gpio_mode(gpio | GPIO_OUT); |
53 | return -EINVAL; | ||
54 | pxa_gpio_mode(gpio | GPIO_OUT); | ||
55 | } | 49 | } |
56 | 50 | ||
57 | /* REVISIT these macros are correct, but suffer code explosion | 51 | static inline int __gpio_get_value(unsigned gpio) |
58 | * for non-constant parameters. Provide out-line versions too. | 52 | { |
59 | */ | 53 | return GPLR(gpio) & GPIO_bit(gpio); |
60 | #define gpio_get_value(gpio) \ | 54 | } |
61 | (GPLR(gpio) & GPIO_bit(gpio)) | 55 | |
56 | #define gpio_get_value(gpio) \ | ||
57 | (__builtin_constant_p(gpio) ? \ | ||
58 | __gpio_get_value(gpio) : \ | ||
59 | pxa_gpio_get_value(gpio)) | ||
60 | |||
61 | static inline void __gpio_set_value(unsigned gpio, int value) | ||
62 | { | ||
63 | if (value) | ||
64 | GPSR(gpio) = GPIO_bit(gpio); | ||
65 | else | ||
66 | GPCR(gpio) = GPIO_bit(gpio); | ||
67 | } | ||
62 | 68 | ||
63 | #define gpio_set_value(gpio,value) \ | 69 | #define gpio_set_value(gpio,value) \ |
64 | ((value) ? (GPSR(gpio) = GPIO_bit(gpio)):(GPCR(gpio) = GPIO_bit(gpio))) | 70 | (__builtin_constant_p(gpio) ? \ |
71 | __gpio_set_value(gpio, value) : \ | ||
72 | pxa_gpio_set_value(gpio, value)) | ||
65 | 73 | ||
66 | #include <asm-generic/gpio.h> /* cansleep wrappers */ | 74 | #include <asm-generic/gpio.h> /* cansleep wrappers */ |
67 | 75 | ||
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 @@ | |||
65 | /* | 65 | /* |
66 | * Handy routine to set GPIO alternate functions | 66 | * Handy routine to set GPIO alternate functions |
67 | */ | 67 | */ |
68 | extern void pxa_gpio_mode( int gpio_mode ); | 68 | extern int pxa_gpio_mode( int gpio_mode ); |
69 | |||
70 | /* | ||
71 | * Return GPIO level, nonzero means high, zero is low | ||
72 | */ | ||
73 | extern int pxa_gpio_get_value(unsigned gpio); | ||
74 | |||
75 | /* | ||
76 | * Set output GPIO level | ||
77 | */ | ||
78 | extern void pxa_gpio_set_value(unsigned gpio, int value); | ||
69 | 79 | ||
70 | /* | 80 | /* |
71 | * Routine to enable or disable CKEN | 81 | * Routine to enable or disable CKEN |