2 * linux/arch/arm/plat-pxa/gpio.c
4 * Generic PXA GPIO handling
6 * Author: Nicolas Pitre
7 * Created: Jun 15, 2001
8 * Copyright: MontaVista Software Inc.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/init.h>
16 #include <linux/irq.h>
18 #include <linux/syscore_ops.h>
19 #include <linux/slab.h>
21 #include <mach/gpio.h>
25 struct pxa_gpio_chip
{
26 struct gpio_chip chip
;
27 void __iomem
*regbase
;
30 unsigned long irq_mask
;
31 unsigned long irq_edge_rise
;
32 unsigned long irq_edge_fall
;
35 unsigned long saved_gplr
;
36 unsigned long saved_gpdr
;
37 unsigned long saved_grer
;
38 unsigned long saved_gfer
;
42 static DEFINE_SPINLOCK(gpio_lock
);
43 static struct pxa_gpio_chip
*pxa_gpio_chips
;
45 #define for_each_gpio_chip(i, c) \
46 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
48 static inline void __iomem
*gpio_chip_base(struct gpio_chip
*c
)
50 return container_of(c
, struct pxa_gpio_chip
, chip
)->regbase
;
53 static inline struct pxa_gpio_chip
*gpio_to_pxachip(unsigned gpio
)
55 return &pxa_gpio_chips
[gpio_to_bank(gpio
)];
58 static int pxa_gpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
60 void __iomem
*base
= gpio_chip_base(chip
);
61 uint32_t value
, mask
= 1 << offset
;
64 spin_lock_irqsave(&gpio_lock
, flags
);
66 value
= __raw_readl(base
+ GPDR_OFFSET
);
67 if (__gpio_is_inverted(chip
->base
+ offset
))
71 __raw_writel(value
, base
+ GPDR_OFFSET
);
73 spin_unlock_irqrestore(&gpio_lock
, flags
);
77 static int pxa_gpio_direction_output(struct gpio_chip
*chip
,
78 unsigned offset
, int value
)
80 void __iomem
*base
= gpio_chip_base(chip
);
81 uint32_t tmp
, mask
= 1 << offset
;
84 __raw_writel(mask
, base
+ (value
? GPSR_OFFSET
: GPCR_OFFSET
));
86 spin_lock_irqsave(&gpio_lock
, flags
);
88 tmp
= __raw_readl(base
+ GPDR_OFFSET
);
89 if (__gpio_is_inverted(chip
->base
+ offset
))
93 __raw_writel(tmp
, base
+ GPDR_OFFSET
);
95 spin_unlock_irqrestore(&gpio_lock
, flags
);
99 static int pxa_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
101 return __raw_readl(gpio_chip_base(chip
) + GPLR_OFFSET
) & (1 << offset
);
104 static void pxa_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
106 __raw_writel(1 << offset
, gpio_chip_base(chip
) +
107 (value
? GPSR_OFFSET
: GPCR_OFFSET
));
110 static int __init
pxa_init_gpio_chip(int gpio_end
)
112 int i
, gpio
, nbanks
= gpio_to_bank(gpio_end
) + 1;
113 struct pxa_gpio_chip
*chips
;
115 chips
= kzalloc(nbanks
* sizeof(struct pxa_gpio_chip
), GFP_KERNEL
);
117 pr_err("%s: failed to allocate GPIO chips\n", __func__
);
121 for (i
= 0, gpio
= 0; i
< nbanks
; i
++, gpio
+= 32) {
122 struct gpio_chip
*c
= &chips
[i
].chip
;
124 sprintf(chips
[i
].label
, "gpio-%d", i
);
125 chips
[i
].regbase
= (void __iomem
*)GPIO_BANK(i
);
128 c
->label
= chips
[i
].label
;
130 c
->direction_input
= pxa_gpio_direction_input
;
131 c
->direction_output
= pxa_gpio_direction_output
;
132 c
->get
= pxa_gpio_get
;
133 c
->set
= pxa_gpio_set
;
135 /* number of GPIOs on last bank may be less than 32 */
136 c
->ngpio
= (gpio
+ 31 > gpio_end
) ? (gpio_end
- gpio
+ 1) : 32;
139 pxa_gpio_chips
= chips
;
143 /* Update only those GRERx and GFERx edge detection register bits if those
144 * bits are set in c->irq_mask
146 static inline void update_edge_detect(struct pxa_gpio_chip
*c
)
150 grer
= __raw_readl(c
->regbase
+ GRER_OFFSET
) & ~c
->irq_mask
;
151 gfer
= __raw_readl(c
->regbase
+ GFER_OFFSET
) & ~c
->irq_mask
;
152 grer
|= c
->irq_edge_rise
& c
->irq_mask
;
153 gfer
|= c
->irq_edge_fall
& c
->irq_mask
;
154 __raw_writel(grer
, c
->regbase
+ GRER_OFFSET
);
155 __raw_writel(gfer
, c
->regbase
+ GFER_OFFSET
);
158 static int pxa_gpio_irq_type(struct irq_data
*d
, unsigned int type
)
160 struct pxa_gpio_chip
*c
;
161 int gpio
= irq_to_gpio(d
->irq
);
162 unsigned long gpdr
, mask
= GPIO_bit(gpio
);
164 c
= gpio_to_pxachip(gpio
);
166 if (type
== IRQ_TYPE_PROBE
) {
167 /* Don't mess with enabled GPIOs using preconfigured edges or
168 * GPIOs set to alternate function or to output during probe
170 if ((c
->irq_edge_rise
| c
->irq_edge_fall
) & GPIO_bit(gpio
))
173 if (__gpio_is_occupied(gpio
))
176 type
= IRQ_TYPE_EDGE_RISING
| IRQ_TYPE_EDGE_FALLING
;
179 gpdr
= __raw_readl(c
->regbase
+ GPDR_OFFSET
);
181 if (__gpio_is_inverted(gpio
))
182 __raw_writel(gpdr
| mask
, c
->regbase
+ GPDR_OFFSET
);
184 __raw_writel(gpdr
& ~mask
, c
->regbase
+ GPDR_OFFSET
);
186 if (type
& IRQ_TYPE_EDGE_RISING
)
187 c
->irq_edge_rise
|= mask
;
189 c
->irq_edge_rise
&= ~mask
;
191 if (type
& IRQ_TYPE_EDGE_FALLING
)
192 c
->irq_edge_fall
|= mask
;
194 c
->irq_edge_fall
&= ~mask
;
196 update_edge_detect(c
);
198 pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__
, d
->irq
, gpio
,
199 ((type
& IRQ_TYPE_EDGE_RISING
) ? " rising" : ""),
200 ((type
& IRQ_TYPE_EDGE_FALLING
) ? " falling" : ""));
204 static void pxa_gpio_demux_handler(unsigned int irq
, struct irq_desc
*desc
)
206 struct pxa_gpio_chip
*c
;
207 int loop
, gpio
, gpio_base
, n
;
212 for_each_gpio_chip(gpio
, c
) {
213 gpio_base
= c
->chip
.base
;
215 gedr
= __raw_readl(c
->regbase
+ GEDR_OFFSET
);
216 gedr
= gedr
& c
->irq_mask
;
217 __raw_writel(gedr
, c
->regbase
+ GEDR_OFFSET
);
219 n
= find_first_bit(&gedr
, BITS_PER_LONG
);
220 while (n
< BITS_PER_LONG
) {
223 generic_handle_irq(gpio_to_irq(gpio_base
+ n
));
224 n
= find_next_bit(&gedr
, BITS_PER_LONG
, n
+ 1);
230 static void pxa_ack_muxed_gpio(struct irq_data
*d
)
232 int gpio
= irq_to_gpio(d
->irq
);
233 struct pxa_gpio_chip
*c
= gpio_to_pxachip(gpio
);
235 __raw_writel(GPIO_bit(gpio
), c
->regbase
+ GEDR_OFFSET
);
238 static void pxa_mask_muxed_gpio(struct irq_data
*d
)
240 int gpio
= irq_to_gpio(d
->irq
);
241 struct pxa_gpio_chip
*c
= gpio_to_pxachip(gpio
);
244 c
->irq_mask
&= ~GPIO_bit(gpio
);
246 grer
= __raw_readl(c
->regbase
+ GRER_OFFSET
) & ~GPIO_bit(gpio
);
247 gfer
= __raw_readl(c
->regbase
+ GFER_OFFSET
) & ~GPIO_bit(gpio
);
248 __raw_writel(grer
, c
->regbase
+ GRER_OFFSET
);
249 __raw_writel(gfer
, c
->regbase
+ GFER_OFFSET
);
252 static void pxa_unmask_muxed_gpio(struct irq_data
*d
)
254 int gpio
= irq_to_gpio(d
->irq
);
255 struct pxa_gpio_chip
*c
= gpio_to_pxachip(gpio
);
257 c
->irq_mask
|= GPIO_bit(gpio
);
258 update_edge_detect(c
);
261 static struct irq_chip pxa_muxed_gpio_chip
= {
263 .irq_ack
= pxa_ack_muxed_gpio
,
264 .irq_mask
= pxa_mask_muxed_gpio
,
265 .irq_unmask
= pxa_unmask_muxed_gpio
,
266 .irq_set_type
= pxa_gpio_irq_type
,
269 void __init
pxa_init_gpio(int mux_irq
, int start
, int end
, set_wake_t fn
)
271 struct pxa_gpio_chip
*c
;
276 /* Initialize GPIO chips */
277 pxa_init_gpio_chip(end
);
279 /* clear all GPIO edge detects */
280 for_each_gpio_chip(gpio
, c
) {
281 __raw_writel(0, c
->regbase
+ GFER_OFFSET
);
282 __raw_writel(0, c
->regbase
+ GRER_OFFSET
);
283 __raw_writel(~0,c
->regbase
+ GEDR_OFFSET
);
286 for (irq
= gpio_to_irq(start
); irq
<= gpio_to_irq(end
); irq
++) {
287 irq_set_chip_and_handler(irq
, &pxa_muxed_gpio_chip
,
289 set_irq_flags(irq
, IRQF_VALID
| IRQF_PROBE
);
292 /* Install handler for GPIO>=2 edge detect interrupts */
293 irq_set_chained_handler(mux_irq
, pxa_gpio_demux_handler
);
294 pxa_muxed_gpio_chip
.irq_set_wake
= fn
;
298 static int pxa_gpio_suspend(void)
300 struct pxa_gpio_chip
*c
;
303 for_each_gpio_chip(gpio
, c
) {
304 c
->saved_gplr
= __raw_readl(c
->regbase
+ GPLR_OFFSET
);
305 c
->saved_gpdr
= __raw_readl(c
->regbase
+ GPDR_OFFSET
);
306 c
->saved_grer
= __raw_readl(c
->regbase
+ GRER_OFFSET
);
307 c
->saved_gfer
= __raw_readl(c
->regbase
+ GFER_OFFSET
);
309 /* Clear GPIO transition detect bits */
310 __raw_writel(0xffffffff, c
->regbase
+ GEDR_OFFSET
);
315 static void pxa_gpio_resume(void)
317 struct pxa_gpio_chip
*c
;
320 for_each_gpio_chip(gpio
, c
) {
321 /* restore level with set/clear */
322 __raw_writel( c
->saved_gplr
, c
->regbase
+ GPSR_OFFSET
);
323 __raw_writel(~c
->saved_gplr
, c
->regbase
+ GPCR_OFFSET
);
325 __raw_writel(c
->saved_grer
, c
->regbase
+ GRER_OFFSET
);
326 __raw_writel(c
->saved_gfer
, c
->regbase
+ GFER_OFFSET
);
327 __raw_writel(c
->saved_gpdr
, c
->regbase
+ GPDR_OFFSET
);
331 #define pxa_gpio_suspend NULL
332 #define pxa_gpio_resume NULL
335 struct syscore_ops pxa_gpio_syscore_ops
= {
336 .suspend
= pxa_gpio_suspend
,
337 .resume
= pxa_gpio_resume
,