aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@marvell.com>2011-10-17 08:37:52 -0400
committerHaojian Zhuang <hzhuang1@hexinfolabs.org>2011-11-15 06:08:27 -0500
commit157d2644cb0c1e71a18baaffca56d2b1d0ebf10f (patch)
treee33d224362ce8ac0706725f02ecd8b89c3645934 /drivers/gpio
parent9bf448c66d4b4cb03813b39195d408701ecf1fab (diff)
ARM: pxa: change gpio to platform device
Remove most gpio macros and change gpio driver to platform driver. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/gpio-pxa.c135
3 files changed, 132 insertions, 11 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8482a23887dc..aa0b94ff36d0 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -141,6 +141,12 @@ config GPIO_PL061
141 help 141 help
142 Say yes here to support the PrimeCell PL061 GPIO device 142 Say yes here to support the PrimeCell PL061 GPIO device
143 143
144config GPIO_PXA
145 bool "PXA GPIO support"
146 depends on ARCH_PXA || ARCH_MMP
147 help
148 Say yes here to support the PXA GPIO device
149
144config GPIO_XILINX 150config GPIO_XILINX
145 bool "Xilinx GPIO support" 151 bool "Xilinx GPIO support"
146 depends on PPC_OF || MICROBLAZE 152 depends on PPC_OF || MICROBLAZE
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index dbcb0bcfd8da..5b2b9e26f49c 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
40obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o 40obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
41obj-$(CONFIG_GPIO_PCH) += gpio-pch.o 41obj-$(CONFIG_GPIO_PCH) += gpio-pch.o
42obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o 42obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
43obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o 43obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
44obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o 44obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
45obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o 45obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
46obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o 46obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 31d2da4100cd..079f97fde2c7 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -12,13 +12,42 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/gpio-pxa.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/irq.h> 17#include <linux/irq.h>
17#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/platform_device.h>
18#include <linux/syscore_ops.h> 20#include <linux/syscore_ops.h>
19#include <linux/slab.h> 21#include <linux/slab.h>
20 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 */
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))
22 51
23int pxa_last_gpio; 52int pxa_last_gpio;
24 53
@@ -52,6 +81,7 @@ enum {
52static DEFINE_SPINLOCK(gpio_lock); 81static DEFINE_SPINLOCK(gpio_lock);
53static struct pxa_gpio_chip *pxa_gpio_chips; 82static struct pxa_gpio_chip *pxa_gpio_chips;
54static int gpio_type; 83static int gpio_type;
84static void __iomem *gpio_reg_base;
55 85
56#define for_each_gpio_chip(i, c) \ 86#define for_each_gpio_chip(i, c) \
57 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) 87 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
@@ -76,6 +106,53 @@ static inline int gpio_is_mmp_type(int type)
76 return (type & MMP_GPIO) != 0; 106 return (type & MMP_GPIO) != 0;
77} 107}
78 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 156#ifdef CONFIG_ARCH_PXA
80static inline int __pxa_gpio_to_irq(int gpio) 157static inline int __pxa_gpio_to_irq(int gpio)
81{ 158{
@@ -187,7 +264,7 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
187 (value ? GPSR_OFFSET : GPCR_OFFSET)); 264 (value ? GPSR_OFFSET : GPCR_OFFSET));
188} 265}
189 266
190static int __init pxa_init_gpio_chip(int gpio_end) 267static int __devinit pxa_init_gpio_chip(int gpio_end)
191{ 268{
192 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; 269 int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
193 struct pxa_gpio_chip *chips; 270 struct pxa_gpio_chip *chips;
@@ -202,7 +279,7 @@ static int __init pxa_init_gpio_chip(int gpio_end)
202 struct gpio_chip *c = &chips[i].chip; 279 struct gpio_chip *c = &chips[i].chip;
203 280
204 sprintf(chips[i].label, "gpio-%d", i); 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 283
207 c->base = gpio; 284 c->base = gpio;
208 c->label = chips[i].label; 285 c->label = chips[i].label;
@@ -384,17 +461,35 @@ static int pxa_gpio_nums(void)
384 return count; 461 return count;
385} 462}
386 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{ 465{
389 struct pxa_gpio_chip *c; 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 470
392 pxa_last_gpio = pxa_gpio_nums(); 471 pxa_last_gpio = pxa_gpio_nums();
393 if (!pxa_last_gpio) 472 if (!pxa_last_gpio)
394 return; 473 return -EINVAL;
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;
395 490
396 /* Initialize GPIO chips */ 491 /* Initialize GPIO chips */
397 pxa_init_gpio_chip(end); 492 pxa_init_gpio_chip(pxa_last_gpio);
398 493
399 /* clear all GPIO edge detects */ 494 /* clear all GPIO edge detects */
400 for_each_gpio_chip(gpio, c) { 495 for_each_gpio_chip(gpio, c) {
@@ -417,16 +512,29 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
417 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); 512 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
418#endif 513#endif
419 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, 517 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
422 handle_edge_irq); 518 handle_edge_irq);
423 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 519 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
424 } 520 }
425 521
426 /* Install handler for GPIO>=2 edge detect interrupts */ 522 irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler);
427 irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler); 523 return 0;
428 pxa_muxed_gpio_chip.irq_set_wake = fn; 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);
429} 536}
537postcore_initcall(pxa_gpio_init);
430 538
431#ifdef CONFIG_PM 539#ifdef CONFIG_PM
432static int pxa_gpio_suspend(void) 540static int pxa_gpio_suspend(void)
@@ -470,3 +578,10 @@ struct syscore_ops pxa_gpio_syscore_ops = {
470 .suspend = pxa_gpio_suspend, 578 .suspend = pxa_gpio_suspend,
471 .resume = pxa_gpio_resume, 579 .resume = pxa_gpio_resume,
472}; 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);