Blame view
drivers/gpio/gpio-pxa.c
20.2 KB
1c44f5f16 gpiolib support f... |
1 |
/* |
38f539a60 [ARM] pxa: move c... |
2 |
* linux/arch/arm/plat-pxa/gpio.c |
1c44f5f16 gpiolib support f... |
3 4 5 6 7 8 9 10 11 12 13 |
* * Generic PXA GPIO handling * * Author: Nicolas Pitre * Created: Jun 15, 2001 * Copyright: MontaVista Software Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ |
7a4d5079b gpio: pxa: parse ... |
14 |
#include <linux/module.h> |
389eda15e ARM: pxa: add clk... |
15 16 |
#include <linux/clk.h> #include <linux/err.h> |
2f8163baa ARM: gpio: conver... |
17 |
#include <linux/gpio.h> |
157d2644c ARM: pxa: change ... |
18 |
#include <linux/gpio-pxa.h> |
1c44f5f16 gpiolib support f... |
19 |
#include <linux/init.h> |
ae4f4cfd8 gpio: pxa: remove... |
20 |
#include <linux/interrupt.h> |
e3630db1f [ARM] pxa: move G... |
21 |
#include <linux/irq.h> |
7a4d5079b gpio: pxa: parse ... |
22 |
#include <linux/irqdomain.h> |
de88cbb7b arm: Move chained... |
23 |
#include <linux/irqchip/chained_irq.h> |
fced80c73 [ARM] Convert asm... |
24 |
#include <linux/io.h> |
7a4d5079b gpio: pxa: parse ... |
25 26 |
#include <linux/of.h> #include <linux/of_device.h> |
a770d9463 gpio: pxa: add pi... |
27 |
#include <linux/pinctrl/consumer.h> |
157d2644c ARM: pxa: change ... |
28 |
#include <linux/platform_device.h> |
2eaa03b5b ARM / PXA: Use st... |
29 |
#include <linux/syscore_ops.h> |
4aa78264d [ARM] pxa: use kz... |
30 |
#include <linux/slab.h> |
1c44f5f16 gpiolib support f... |
31 |
|
157d2644c ARM: pxa: change ... |
32 33 34 35 36 37 38 39 40 41 42 43 44 |
/* * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with * one set of registers. The register offsets are organized below: * * GPLR GPDR GPSR GPCR GRER GFER GEDR * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 * * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 * |
684bba2ff gpio: pxa: add PX... |
45 46 |
* BANK 6 - 0x0200 0x020C 0x0218 0x0224 0x0230 0x023C 0x0248 * |
157d2644c ARM: pxa: change ... |
47 48 |
* NOTE: * BANK 3 is only available on PXA27x and later processors. |
684bba2ff gpio: pxa: add PX... |
49 50 |
* BANK 4 and 5 are only available on PXA935, PXA1928 * BANK 6 is only available on PXA1928 |
157d2644c ARM: pxa: change ... |
51 52 53 54 55 56 57 58 59 60 |
*/ #define GPLR_OFFSET 0x00 #define GPDR_OFFSET 0x0C #define GPSR_OFFSET 0x18 #define GPCR_OFFSET 0x24 #define GRER_OFFSET 0x30 #define GFER_OFFSET 0x3C #define GEDR_OFFSET 0x48 #define GAFR_OFFSET 0x54 |
be24168f1 ARM: mmp: clear g... |
61 |
#define ED_MASK_OFFSET 0x9C /* GPIO edge detection for AP side */ |
157d2644c ARM: pxa: change ... |
62 |
|
1e970b7d6 gpio: pxa: simpli... |
63 |
#define BANK_OFF(n) (((n) / 3) << 8) + (((n) % 3) << 2) |
1c44f5f16 gpiolib support f... |
64 |
|
3b8e285c2 [ARM] pxa: move d... |
65 |
int pxa_last_gpio; |
9450be76d GPIO: gpio-pxa: s... |
66 |
static int irq_base; |
3b8e285c2 [ARM] pxa: move d... |
67 |
|
fc0589ca6 gpio: pxa: conver... |
68 |
struct pxa_gpio_bank { |
0807da593 [ARM] pxa: access... |
69 |
void __iomem *regbase; |
0807da593 [ARM] pxa: access... |
70 71 72 73 74 75 76 77 78 79 |
unsigned long irq_mask; unsigned long irq_edge_rise; unsigned long irq_edge_fall; #ifdef CONFIG_PM unsigned long saved_gplr; unsigned long saved_gpdr; unsigned long saved_grer; unsigned long saved_gfer; #endif |
1c44f5f16 gpiolib support f... |
80 |
}; |
fc0589ca6 gpio: pxa: conver... |
81 82 83 84 |
struct pxa_gpio_chip { struct device *dev; struct gpio_chip chip; struct pxa_gpio_bank *banks; |
384ca3c6a gpio: pxa: change... |
85 |
struct irq_domain *irqdomain; |
fc0589ca6 gpio: pxa: conver... |
86 87 88 89 90 |
int irq0; int irq1; int (*set_wake)(unsigned int gpio, unsigned int on); }; |
2cab02922 ARM: pxa: remove ... |
91 |
enum pxa_gpio_type { |
4929f5a8a ARM: pxa: rename ... |
92 93 94 95 96 97 |
PXA25X_GPIO = 0, PXA26X_GPIO, PXA27X_GPIO, PXA3XX_GPIO, PXA93X_GPIO, MMP_GPIO = 0x10, |
2cab02922 ARM: pxa: remove ... |
98 |
MMP2_GPIO, |
684bba2ff gpio: pxa: add PX... |
99 |
PXA1928_GPIO, |
2cab02922 ARM: pxa: remove ... |
100 101 102 103 104 |
}; struct pxa_gpio_id { enum pxa_gpio_type type; int gpio_nums; |
4929f5a8a ARM: pxa: rename ... |
105 |
}; |
0807da593 [ARM] pxa: access... |
106 |
static DEFINE_SPINLOCK(gpio_lock); |
fc0589ca6 gpio: pxa: conver... |
107 |
static struct pxa_gpio_chip *pxa_gpio_chip; |
2cab02922 ARM: pxa: remove ... |
108 |
static enum pxa_gpio_type gpio_type; |
0807da593 [ARM] pxa: access... |
109 |
|
2cab02922 ARM: pxa: remove ... |
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
static struct pxa_gpio_id pxa25x_id = { .type = PXA25X_GPIO, .gpio_nums = 85, }; static struct pxa_gpio_id pxa26x_id = { .type = PXA26X_GPIO, .gpio_nums = 90, }; static struct pxa_gpio_id pxa27x_id = { .type = PXA27X_GPIO, .gpio_nums = 121, }; static struct pxa_gpio_id pxa3xx_id = { .type = PXA3XX_GPIO, .gpio_nums = 128, }; static struct pxa_gpio_id pxa93x_id = { .type = PXA93X_GPIO, .gpio_nums = 192, }; static struct pxa_gpio_id mmp_id = { .type = MMP_GPIO, .gpio_nums = 128, }; static struct pxa_gpio_id mmp2_id = { .type = MMP2_GPIO, .gpio_nums = 192, }; |
684bba2ff gpio: pxa: add PX... |
144 145 146 147 |
static struct pxa_gpio_id pxa1928_id = { .type = PXA1928_GPIO, .gpio_nums = 224, }; |
fc0589ca6 gpio: pxa: conver... |
148 149 |
#define for_each_gpio_bank(i, b, pc) \ for (i = 0, b = pc->banks; i <= pxa_last_gpio; i += 32, b++) |
0807da593 [ARM] pxa: access... |
150 |
|
fc0589ca6 gpio: pxa: conver... |
151 |
static inline struct pxa_gpio_chip *chip_to_pxachip(struct gpio_chip *c) |
0807da593 [ARM] pxa: access... |
152 |
{ |
81d0c31d1 gpio: pxa: use gp... |
153 |
struct pxa_gpio_chip *pxa_chip = gpiochip_get_data(c); |
fc0589ca6 gpio: pxa: conver... |
154 155 |
return pxa_chip; |
0807da593 [ARM] pxa: access... |
156 |
} |
81d0c31d1 gpio: pxa: use gp... |
157 |
|
fc0589ca6 gpio: pxa: conver... |
158 159 |
static inline void __iomem *gpio_bank_base(struct gpio_chip *c, int gpio) { |
81d0c31d1 gpio: pxa: use gp... |
160 161 |
struct pxa_gpio_chip *p = gpiochip_get_data(c); struct pxa_gpio_bank *bank = p->banks + (gpio / 32); |
0807da593 [ARM] pxa: access... |
162 |
|
fc0589ca6 gpio: pxa: conver... |
163 164 165 166 167 |
return bank->regbase; } static inline struct pxa_gpio_bank *gpio_to_pxabank(struct gpio_chip *c, unsigned gpio) |
0807da593 [ARM] pxa: access... |
168 |
{ |
fc0589ca6 gpio: pxa: conver... |
169 |
return chip_to_pxachip(c)->banks + gpio / 32; |
0807da593 [ARM] pxa: access... |
170 |
} |
4929f5a8a ARM: pxa: rename ... |
171 172 173 174 175 176 177 178 179 |
static inline int gpio_is_pxa_type(int type) { return (type & MMP_GPIO) == 0; } static inline int gpio_is_mmp_type(int type) { return (type & MMP_GPIO) != 0; } |
157d2644c ARM: pxa: change ... |
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
/* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, * as well as their Alternate Function value being '1' for GPIO in GAFRx. */ static inline int __gpio_is_inverted(int gpio) { if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) return 1; return 0; } /* * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate * function of a GPIO, and GPDRx cannot be altered once configured. It * is attributed as "occupied" here (I know this terminology isn't * accurate, you are welcome to propose a better one :-) */ |
fc0589ca6 gpio: pxa: conver... |
196 |
static inline int __gpio_is_occupied(struct pxa_gpio_chip *pchip, unsigned gpio) |
157d2644c ARM: pxa: change ... |
197 |
{ |
157d2644c ARM: pxa: change ... |
198 199 200 |
void __iomem *base; unsigned long gafr = 0, gpdr = 0; int ret, af = 0, dir = 0; |
fc0589ca6 gpio: pxa: conver... |
201 |
base = gpio_bank_base(&pchip->chip, gpio); |
157d2644c ARM: pxa: change ... |
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
gpdr = readl_relaxed(base + GPDR_OFFSET); switch (gpio_type) { case PXA25X_GPIO: case PXA26X_GPIO: case PXA27X_GPIO: gafr = readl_relaxed(base + GAFR_OFFSET); af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; dir = gpdr & GPIO_bit(gpio); if (__gpio_is_inverted(gpio)) ret = (af != 1) || (dir == 0); else ret = (af != 0) || (dir != 0); break; default: ret = gpdr & GPIO_bit(gpio); break; } return ret; } |
384ca3c6a gpio: pxa: change... |
223 |
int pxa_irq_to_gpio(int irq) |
4929f5a8a ARM: pxa: rename ... |
224 |
{ |
384ca3c6a gpio: pxa: change... |
225 226 227 228 229 230 231 232 |
struct pxa_gpio_chip *pchip = pxa_gpio_chip; int irq_gpio0; irq_gpio0 = irq_find_mapping(pchip->irqdomain, 0); if (irq_gpio0 > 0) return irq - irq_gpio0; return irq_gpio0; |
4929f5a8a ARM: pxa: rename ... |
233 |
} |
384ca3c6a gpio: pxa: change... |
234 |
static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
4929f5a8a ARM: pxa: rename ... |
235 |
{ |
384ca3c6a gpio: pxa: change... |
236 237 238 |
struct pxa_gpio_chip *pchip = chip_to_pxachip(chip); return irq_find_mapping(pchip->irqdomain, offset); |
4929f5a8a ARM: pxa: rename ... |
239 |
} |
1c44f5f16 gpiolib support f... |
240 241 |
static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { |
fc0589ca6 gpio: pxa: conver... |
242 243 |
void __iomem *base = gpio_bank_base(chip, offset); uint32_t value, mask = GPIO_bit(offset); |
0807da593 [ARM] pxa: access... |
244 |
unsigned long flags; |
a770d9463 gpio: pxa: add pi... |
245 246 247 248 249 |
int ret; ret = pinctrl_gpio_direction_input(chip->base + offset); if (!ret) return 0; |
0807da593 [ARM] pxa: access... |
250 251 |
spin_lock_irqsave(&gpio_lock, flags); |
df664d208 ARM: pxa: use lit... |
252 |
value = readl_relaxed(base + GPDR_OFFSET); |
067455aa5 [ARM] pxa: add su... |
253 254 255 256 |
if (__gpio_is_inverted(chip->base + offset)) value |= mask; else value &= ~mask; |
df664d208 ARM: pxa: use lit... |
257 |
writel_relaxed(value, base + GPDR_OFFSET); |
1c44f5f16 gpiolib support f... |
258 |
|
0807da593 [ARM] pxa: access... |
259 |
spin_unlock_irqrestore(&gpio_lock, flags); |
1c44f5f16 gpiolib support f... |
260 261 262 263 |
return 0; } static int pxa_gpio_direction_output(struct gpio_chip *chip, |
0807da593 [ARM] pxa: access... |
264 |
unsigned offset, int value) |
1c44f5f16 gpiolib support f... |
265 |
{ |
fc0589ca6 gpio: pxa: conver... |
266 267 |
void __iomem *base = gpio_bank_base(chip, offset); uint32_t tmp, mask = GPIO_bit(offset); |
0807da593 [ARM] pxa: access... |
268 |
unsigned long flags; |
a770d9463 gpio: pxa: add pi... |
269 |
int ret; |
0807da593 [ARM] pxa: access... |
270 |
|
df664d208 ARM: pxa: use lit... |
271 |
writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); |
0807da593 [ARM] pxa: access... |
272 |
|
a770d9463 gpio: pxa: add pi... |
273 |
ret = pinctrl_gpio_direction_output(chip->base + offset); |
c4e5ffb6f gpio: pxa: fix le... |
274 275 |
if (ret) return ret; |
a770d9463 gpio: pxa: add pi... |
276 |
|
0807da593 [ARM] pxa: access... |
277 |
spin_lock_irqsave(&gpio_lock, flags); |
df664d208 ARM: pxa: use lit... |
278 |
tmp = readl_relaxed(base + GPDR_OFFSET); |
067455aa5 [ARM] pxa: add su... |
279 280 281 282 |
if (__gpio_is_inverted(chip->base + offset)) tmp &= ~mask; else tmp |= mask; |
df664d208 ARM: pxa: use lit... |
283 |
writel_relaxed(tmp, base + GPDR_OFFSET); |
1c44f5f16 gpiolib support f... |
284 |
|
0807da593 [ARM] pxa: access... |
285 |
spin_unlock_irqrestore(&gpio_lock, flags); |
1c44f5f16 gpiolib support f... |
286 287 |
return 0; } |
1c44f5f16 gpiolib support f... |
288 289 |
static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) { |
fc0589ca6 gpio: pxa: conver... |
290 291 292 293 |
void __iomem *base = gpio_bank_base(chip, offset); u32 gplr = readl_relaxed(base + GPLR_OFFSET); return !!(gplr & GPIO_bit(offset)); |
1c44f5f16 gpiolib support f... |
294 |
} |
1c44f5f16 gpiolib support f... |
295 296 |
static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { |
fc0589ca6 gpio: pxa: conver... |
297 298 299 300 |
void __iomem *base = gpio_bank_base(chip, offset); writel_relaxed(GPIO_bit(offset), base + (value ? GPSR_OFFSET : GPCR_OFFSET)); |
1c44f5f16 gpiolib support f... |
301 |
} |
721215726 GPIO: gpio-pxa: f... |
302 303 304 305 306 307 308 |
#ifdef CONFIG_OF_GPIO static int pxa_gpio_of_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags) { if (gpiospec->args[0] > pxa_last_gpio) return -EINVAL; |
721215726 GPIO: gpio-pxa: f... |
309 310 |
if (flags) *flags = gpiospec->args[1]; |
fc0589ca6 gpio: pxa: conver... |
311 |
return gpiospec->args[0]; |
721215726 GPIO: gpio-pxa: f... |
312 313 |
} #endif |
a770d9463 gpio: pxa: add pi... |
314 315 316 317 318 319 320 321 322 |
static int pxa_gpio_request(struct gpio_chip *chip, unsigned int offset) { return pinctrl_request_gpio(chip->base + offset); } static void pxa_gpio_free(struct gpio_chip *chip, unsigned int offset) { pinctrl_free_gpio(chip->base + offset); } |
fc0589ca6 gpio: pxa: conver... |
323 |
static int pxa_init_gpio_chip(struct pxa_gpio_chip *pchip, int ngpio, |
384ca3c6a gpio: pxa: change... |
324 |
struct device_node *np, void __iomem *regbase) |
a58fbcd8a [ARM] pxa: move I... |
325 |
{ |
fc0589ca6 gpio: pxa: conver... |
326 327 |
int i, gpio, nbanks = DIV_ROUND_UP(ngpio, 32); struct pxa_gpio_bank *bank; |
a58fbcd8a [ARM] pxa: move I... |
328 |
|
fc0589ca6 gpio: pxa: conver... |
329 330 331 |
pchip->banks = devm_kcalloc(pchip->dev, nbanks, sizeof(*pchip->banks), GFP_KERNEL); if (!pchip->banks) |
0807da593 [ARM] pxa: access... |
332 |
return -ENOMEM; |
a58fbcd8a [ARM] pxa: move I... |
333 |
|
fc0589ca6 gpio: pxa: conver... |
334 335 336 337 338 339 340 |
pchip->chip.label = "gpio-pxa"; pchip->chip.direction_input = pxa_gpio_direction_input; pchip->chip.direction_output = pxa_gpio_direction_output; pchip->chip.get = pxa_gpio_get; pchip->chip.set = pxa_gpio_set; pchip->chip.to_irq = pxa_gpio_to_irq; pchip->chip.ngpio = ngpio; |
a770d9463 gpio: pxa: add pi... |
341 342 |
pchip->chip.request = pxa_gpio_request; pchip->chip.free = pxa_gpio_free; |
721215726 GPIO: gpio-pxa: f... |
343 |
#ifdef CONFIG_OF_GPIO |
384ca3c6a gpio: pxa: change... |
344 |
pchip->chip.of_node = np; |
fc0589ca6 gpio: pxa: conver... |
345 346 |
pchip->chip.of_xlate = pxa_gpio_of_xlate; pchip->chip.of_gpio_n_cells = 2; |
721215726 GPIO: gpio-pxa: f... |
347 |
#endif |
0807da593 [ARM] pxa: access... |
348 |
|
fc0589ca6 gpio: pxa: conver... |
349 350 351 |
for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { bank = pchip->banks + i; bank->regbase = regbase + BANK_OFF(i); |
0807da593 [ARM] pxa: access... |
352 |
} |
fc0589ca6 gpio: pxa: conver... |
353 |
|
81d0c31d1 gpio: pxa: use gp... |
354 |
return gpiochip_add_data(&pchip->chip, pchip); |
0807da593 [ARM] pxa: access... |
355 |
} |
e3630db1f [ARM] pxa: move G... |
356 |
|
a8f6faeba [ARM] pxa: fix is... |
357 358 359 |
/* Update only those GRERx and GFERx edge detection register bits if those * bits are set in c->irq_mask */ |
fc0589ca6 gpio: pxa: conver... |
360 |
static inline void update_edge_detect(struct pxa_gpio_bank *c) |
a8f6faeba [ARM] pxa: fix is... |
361 362 |
{ uint32_t grer, gfer; |
df664d208 ARM: pxa: use lit... |
363 364 |
grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask; gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask; |
a8f6faeba [ARM] pxa: fix is... |
365 366 |
grer |= c->irq_edge_rise & c->irq_mask; gfer |= c->irq_edge_fall & c->irq_mask; |
df664d208 ARM: pxa: use lit... |
367 368 |
writel_relaxed(grer, c->regbase + GRER_OFFSET); writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
a8f6faeba [ARM] pxa: fix is... |
369 |
} |
a3f4c927d ARM: PXA SoCs: ir... |
370 |
static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) |
e3630db1f [ARM] pxa: move G... |
371 |
{ |
384ca3c6a gpio: pxa: change... |
372 373 |
struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); unsigned int gpio = irqd_to_hwirq(d); |
fc0589ca6 gpio: pxa: conver... |
374 |
struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio); |
0807da593 [ARM] pxa: access... |
375 |
unsigned long gpdr, mask = GPIO_bit(gpio); |
e3630db1f [ARM] pxa: move G... |
376 |
|
e3630db1f [ARM] pxa: move G... |
377 378 379 380 |
if (type == IRQ_TYPE_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or * GPIOs set to alternate function or to output during probe */ |
0807da593 [ARM] pxa: access... |
381 |
if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio)) |
e3630db1f [ARM] pxa: move G... |
382 |
return 0; |
689c04a39 [ARM] pxa: make p... |
383 |
|
fc0589ca6 gpio: pxa: conver... |
384 |
if (__gpio_is_occupied(pchip, gpio)) |
e3630db1f [ARM] pxa: move G... |
385 |
return 0; |
689c04a39 [ARM] pxa: make p... |
386 |
|
e3630db1f [ARM] pxa: move G... |
387 388 |
type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; } |
df664d208 ARM: pxa: use lit... |
389 |
gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
0807da593 [ARM] pxa: access... |
390 |
|
067455aa5 [ARM] pxa: add su... |
391 |
if (__gpio_is_inverted(gpio)) |
df664d208 ARM: pxa: use lit... |
392 |
writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET); |
067455aa5 [ARM] pxa: add su... |
393 |
else |
df664d208 ARM: pxa: use lit... |
394 |
writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET); |
e3630db1f [ARM] pxa: move G... |
395 396 |
if (type & IRQ_TYPE_EDGE_RISING) |
0807da593 [ARM] pxa: access... |
397 |
c->irq_edge_rise |= mask; |
e3630db1f [ARM] pxa: move G... |
398 |
else |
0807da593 [ARM] pxa: access... |
399 |
c->irq_edge_rise &= ~mask; |
e3630db1f [ARM] pxa: move G... |
400 401 |
if (type & IRQ_TYPE_EDGE_FALLING) |
0807da593 [ARM] pxa: access... |
402 |
c->irq_edge_fall |= mask; |
e3630db1f [ARM] pxa: move G... |
403 |
else |
0807da593 [ARM] pxa: access... |
404 |
c->irq_edge_fall &= ~mask; |
e3630db1f [ARM] pxa: move G... |
405 |
|
a8f6faeba [ARM] pxa: fix is... |
406 |
update_edge_detect(c); |
e3630db1f [ARM] pxa: move G... |
407 |
|
a3f4c927d ARM: PXA SoCs: ir... |
408 409 |
pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s ", __func__, d->irq, gpio, |
e3630db1f [ARM] pxa: move G... |
410 411 412 413 |
((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""), ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : "")); return 0; } |
384ca3c6a gpio: pxa: change... |
414 |
static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d) |
e3630db1f [ARM] pxa: move G... |
415 |
{ |
fc0589ca6 gpio: pxa: conver... |
416 |
int loop, gpio, n, handled = 0; |
0807da593 [ARM] pxa: access... |
417 |
unsigned long gedr; |
384ca3c6a gpio: pxa: change... |
418 |
struct pxa_gpio_chip *pchip = d; |
fc0589ca6 gpio: pxa: conver... |
419 |
struct pxa_gpio_bank *c; |
0d2ee5d77 gpio: pxa: add ch... |
420 |
|
e3630db1f [ARM] pxa: move G... |
421 |
do { |
e3630db1f [ARM] pxa: move G... |
422 |
loop = 0; |
fc0589ca6 gpio: pxa: conver... |
423 |
for_each_gpio_bank(gpio, c, pchip) { |
df664d208 ARM: pxa: use lit... |
424 |
gedr = readl_relaxed(c->regbase + GEDR_OFFSET); |
0807da593 [ARM] pxa: access... |
425 |
gedr = gedr & c->irq_mask; |
df664d208 ARM: pxa: use lit... |
426 |
writel_relaxed(gedr, c->regbase + GEDR_OFFSET); |
e3630db1f [ARM] pxa: move G... |
427 |
|
d724f1c9c gpio: pxa: using ... |
428 |
for_each_set_bit(n, &gedr, BITS_PER_LONG) { |
0807da593 [ARM] pxa: access... |
429 |
loop = 1; |
e3630db1f [ARM] pxa: move G... |
430 |
|
fc0589ca6 gpio: pxa: conver... |
431 |
generic_handle_irq(gpio_to_irq(gpio + n)); |
0807da593 [ARM] pxa: access... |
432 |
} |
e3630db1f [ARM] pxa: move G... |
433 |
} |
384ca3c6a gpio: pxa: change... |
434 |
handled += loop; |
e3630db1f [ARM] pxa: move G... |
435 |
} while (loop); |
0d2ee5d77 gpio: pxa: add ch... |
436 |
|
384ca3c6a gpio: pxa: change... |
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
return handled ? IRQ_HANDLED : IRQ_NONE; } static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d) { struct pxa_gpio_chip *pchip = d; if (in_irq == pchip->irq0) { generic_handle_irq(gpio_to_irq(0)); } else if (in_irq == pchip->irq1) { generic_handle_irq(gpio_to_irq(1)); } else { pr_err("%s() unknown irq %d ", __func__, in_irq); return IRQ_NONE; } return IRQ_HANDLED; |
e3630db1f [ARM] pxa: move G... |
454 |
} |
a3f4c927d ARM: PXA SoCs: ir... |
455 |
static void pxa_ack_muxed_gpio(struct irq_data *d) |
e3630db1f [ARM] pxa: move G... |
456 |
{ |
384ca3c6a gpio: pxa: change... |
457 458 |
struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); unsigned int gpio = irqd_to_hwirq(d); |
fc0589ca6 gpio: pxa: conver... |
459 |
void __iomem *base = gpio_bank_base(&pchip->chip, gpio); |
0807da593 [ARM] pxa: access... |
460 |
|
fc0589ca6 gpio: pxa: conver... |
461 |
writel_relaxed(GPIO_bit(gpio), base + GEDR_OFFSET); |
e3630db1f [ARM] pxa: move G... |
462 |
} |
a3f4c927d ARM: PXA SoCs: ir... |
463 |
static void pxa_mask_muxed_gpio(struct irq_data *d) |
e3630db1f [ARM] pxa: move G... |
464 |
{ |
384ca3c6a gpio: pxa: change... |
465 466 |
struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); unsigned int gpio = irqd_to_hwirq(d); |
fc0589ca6 gpio: pxa: conver... |
467 468 |
struct pxa_gpio_bank *b = gpio_to_pxabank(&pchip->chip, gpio); void __iomem *base = gpio_bank_base(&pchip->chip, gpio); |
0807da593 [ARM] pxa: access... |
469 |
uint32_t grer, gfer; |
fc0589ca6 gpio: pxa: conver... |
470 |
b->irq_mask &= ~GPIO_bit(gpio); |
0807da593 [ARM] pxa: access... |
471 |
|
fc0589ca6 gpio: pxa: conver... |
472 473 474 475 |
grer = readl_relaxed(base + GRER_OFFSET) & ~GPIO_bit(gpio); gfer = readl_relaxed(base + GFER_OFFSET) & ~GPIO_bit(gpio); writel_relaxed(grer, base + GRER_OFFSET); writel_relaxed(gfer, base + GFER_OFFSET); |
e3630db1f [ARM] pxa: move G... |
476 |
} |
b95ace54a ARM: pxa: fix gpi... |
477 478 |
static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) { |
384ca3c6a gpio: pxa: change... |
479 480 |
struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); unsigned int gpio = irqd_to_hwirq(d); |
b95ace54a ARM: pxa: fix gpi... |
481 |
|
fc0589ca6 gpio: pxa: conver... |
482 483 |
if (pchip->set_wake) return pchip->set_wake(gpio, on); |
b95ace54a ARM: pxa: fix gpi... |
484 485 486 |
else return 0; } |
a3f4c927d ARM: PXA SoCs: ir... |
487 |
static void pxa_unmask_muxed_gpio(struct irq_data *d) |
e3630db1f [ARM] pxa: move G... |
488 |
{ |
384ca3c6a gpio: pxa: change... |
489 490 |
struct pxa_gpio_chip *pchip = irq_data_get_irq_chip_data(d); unsigned int gpio = irqd_to_hwirq(d); |
fc0589ca6 gpio: pxa: conver... |
491 |
struct pxa_gpio_bank *c = gpio_to_pxabank(&pchip->chip, gpio); |
0807da593 [ARM] pxa: access... |
492 493 |
c->irq_mask |= GPIO_bit(gpio); |
a8f6faeba [ARM] pxa: fix is... |
494 |
update_edge_detect(c); |
e3630db1f [ARM] pxa: move G... |
495 496 497 498 |
} static struct irq_chip pxa_muxed_gpio_chip = { .name = "GPIO", |
a3f4c927d ARM: PXA SoCs: ir... |
499 500 501 502 |
.irq_ack = pxa_ack_muxed_gpio, .irq_mask = pxa_mask_muxed_gpio, .irq_unmask = pxa_unmask_muxed_gpio, .irq_set_type = pxa_gpio_irq_type, |
b95ace54a ARM: pxa: fix gpi... |
503 |
.irq_set_wake = pxa_gpio_set_wake, |
e3630db1f [ARM] pxa: move G... |
504 |
}; |
2cab02922 ARM: pxa: remove ... |
505 |
static int pxa_gpio_nums(struct platform_device *pdev) |
478e223cc ARM: pxa: recogni... |
506 |
{ |
2cab02922 ARM: pxa: remove ... |
507 508 |
const struct platform_device_id *id = platform_get_device_id(pdev); struct pxa_gpio_id *pxa_id = (struct pxa_gpio_id *)id->driver_data; |
478e223cc ARM: pxa: recogni... |
509 |
int count = 0; |
2cab02922 ARM: pxa: remove ... |
510 511 512 513 514 515 516 517 |
switch (pxa_id->type) { case PXA25X_GPIO: case PXA26X_GPIO: case PXA27X_GPIO: case PXA3XX_GPIO: case PXA93X_GPIO: case MMP_GPIO: case MMP2_GPIO: |
684bba2ff gpio: pxa: add PX... |
518 |
case PXA1928_GPIO: |
2cab02922 ARM: pxa: remove ... |
519 520 521 522 523 524 |
gpio_type = pxa_id->type; count = pxa_id->gpio_nums - 1; break; default: count = -EINVAL; break; |
478e223cc ARM: pxa: recogni... |
525 |
} |
478e223cc ARM: pxa: recogni... |
526 527 |
return count; } |
7a4d5079b gpio: pxa: parse ... |
528 529 530 531 532 |
static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, handle_edge_irq); |
384ca3c6a gpio: pxa: change... |
533 |
irq_set_chip_data(irq, d->host_data); |
23393d49f gpio: kill off se... |
534 |
irq_set_noprobe(irq); |
7a4d5079b gpio: pxa: parse ... |
535 536 537 538 539 |
return 0; } const struct irq_domain_ops pxa_irq_domain_ops = { .map = pxa_irq_domain_map, |
721215726 GPIO: gpio-pxa: f... |
540 |
.xlate = irq_domain_xlate_twocell, |
7a4d5079b gpio: pxa: parse ... |
541 |
}; |
0440091be gpio: pxa: fixes ... |
542 543 544 545 546 547 548 549 550 551 552 553 |
#ifdef CONFIG_OF static const struct of_device_id pxa_gpio_dt_ids[] = { { .compatible = "intel,pxa25x-gpio", .data = &pxa25x_id, }, { .compatible = "intel,pxa26x-gpio", .data = &pxa26x_id, }, { .compatible = "intel,pxa27x-gpio", .data = &pxa27x_id, }, { .compatible = "intel,pxa3xx-gpio", .data = &pxa3xx_id, }, { .compatible = "marvell,pxa93x-gpio", .data = &pxa93x_id, }, { .compatible = "marvell,mmp-gpio", .data = &mmp_id, }, { .compatible = "marvell,mmp2-gpio", .data = &mmp2_id, }, { .compatible = "marvell,pxa1928-gpio", .data = &pxa1928_id, }, {} }; |
fc0589ca6 gpio: pxa: conver... |
554 555 |
static int pxa_gpio_probe_dt(struct platform_device *pdev, struct pxa_gpio_chip *pchip) |
7a4d5079b gpio: pxa: parse ... |
556 |
{ |
fc0589ca6 gpio: pxa: conver... |
557 |
int nr_gpios; |
7a4d5079b gpio: pxa: parse ... |
558 559 |
const struct of_device_id *of_id = of_match_device(pxa_gpio_dt_ids, &pdev->dev); |
f87311743 ARM: mmp: add mor... |
560 |
const struct pxa_gpio_id *gpio_id; |
7a4d5079b gpio: pxa: parse ... |
561 |
|
f87311743 ARM: mmp: add mor... |
562 |
if (!of_id || !of_id->data) { |
7a4d5079b gpio: pxa: parse ... |
563 564 565 566 |
dev_err(&pdev->dev, "Failed to find gpio controller "); return -EFAULT; } |
f87311743 ARM: mmp: add mor... |
567 568 |
gpio_id = of_id->data; gpio_type = gpio_id->type; |
7a4d5079b gpio: pxa: parse ... |
569 |
|
f87311743 ARM: mmp: add mor... |
570 |
nr_gpios = gpio_id->gpio_nums; |
7a4d5079b gpio: pxa: parse ... |
571 572 573 574 575 576 |
pxa_last_gpio = nr_gpios - 1; irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); if (irq_base < 0) { dev_err(&pdev->dev, "Failed to allocate IRQ numbers "); |
fc0589ca6 gpio: pxa: conver... |
577 |
return irq_base; |
7a4d5079b gpio: pxa: parse ... |
578 |
} |
384ca3c6a gpio: pxa: change... |
579 |
return irq_base; |
7a4d5079b gpio: pxa: parse ... |
580 581 |
} #else |
fc0589ca6 gpio: pxa: conver... |
582 |
#define pxa_gpio_probe_dt(pdev, pchip) (-1) |
7a4d5079b gpio: pxa: parse ... |
583 |
#endif |
3836309d9 gpio: remove use ... |
584 |
static int pxa_gpio_probe(struct platform_device *pdev) |
e3630db1f [ARM] pxa: move G... |
585 |
{ |
fc0589ca6 gpio: pxa: conver... |
586 587 |
struct pxa_gpio_chip *pchip; struct pxa_gpio_bank *c; |
157d2644c ARM: pxa: change ... |
588 |
struct resource *res; |
389eda15e ARM: pxa: add clk... |
589 |
struct clk *clk; |
b95ace54a ARM: pxa: fix gpi... |
590 |
struct pxa_gpio_platform_data *info; |
fc0589ca6 gpio: pxa: conver... |
591 |
void __iomem *gpio_reg_base; |
384ca3c6a gpio: pxa: change... |
592 |
int gpio, ret; |
157d2644c ARM: pxa: change ... |
593 |
int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
e3630db1f [ARM] pxa: move G... |
594 |
|
fc0589ca6 gpio: pxa: conver... |
595 596 597 598 |
pchip = devm_kzalloc(&pdev->dev, sizeof(*pchip), GFP_KERNEL); if (!pchip) return -ENOMEM; pchip->dev = &pdev->dev; |
b8f649f1f ARM: pxa: move PX... |
599 600 601 602 603 |
info = dev_get_platdata(&pdev->dev); if (info) { irq_base = info->irq_base; if (irq_base <= 0) return -EINVAL; |
2cab02922 ARM: pxa: remove ... |
604 |
pxa_last_gpio = pxa_gpio_nums(pdev); |
fc0589ca6 gpio: pxa: conver... |
605 |
pchip->set_wake = info->gpio_set_wake; |
9450be76d GPIO: gpio-pxa: s... |
606 |
} else { |
384ca3c6a gpio: pxa: change... |
607 608 |
irq_base = pxa_gpio_probe_dt(pdev, pchip); if (irq_base < 0) |
b8f649f1f ARM: pxa: move PX... |
609 |
return -EINVAL; |
9450be76d GPIO: gpio-pxa: s... |
610 |
} |
478e223cc ARM: pxa: recogni... |
611 |
if (!pxa_last_gpio) |
157d2644c ARM: pxa: change ... |
612 |
return -EINVAL; |
384ca3c6a gpio: pxa: change... |
613 614 615 |
pchip->irqdomain = irq_domain_add_legacy(pdev->dev.of_node, pxa_last_gpio + 1, irq_base, 0, &pxa_irq_domain_ops, pchip); |
41d107ad9 gpio: pxa: checki... |
616 617 |
if (!pchip->irqdomain) return -ENOMEM; |
384ca3c6a gpio: pxa: change... |
618 |
|
157d2644c ARM: pxa: change ... |
619 620 621 622 623 624 |
irq0 = platform_get_irq_byname(pdev, "gpio0"); irq1 = platform_get_irq_byname(pdev, "gpio1"); irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) || (irq_mux <= 0)) return -EINVAL; |
384ca3c6a gpio: pxa: change... |
625 626 627 |
pchip->irq0 = irq0; pchip->irq1 = irq1; |
157d2644c ARM: pxa: change ... |
628 |
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
8852b2f7d gpio: pxa: conver... |
629 630 |
gpio_reg_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); |
157d2644c ARM: pxa: change ... |
631 632 633 634 635 |
if (!gpio_reg_base) return -EINVAL; if (irq0 > 0) gpio_offset = 2; |
e3630db1f [ARM] pxa: move G... |
636 |
|
389eda15e ARM: pxa: add clk... |
637 638 639 640 641 |
clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "Error %ld to get gpio clock ", PTR_ERR(clk)); |
389eda15e ARM: pxa: add clk... |
642 643 |
return PTR_ERR(clk); } |
6ab49f420 drivers/gpio/gpio... |
644 |
ret = clk_prepare_enable(clk); |
389eda15e ARM: pxa: add clk... |
645 646 |
if (ret) { clk_put(clk); |
389eda15e ARM: pxa: add clk... |
647 648 |
return ret; } |
389eda15e ARM: pxa: add clk... |
649 |
|
0807da593 [ARM] pxa: access... |
650 |
/* Initialize GPIO chips */ |
384ca3c6a gpio: pxa: change... |
651 652 |
ret = pxa_init_gpio_chip(pchip, pxa_last_gpio + 1, pdev->dev.of_node, gpio_reg_base); |
fc0589ca6 gpio: pxa: conver... |
653 654 655 656 |
if (ret) { clk_put(clk); return ret; } |
0807da593 [ARM] pxa: access... |
657 |
|
e3630db1f [ARM] pxa: move G... |
658 |
/* clear all GPIO edge detects */ |
fc0589ca6 gpio: pxa: conver... |
659 |
for_each_gpio_bank(gpio, c, pchip) { |
df664d208 ARM: pxa: use lit... |
660 661 |
writel_relaxed(0, c->regbase + GFER_OFFSET); writel_relaxed(0, c->regbase + GRER_OFFSET); |
e37f4af76 gpio: gpio-pxa.c:... |
662 |
writel_relaxed(~0, c->regbase + GEDR_OFFSET); |
be24168f1 ARM: mmp: clear g... |
663 664 665 |
/* unmask GPIO edge detect for AP side */ if (gpio_is_mmp_type(gpio_type)) writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); |
e3630db1f [ARM] pxa: move G... |
666 |
} |
384ca3c6a gpio: pxa: change... |
667 668 669 670 671 672 673 674 |
if (irq0 > 0) { ret = devm_request_irq(&pdev->dev, irq0, pxa_gpio_direct_handler, 0, "gpio-0", pchip); if (ret) dev_err(&pdev->dev, "request of gpio0 irq failed: %d ", ret); |
e3630db1f [ARM] pxa: move G... |
675 |
} |
384ca3c6a gpio: pxa: change... |
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
if (irq1 > 0) { ret = devm_request_irq(&pdev->dev, irq1, pxa_gpio_direct_handler, 0, "gpio-1", pchip); if (ret) dev_err(&pdev->dev, "request of gpio1 irq failed: %d ", ret); } ret = devm_request_irq(&pdev->dev, irq_mux, pxa_gpio_demux_handler, 0, "gpio-mux", pchip); if (ret) dev_err(&pdev->dev, "request of gpio-mux irq failed: %d ", ret); |
e3630db1f [ARM] pxa: move G... |
692 |
|
fc0589ca6 gpio: pxa: conver... |
693 |
pxa_gpio_chip = pchip; |
ae4f4cfd8 gpio: pxa: remove... |
694 |
|
157d2644c ARM: pxa: change ... |
695 696 |
return 0; } |
2cab02922 ARM: pxa: remove ... |
697 698 699 700 701 702 703 704 |
static const struct platform_device_id gpio_id_table[] = { { "pxa25x-gpio", (unsigned long)&pxa25x_id }, { "pxa26x-gpio", (unsigned long)&pxa26x_id }, { "pxa27x-gpio", (unsigned long)&pxa27x_id }, { "pxa3xx-gpio", (unsigned long)&pxa3xx_id }, { "pxa93x-gpio", (unsigned long)&pxa93x_id }, { "mmp-gpio", (unsigned long)&mmp_id }, { "mmp2-gpio", (unsigned long)&mmp2_id }, |
684bba2ff gpio: pxa: add PX... |
705 |
{ "pxa1928-gpio", (unsigned long)&pxa1928_id }, |
2cab02922 ARM: pxa: remove ... |
706 707 |
{ }, }; |
157d2644c ARM: pxa: change ... |
708 709 710 711 |
static struct platform_driver pxa_gpio_driver = { .probe = pxa_gpio_probe, .driver = { .name = "pxa-gpio", |
f43e04ec4 GPIO: gpio-pxa: f... |
712 |
.of_match_table = of_match_ptr(pxa_gpio_dt_ids), |
157d2644c ARM: pxa: change ... |
713 |
}, |
2cab02922 ARM: pxa: remove ... |
714 |
.id_table = gpio_id_table, |
157d2644c ARM: pxa: change ... |
715 |
}; |
cf3fa17c2 Revert "gpio: pxa... |
716 |
|
eae122b82 gpio: pxa: change... |
717 |
static int __init pxa_gpio_legacy_init(void) |
cf3fa17c2 Revert "gpio: pxa... |
718 |
{ |
eae122b82 gpio: pxa: change... |
719 720 |
if (of_have_populated_dt()) return 0; |
cf3fa17c2 Revert "gpio: pxa... |
721 722 |
return platform_driver_register(&pxa_gpio_driver); } |
eae122b82 gpio: pxa: change... |
723 724 725 726 727 728 729 730 731 732 |
postcore_initcall(pxa_gpio_legacy_init); static int __init pxa_gpio_dt_init(void) { if (of_have_populated_dt()) return platform_driver_register(&pxa_gpio_driver); return 0; } device_initcall(pxa_gpio_dt_init); |
663707c1a [ARM] pxa: move G... |
733 734 |
#ifdef CONFIG_PM |
2eaa03b5b ARM / PXA: Use st... |
735 |
static int pxa_gpio_suspend(void) |
663707c1a [ARM] pxa: move G... |
736 |
{ |
fc0589ca6 gpio: pxa: conver... |
737 738 |
struct pxa_gpio_chip *pchip = pxa_gpio_chip; struct pxa_gpio_bank *c; |
0807da593 [ARM] pxa: access... |
739 |
int gpio; |
663707c1a [ARM] pxa: move G... |
740 |
|
fc0589ca6 gpio: pxa: conver... |
741 |
for_each_gpio_bank(gpio, c, pchip) { |
df664d208 ARM: pxa: use lit... |
742 743 744 745 |
c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET); c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET); |
663707c1a [ARM] pxa: move G... |
746 747 |
/* Clear GPIO transition detect bits */ |
df664d208 ARM: pxa: use lit... |
748 |
writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET); |
663707c1a [ARM] pxa: move G... |
749 750 751 |
} return 0; } |
2eaa03b5b ARM / PXA: Use st... |
752 |
static void pxa_gpio_resume(void) |
663707c1a [ARM] pxa: move G... |
753 |
{ |
fc0589ca6 gpio: pxa: conver... |
754 755 |
struct pxa_gpio_chip *pchip = pxa_gpio_chip; struct pxa_gpio_bank *c; |
0807da593 [ARM] pxa: access... |
756 |
int gpio; |
663707c1a [ARM] pxa: move G... |
757 |
|
fc0589ca6 gpio: pxa: conver... |
758 |
for_each_gpio_bank(gpio, c, pchip) { |
663707c1a [ARM] pxa: move G... |
759 |
/* restore level with set/clear */ |
e37f4af76 gpio: gpio-pxa.c:... |
760 |
writel_relaxed(c->saved_gplr, c->regbase + GPSR_OFFSET); |
df664d208 ARM: pxa: use lit... |
761 |
writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET); |
663707c1a [ARM] pxa: move G... |
762 |
|
df664d208 ARM: pxa: use lit... |
763 764 765 |
writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET); writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET); writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET); |
663707c1a [ARM] pxa: move G... |
766 |
} |
663707c1a [ARM] pxa: move G... |
767 768 769 770 771 |
} #else #define pxa_gpio_suspend NULL #define pxa_gpio_resume NULL #endif |
2eaa03b5b ARM / PXA: Use st... |
772 |
struct syscore_ops pxa_gpio_syscore_ops = { |
663707c1a [ARM] pxa: move G... |
773 774 775 |
.suspend = pxa_gpio_suspend, .resume = pxa_gpio_resume, }; |
157d2644c ARM: pxa: change ... |
776 777 778 779 780 781 782 |
static int __init pxa_gpio_sysinit(void) { register_syscore_ops(&pxa_gpio_syscore_ops); return 0; } postcore_initcall(pxa_gpio_sysinit); |