gpio-pxa.c (df664d20814f9b3c3020ced7088a328b477ecf8d) | gpio-pxa.c (157d2644cb0c1e71a18baaffca56d2b1d0ebf10f) |
---|---|
1/* 2 * linux/arch/arm/plat-pxa/gpio.c 3 * 4 * Generic PXA GPIO handling 5 * 6 * Author: Nicolas Pitre 7 * Created: Jun 15, 2001 8 * Copyright: MontaVista Software Inc. 9 * 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. 13 */ 14#include <linux/gpio.h> | 1/* 2 * linux/arch/arm/plat-pxa/gpio.c 3 * 4 * Generic PXA GPIO handling 5 * 6 * Author: Nicolas Pitre 7 * Created: Jun 15, 2001 8 * Copyright: MontaVista Software Inc. 9 * 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. 13 */ 14#include <linux/gpio.h> |
15#include <linux/gpio-pxa.h> |
|
15#include <linux/init.h> 16#include <linux/irq.h> 17#include <linux/io.h> | 16#include <linux/init.h> 17#include <linux/irq.h> 18#include <linux/io.h> |
19#include <linux/platform_device.h> |
|
18#include <linux/syscore_ops.h> 19#include <linux/slab.h> 20 | 20#include <linux/syscore_ops.h> 21#include <linux/slab.h> 22 |
21#include <mach/gpio-pxa.h> | 23/* 24 * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with 25 * one set of registers. The register offsets are organized below: 26 * 27 * GPLR GPDR GPSR GPCR GRER GFER GEDR 28 * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 29 * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C 30 * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 31 * 32 * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 33 * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C 34 * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 35 * 36 * NOTE: 37 * BANK 3 is only available on PXA27x and later processors. 38 * BANK 4 and 5 are only available on PXA935 39 */ |
22 | 40 |
41#define GPLR_OFFSET 0x00 42#define GPDR_OFFSET 0x0C 43#define GPSR_OFFSET 0x18 44#define GPCR_OFFSET 0x24 45#define GRER_OFFSET 0x30 46#define GFER_OFFSET 0x3C 47#define GEDR_OFFSET 0x48 48#define GAFR_OFFSET 0x54 49 50#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) 51 |
|
23int pxa_last_gpio; 24 25struct pxa_gpio_chip { 26 struct gpio_chip chip; 27 void __iomem *regbase; 28 char label[10]; 29 30 unsigned long irq_mask; --- 16 unchanged lines hidden (view full) --- 47 PXA93X_GPIO, 48 MMP_GPIO = 0x10, 49 MMP2_GPIO, 50}; 51 52static DEFINE_SPINLOCK(gpio_lock); 53static struct pxa_gpio_chip *pxa_gpio_chips; 54static int gpio_type; | 52int pxa_last_gpio; 53 54struct pxa_gpio_chip { 55 struct gpio_chip chip; 56 void __iomem *regbase; 57 char label[10]; 58 59 unsigned long irq_mask; --- 16 unchanged lines hidden (view full) --- 76 PXA93X_GPIO, 77 MMP_GPIO = 0x10, 78 MMP2_GPIO, 79}; 80 81static DEFINE_SPINLOCK(gpio_lock); 82static struct pxa_gpio_chip *pxa_gpio_chips; 83static int gpio_type; |
84static void __iomem *gpio_reg_base; |
|
55 56#define for_each_gpio_chip(i, c) \ 57 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) 58 59static inline void __iomem *gpio_chip_base(struct gpio_chip *c) 60{ 61 return container_of(c, struct pxa_gpio_chip, chip)->regbase; 62} --- 8 unchanged lines hidden (view full) --- 71 return (type & MMP_GPIO) == 0; 72} 73 74static inline int gpio_is_mmp_type(int type) 75{ 76 return (type & MMP_GPIO) != 0; 77} 78 | 85 86#define for_each_gpio_chip(i, c) \ 87 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) 88 89static inline void __iomem *gpio_chip_base(struct gpio_chip *c) 90{ 91 return container_of(c, struct pxa_gpio_chip, chip)->regbase; 92} --- 8 unchanged lines hidden (view full) --- 101 return (type & MMP_GPIO) == 0; 102} 103 104static inline int gpio_is_mmp_type(int type) 105{ 106 return (type & MMP_GPIO) != 0; 107} 108 |
109/* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, 110 * as well as their Alternate Function value being '1' for GPIO in GAFRx. 111 */ 112static inline int __gpio_is_inverted(int gpio) 113{ 114 if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) 115 return 1; 116 return 0; 117} 118 119/* 120 * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate 121 * function of a GPIO, and GPDRx cannot be altered once configured. It 122 * is attributed as "occupied" here (I know this terminology isn't 123 * accurate, you are welcome to propose a better one :-) 124 */ 125static inline int __gpio_is_occupied(unsigned gpio) 126{ 127 struct pxa_gpio_chip *pxachip; 128 void __iomem *base; 129 unsigned long gafr = 0, gpdr = 0; 130 int ret, af = 0, dir = 0; 131 132 pxachip = gpio_to_pxachip(gpio); 133 base = gpio_chip_base(&pxachip->chip); 134 gpdr = readl_relaxed(base + GPDR_OFFSET); 135 136 switch (gpio_type) { 137 case PXA25X_GPIO: 138 case PXA26X_GPIO: 139 case PXA27X_GPIO: 140 gafr = readl_relaxed(base + GAFR_OFFSET); 141 af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; 142 dir = gpdr & GPIO_bit(gpio); 143 144 if (__gpio_is_inverted(gpio)) 145 ret = (af != 1) || (dir == 0); 146 else 147 ret = (af != 0) || (dir != 0); 148 break; 149 default: 150 ret = gpdr & GPIO_bit(gpio); 151 break; 152 } 153 return ret; 154} 155 |
|
79#ifdef CONFIG_ARCH_PXA 80static inline int __pxa_gpio_to_irq(int gpio) 81{ 82 if (gpio_is_pxa_type(gpio_type)) 83 return PXA_GPIO_TO_IRQ(gpio); 84 return -1; 85} 86 --- 95 unchanged lines hidden (view full) --- 182} 183 184static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 185{ 186 writel_relaxed(1 << offset, gpio_chip_base(chip) + 187 (value ? GPSR_OFFSET : GPCR_OFFSET)); 188} 189 | 156#ifdef CONFIG_ARCH_PXA 157static inline int __pxa_gpio_to_irq(int gpio) 158{ 159 if (gpio_is_pxa_type(gpio_type)) 160 return PXA_GPIO_TO_IRQ(gpio); 161 return -1; 162} 163 --- 95 unchanged lines hidden (view full) --- 259} 260 261static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 262{ 263 writel_relaxed(1 << offset, gpio_chip_base(chip) + 264 (value ? GPSR_OFFSET : GPCR_OFFSET)); 265} 266 |
190static int __init pxa_init_gpio_chip(int gpio_end) | 267static int __devinit pxa_init_gpio_chip(int gpio_end) |
191{ 192 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; 193 struct pxa_gpio_chip *chips; 194 195 chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); 196 if (chips == NULL) { 197 pr_err("%s: failed to allocate GPIO chips\n", __func__); 198 return -ENOMEM; 199 } 200 201 for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { 202 struct gpio_chip *c = &chips[i].chip; 203 204 sprintf(chips[i].label, "gpio-%d", i); | 268{ 269 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; 270 struct pxa_gpio_chip *chips; 271 272 chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); 273 if (chips == NULL) { 274 pr_err("%s: failed to allocate GPIO chips\n", __func__); 275 return -ENOMEM; 276 } 277 278 for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { 279 struct gpio_chip *c = &chips[i].chip; 280 281 sprintf(chips[i].label, "gpio-%d", i); |
205 chips[i].regbase = GPIO_BANK(i); | 282 chips[i].regbase = gpio_reg_base + BANK_OFF(i); |
206 207 c->base = gpio; 208 c->label = chips[i].label; 209 210 c->direction_input = pxa_gpio_direction_input; 211 c->direction_output = pxa_gpio_direction_output; 212 c->get = pxa_gpio_get; 213 c->set = pxa_gpio_set; --- 165 unchanged lines hidden (view full) --- 379 } else if (cpu_is_mmp2()) { 380 count = 191; 381 gpio_type = MMP2_GPIO; 382 } 383#endif /* CONFIG_ARCH_MMP */ 384 return count; 385} 386 | 283 284 c->base = gpio; 285 c->label = chips[i].label; 286 287 c->direction_input = pxa_gpio_direction_input; 288 c->direction_output = pxa_gpio_direction_output; 289 c->get = pxa_gpio_get; 290 c->set = pxa_gpio_set; --- 165 unchanged lines hidden (view full) --- 456 } else if (cpu_is_mmp2()) { 457 count = 191; 458 gpio_type = MMP2_GPIO; 459 } 460#endif /* CONFIG_ARCH_MMP */ 461 return count; 462} 463 |
387void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) | 464static int __devinit pxa_gpio_probe(struct platform_device *pdev) |
388{ 389 struct pxa_gpio_chip *c; | 465{ 466 struct pxa_gpio_chip *c; |
467 struct resource *res; |
|
390 int gpio, irq; | 468 int gpio, irq; |
469 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
|
391 392 pxa_last_gpio = pxa_gpio_nums(); 393 if (!pxa_last_gpio) | 470 471 pxa_last_gpio = pxa_gpio_nums(); 472 if (!pxa_last_gpio) |
394 return; | 473 return -EINVAL; |
395 | 474 |
475 irq0 = platform_get_irq_byname(pdev, "gpio0"); 476 irq1 = platform_get_irq_byname(pdev, "gpio1"); 477 irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); 478 if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) 479 || (irq_mux <= 0)) 480 return -EINVAL; 481 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 482 if (!res) 483 return -EINVAL; 484 gpio_reg_base = ioremap(res->start, resource_size(res)); 485 if (!gpio_reg_base) 486 return -EINVAL; 487 488 if (irq0 > 0) 489 gpio_offset = 2; 490 |
|
396 /* Initialize GPIO chips */ | 491 /* Initialize GPIO chips */ |
397 pxa_init_gpio_chip(end); | 492 pxa_init_gpio_chip(pxa_last_gpio); |
398 399 /* clear all GPIO edge detects */ 400 for_each_gpio_chip(gpio, c) { 401 writel_relaxed(0, c->regbase + GFER_OFFSET); 402 writel_relaxed(0, c->regbase + GRER_OFFSET); 403 writel_relaxed(~0,c->regbase + GEDR_OFFSET); 404 } 405 --- 6 unchanged lines hidden (view full) --- 412 413 irq = gpio_to_irq(1); 414 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 415 handle_edge_irq); 416 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 417 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); 418#endif 419 | 493 494 /* clear all GPIO edge detects */ 495 for_each_gpio_chip(gpio, c) { 496 writel_relaxed(0, c->regbase + GFER_OFFSET); 497 writel_relaxed(0, c->regbase + GRER_OFFSET); 498 writel_relaxed(~0,c->regbase + GEDR_OFFSET); 499 } 500 --- 6 unchanged lines hidden (view full) --- 507 508 irq = gpio_to_irq(1); 509 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 510 handle_edge_irq); 511 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 512 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); 513#endif 514 |
420 for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { | 515 for (irq = gpio_to_irq(gpio_offset); 516 irq <= gpio_to_irq(pxa_last_gpio); irq++) { |
421 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 422 handle_edge_irq); 423 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 424 } 425 | 517 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 518 handle_edge_irq); 519 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 520 } 521 |
426 /* Install handler for GPIO>=2 edge detect interrupts */ 427 irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler); 428 pxa_muxed_gpio_chip.irq_set_wake = fn; | 522 irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); 523 return 0; |
429} 430 | 524} 525 |
526static struct platform_driver pxa_gpio_driver = { 527 .probe = pxa_gpio_probe, 528 .driver = { 529 .name = "pxa-gpio", 530 }, 531}; 532 533static int __init pxa_gpio_init(void) 534{ 535 return platform_driver_register(&pxa_gpio_driver); 536} 537postcore_initcall(pxa_gpio_init); 538 |
|
431#ifdef CONFIG_PM 432static int pxa_gpio_suspend(void) 433{ 434 struct pxa_gpio_chip *c; 435 int gpio; 436 437 for_each_gpio_chip(gpio, c) { 438 c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); --- 26 unchanged lines hidden (view full) --- 465#define pxa_gpio_suspend NULL 466#define pxa_gpio_resume NULL 467#endif 468 469struct syscore_ops pxa_gpio_syscore_ops = { 470 .suspend = pxa_gpio_suspend, 471 .resume = pxa_gpio_resume, 472}; | 539#ifdef CONFIG_PM 540static int pxa_gpio_suspend(void) 541{ 542 struct pxa_gpio_chip *c; 543 int gpio; 544 545 for_each_gpio_chip(gpio, c) { 546 c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); --- 26 unchanged lines hidden (view full) --- 573#define pxa_gpio_suspend NULL 574#define pxa_gpio_resume NULL 575#endif 576 577struct syscore_ops pxa_gpio_syscore_ops = { 578 .suspend = pxa_gpio_suspend, 579 .resume = pxa_gpio_resume, 580}; |
581 582static int __init pxa_gpio_sysinit(void) 583{ 584 register_syscore_ops(&pxa_gpio_syscore_ops); 585 return 0; 586} 587postcore_initcall(pxa_gpio_sysinit); |
|