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.
14 #include <linux/gpio.h>
15 #include <linux/init.h>
16 #include <linux/irq.h>
18 #include <linux/syscore_ops.h>
19 #include <linux/slab.h>
23 struct pxa_gpio_chip
{
24 struct gpio_chip chip
;
25 void __iomem
*regbase
;
28 unsigned long irq_mask
;
29 unsigned long irq_edge_rise
;
30 unsigned long irq_edge_fall
;
33 unsigned long saved_gplr
;
34 unsigned long saved_gpdr
;
35 unsigned long saved_grer
;
36 unsigned long saved_gfer
;
40 static DEFINE_SPINLOCK(gpio_lock
);
41 static struct pxa_gpio_chip
*pxa_gpio_chips
;
43 #define for_each_gpio_chip(i, c) \
44 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
46 static inline void __iomem
*gpio_chip_base(struct gpio_chip
*c
)
48 return container_of(c
, struct pxa_gpio_chip
, chip
)->regbase
;
51 static inline struct pxa_gpio_chip
*gpio_to_pxachip(unsigned gpio
)
53 return &pxa_gpio_chips
[gpio_to_bank(gpio
)];
56 static int pxa_gpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
58 void __iomem
*base
= gpio_chip_base(chip
);
59 uint32_t value
, mask
= 1 << offset
;
62 spin_lock_irqsave(&gpio_lock
, flags
);
64 value
= __raw_readl(base
+ GPDR_OFFSET
);
65 if (__gpio_is_inverted(chip
->base
+ offset
))
69 __raw_writel(value
, base
+ GPDR_OFFSET
);
71 spin_unlock_irqrestore(&gpio_lock
, flags
);
75 static int pxa_gpio_direction_output(struct gpio_chip
*chip
,
76 unsigned offset
, int value
)
78 void __iomem
*base
= gpio_chip_base(chip
);
79 uint32_t tmp
, mask
= 1 << offset
;
82 __raw_writel(mask
, base
+ (value
? GPSR_OFFSET
: GPCR_OFFSET
));
84 spin_lock_irqsave(&gpio_lock
, flags
);
86 tmp
= __raw_readl(base
+ GPDR_OFFSET
);
87 if (__gpio_is_inverted(chip
->base
+ offset
))
91 __raw_writel(tmp
, base
+ GPDR_OFFSET
);
93 spin_unlock_irqrestore(&gpio_lock
, flags
);
97 static int pxa_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
99 return __raw_readl(gpio_chip_base(chip
) + GPLR_OFFSET
) & (1 << offset
);
102 static void pxa_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
104 __raw_writel(1 << offset
, gpio_chip_base(chip
) +
105 (value
? GPSR_OFFSET
: GPCR_OFFSET
));
108 static int __init
pxa_init_gpio_chip(int gpio_end
)
110 int i
, gpio
, nbanks
= gpio_to_bank(gpio_end
) + 1;
111 struct pxa_gpio_chip
*chips
;
113 chips
= kzalloc(nbanks
* sizeof(struct pxa_gpio_chip
), GFP_KERNEL
);
115 pr_err("%s: failed to allocate GPIO chips\n", __func__
);
119 for (i
= 0, gpio
= 0; i
< nbanks
; i
++, gpio
+= 32) {
120 struct gpio_chip
*c
= &chips
[i
].chip
;
122 sprintf(chips
[i
].label
, "gpio-%d", i
);
123 chips
[i
].regbase
= (void __iomem
*)GPIO_BANK(i
);
126 c
->label
= chips
[i
].label
;
128 c
->direction_input
= pxa_gpio_direction_input
;
129 c
->direction_output
= pxa_gpio_direction_output
;
130 c
->get
= pxa_gpio_get
;
131 c
->set
= pxa_gpio_set
;
133 /* number of GPIOs on last bank may be less than 32 */
134 c
->ngpio
= (gpio
+ 31 > gpio_end
) ? (gpio_end
- gpio
+ 1) : 32;
137 pxa_gpio_chips
= chips
;
141 /* Update only those GRERx and GFERx edge detection register bits if those
142 * bits are set in c->irq_mask
144 static inline void update_edge_detect(struct pxa_gpio_chip
*c
)
148 grer
= __raw_readl(c
->regbase
+ GRER_OFFSET
) & ~c
->irq_mask
;
149 gfer
= __raw_readl(c
->regbase
+ GFER_OFFSET
) & ~c
->irq_mask
;
150 grer
|= c
->irq_edge_rise
& c
->irq_mask
;
151 gfer
|= c
->irq_edge_fall
& c
->irq_mask
;
152 __raw_writel(grer
, c
->regbase
+ GRER_OFFSET
);
153 __raw_writel(gfer
, c
->regbase
+ GFER_OFFSET
);
156 static int pxa_gpio_irq_type(struct irq_data
*d
, unsigned int type
)
158 struct pxa_gpio_chip
*c
;
159 int gpio
= irq_to_gpio(d
->irq
);
160 unsigned long gpdr
, mask
= GPIO_bit(gpio
);
162 c
= gpio_to_pxachip(gpio
);
164 if (type
== IRQ_TYPE_PROBE
) {
165 /* Don't mess with enabled GPIOs using preconfigured edges or
166 * GPIOs set to alternate function or to output during probe
168 if ((c
->irq_edge_rise
| c
->irq_edge_fall
) & GPIO_bit(gpio
))
171 if (__gpio_is_occupied(gpio
))
174 type
= IRQ_TYPE_EDGE_RISING
| IRQ_TYPE_EDGE_FALLING
;
177 gpdr
= __raw_readl(c
->regbase
+ GPDR_OFFSET
);
179 if (__gpio_is_inverted(gpio
))
180 __raw_writel(gpdr
| mask
, c
->regbase
+ GPDR_OFFSET
);
182 __raw_writel(gpdr
& ~mask
, c
->regbase
+ GPDR_OFFSET
);
184 if (type
& IRQ_TYPE_EDGE_RISING
)
185 c
->irq_edge_rise
|= mask
;
187 c
->irq_edge_rise
&= ~mask
;
189 if (type
& IRQ_TYPE_EDGE_FALLING
)
190 c
->irq_edge_fall
|= mask
;
192 c
->irq_edge_fall
&= ~mask
;
194 update_edge_detect(c
);
196 pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__
, d
->irq
, gpio
,
197 ((type
& IRQ_TYPE_EDGE_RISING
) ? " rising" : ""),
198 ((type
& IRQ_TYPE_EDGE_FALLING
) ? " falling" : ""));
202 static void pxa_gpio_demux_handler(unsigned int irq
, struct irq_desc
*desc
)
204 struct pxa_gpio_chip
*c
;
205 int loop
, gpio
, gpio_base
, n
;
210 for_each_gpio_chip(gpio
, c
) {
211 gpio_base
= c
->chip
.base
;
213 gedr
= __raw_readl(c
->regbase
+ GEDR_OFFSET
);
214 gedr
= gedr
& c
->irq_mask
;
215 __raw_writel(gedr
, c
->regbase
+ GEDR_OFFSET
);
217 n
= find_first_bit(&gedr
, BITS_PER_LONG
);
218 while (n
< BITS_PER_LONG
) {
221 generic_handle_irq(gpio_to_irq(gpio_base
+ n
));
222 n
= find_next_bit(&gedr
, BITS_PER_LONG
, n
+ 1);
228 static void pxa_ack_muxed_gpio(struct irq_data
*d
)
230 int gpio
= irq_to_gpio(d
->irq
);
231 struct pxa_gpio_chip
*c
= gpio_to_pxachip(gpio
);
233 __raw_writel(GPIO_bit(gpio
), c
->regbase
+ GEDR_OFFSET
);
236 static void pxa_mask_muxed_gpio(struct irq_data
*d
)
238 int gpio
= irq_to_gpio(d
->irq
);
239 struct pxa_gpio_chip
*c
= gpio_to_pxachip(gpio
);
242 c
->irq_mask
&= ~GPIO_bit(gpio
);
244 grer
= __raw_readl(c
->regbase
+ GRER_OFFSET
) & ~GPIO_bit(gpio
);
245 gfer
= __raw_readl(c
->regbase
+ GFER_OFFSET
) & ~GPIO_bit(gpio
);
246 __raw_writel(grer
, c
->regbase
+ GRER_OFFSET
);
247 __raw_writel(gfer
, c
->regbase
+ GFER_OFFSET
);
250 static void pxa_unmask_muxed_gpio(struct irq_data
*d
)
252 int gpio
= irq_to_gpio(d
->irq
);
253 struct pxa_gpio_chip
*c
= gpio_to_pxachip(gpio
);
255 c
->irq_mask
|= GPIO_bit(gpio
);
256 update_edge_detect(c
);
259 static struct irq_chip pxa_muxed_gpio_chip
= {
261 .irq_ack
= pxa_ack_muxed_gpio
,
262 .irq_mask
= pxa_mask_muxed_gpio
,
263 .irq_unmask
= pxa_unmask_muxed_gpio
,
264 .irq_set_type
= pxa_gpio_irq_type
,
267 void __init
pxa_init_gpio(int mux_irq
, int start
, int end
, set_wake_t fn
)
269 struct pxa_gpio_chip
*c
;
274 /* Initialize GPIO chips */
275 pxa_init_gpio_chip(end
);
277 /* clear all GPIO edge detects */
278 for_each_gpio_chip(gpio
, c
) {
279 __raw_writel(0, c
->regbase
+ GFER_OFFSET
);
280 __raw_writel(0, c
->regbase
+ GRER_OFFSET
);
281 __raw_writel(~0,c
->regbase
+ GEDR_OFFSET
);
284 for (irq
= gpio_to_irq(start
); irq
<= gpio_to_irq(end
); irq
++) {
285 irq_set_chip_and_handler(irq
, &pxa_muxed_gpio_chip
,
287 set_irq_flags(irq
, IRQF_VALID
| IRQF_PROBE
);
290 /* Install handler for GPIO>=2 edge detect interrupts */
291 irq_set_chained_handler(mux_irq
, pxa_gpio_demux_handler
);
292 pxa_muxed_gpio_chip
.irq_set_wake
= fn
;
296 static int pxa_gpio_suspend(void)
298 struct pxa_gpio_chip
*c
;
301 for_each_gpio_chip(gpio
, c
) {
302 c
->saved_gplr
= __raw_readl(c
->regbase
+ GPLR_OFFSET
);
303 c
->saved_gpdr
= __raw_readl(c
->regbase
+ GPDR_OFFSET
);
304 c
->saved_grer
= __raw_readl(c
->regbase
+ GRER_OFFSET
);
305 c
->saved_gfer
= __raw_readl(c
->regbase
+ GFER_OFFSET
);
307 /* Clear GPIO transition detect bits */
308 __raw_writel(0xffffffff, c
->regbase
+ GEDR_OFFSET
);
313 static void pxa_gpio_resume(void)
315 struct pxa_gpio_chip
*c
;
318 for_each_gpio_chip(gpio
, c
) {
319 /* restore level with set/clear */
320 __raw_writel( c
->saved_gplr
, c
->regbase
+ GPSR_OFFSET
);
321 __raw_writel(~c
->saved_gplr
, c
->regbase
+ GPCR_OFFSET
);
323 __raw_writel(c
->saved_grer
, c
->regbase
+ GRER_OFFSET
);
324 __raw_writel(c
->saved_gfer
, c
->regbase
+ GFER_OFFSET
);
325 __raw_writel(c
->saved_gpdr
, c
->regbase
+ GPDR_OFFSET
);
329 #define pxa_gpio_suspend NULL
330 #define pxa_gpio_resume NULL
333 struct syscore_ops pxa_gpio_syscore_ops
= {
334 .suspend
= pxa_gpio_suspend
,
335 .resume
= pxa_gpio_resume
,