diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-11-29 04:51:07 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-11-29 04:51:07 -0500 |
commit | 0d2cd91bf7b1a7cc1d638296111fcc2bcf5c0bb4 (patch) | |
tree | d2ca69347816c27f9dc352581f5d0fe76811cd49 /drivers/gpio | |
parent | 3d95fd6ad8d3cf582a70ed65660017114b6e4065 (diff) | |
parent | caca6a03d365883564885f2c1da3e88dcf65d139 (diff) |
Merge commit 'v3.2-rc3' into next
Diffstat (limited to 'drivers/gpio')
33 files changed, 6530 insertions, 1880 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d539efd96d4b..8482a23887dc 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -95,14 +95,18 @@ config GPIO_EP93XX | |||
95 | depends on ARCH_EP93XX | 95 | depends on ARCH_EP93XX |
96 | select GPIO_GENERIC | 96 | select GPIO_GENERIC |
97 | 97 | ||
98 | config GPIO_EXYNOS4 | ||
99 | def_bool y | ||
100 | depends on CPU_EXYNOS4210 | ||
101 | |||
102 | config GPIO_MPC5200 | 98 | config GPIO_MPC5200 |
103 | def_bool y | 99 | def_bool y |
104 | depends on PPC_MPC52xx | 100 | depends on PPC_MPC52xx |
105 | 101 | ||
102 | config GPIO_MPC8XXX | ||
103 | bool "MPC512x/MPC8xxx GPIO support" | ||
104 | depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \ | ||
105 | FSL_SOC_BOOKE || PPC_86xx | ||
106 | help | ||
107 | Say Y here if you're going to use hardware that connects to the | ||
108 | MPC512x/831x/834x/837x/8572/8610 GPIOs. | ||
109 | |||
106 | config GPIO_MSM_V1 | 110 | config GPIO_MSM_V1 |
107 | tristate "Qualcomm MSM GPIO v1" | 111 | tristate "Qualcomm MSM GPIO v1" |
108 | depends on GPIOLIB && ARCH_MSM | 112 | depends on GPIOLIB && ARCH_MSM |
@@ -131,18 +135,6 @@ config GPIO_MXS | |||
131 | select GPIO_GENERIC | 135 | select GPIO_GENERIC |
132 | select GENERIC_IRQ_CHIP | 136 | select GENERIC_IRQ_CHIP |
133 | 137 | ||
134 | config GPIO_PLAT_SAMSUNG | ||
135 | def_bool y | ||
136 | depends on SAMSUNG_GPIOLIB_4BIT | ||
137 | |||
138 | config GPIO_S5PC100 | ||
139 | def_bool y | ||
140 | depends on CPU_S5PC100 | ||
141 | |||
142 | config GPIO_S5PV210 | ||
143 | def_bool y | ||
144 | depends on CPU_S5PV210 | ||
145 | |||
146 | config GPIO_PL061 | 138 | config GPIO_PL061 |
147 | bool "PrimeCell PL061 GPIO support" | 139 | bool "PrimeCell PL061 GPIO support" |
148 | depends on ARM_AMBA | 140 | depends on ARM_AMBA |
@@ -178,9 +170,18 @@ config GPIO_SCH | |||
178 | The Intel Tunnel Creek processor has 5 GPIOs powered by the | 170 | The Intel Tunnel Creek processor has 5 GPIOs powered by the |
179 | core power rail and 9 from suspend power supply. | 171 | core power rail and 9 from suspend power supply. |
180 | 172 | ||
173 | config GPIO_U300 | ||
174 | bool "ST-Ericsson U300 COH 901 335/571 GPIO" | ||
175 | depends on GPIOLIB && ARCH_U300 | ||
176 | help | ||
177 | Say yes here to support GPIO interface on ST-Ericsson U300. | ||
178 | The names of the two IP block variants supported are | ||
179 | COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 | ||
180 | ports of 8 GPIO pins each. | ||
181 | |||
181 | config GPIO_VX855 | 182 | config GPIO_VX855 |
182 | tristate "VIA VX855/VX875 GPIO" | 183 | tristate "VIA VX855/VX875 GPIO" |
183 | depends on MFD_SUPPORT && PCI | 184 | depends on PCI |
184 | select MFD_CORE | 185 | select MFD_CORE |
185 | select MFD_VX855 | 186 | select MFD_VX855 |
186 | help | 187 | help |
@@ -388,6 +389,7 @@ config GPIO_LANGWELL | |||
388 | config GPIO_PCH | 389 | config GPIO_PCH |
389 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO" | 390 | tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO" |
390 | depends on PCI && X86 | 391 | depends on PCI && X86 |
392 | select GENERIC_IRQ_CHIP | ||
391 | help | 393 | help |
392 | This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff | 394 | This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff |
393 | which is an IOH(Input/Output Hub) for x86 embedded processor. | 395 | which is an IOH(Input/Output Hub) for x86 embedded processor. |
@@ -402,6 +404,7 @@ config GPIO_PCH | |||
402 | config GPIO_ML_IOH | 404 | config GPIO_ML_IOH |
403 | tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" | 405 | tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" |
404 | depends on PCI | 406 | depends on PCI |
407 | select GENERIC_IRQ_CHIP | ||
405 | help | 408 | help |
406 | ML7213 is companion chip for Intel Atom E6xx series. | 409 | ML7213 is companion chip for Intel Atom E6xx series. |
407 | This driver can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/Output | 410 | This driver can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/Output |
@@ -417,7 +420,6 @@ config GPIO_TIMBERDALE | |||
417 | config GPIO_RDC321X | 420 | config GPIO_RDC321X |
418 | tristate "RDC R-321x GPIO support" | 421 | tristate "RDC R-321x GPIO support" |
419 | depends on PCI | 422 | depends on PCI |
420 | select MFD_SUPPORT | ||
421 | select MFD_CORE | 423 | select MFD_CORE |
422 | select MFD_RDC321X | 424 | select MFD_RDC321X |
423 | help | 425 | help |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9588948c96f0..dbcb0bcfd8da 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -14,11 +14,13 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o | |||
14 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 14 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
15 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 15 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
16 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 16 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
17 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | ||
17 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 18 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
18 | obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o | ||
19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o | 19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o |
20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o | 20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o |
21 | obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o | ||
21 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o | 22 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o |
23 | obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o | ||
22 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o | 24 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o |
23 | obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o | 25 | obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o |
24 | obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o | 26 | obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o |
@@ -27,6 +29,7 @@ obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o | |||
27 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o | 29 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o |
28 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o | 30 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o |
29 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o | 31 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o |
32 | obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o | ||
30 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o | 33 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o |
31 | obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o | 34 | obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o |
32 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o | 35 | obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o |
@@ -37,18 +40,17 @@ obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o | |||
37 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o | 40 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o |
38 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o | 41 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o |
39 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | 42 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o |
43 | obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o | ||
40 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o | 44 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o |
41 | 45 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | |
42 | obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o | 46 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
43 | obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o | ||
44 | obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o | ||
45 | |||
46 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o | 47 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
47 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 48 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
48 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o | 49 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o |
49 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o | 50 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o |
50 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o | 51 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o |
51 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o | 52 | obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o |
53 | obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o | ||
52 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o | 54 | obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o |
53 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o | 55 | obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o |
54 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o | 56 | obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o |
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index ff525c0958dd..a31ad6f5d910 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/spi/74x164.h> | 15 | #include <linux/spi/74x164.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/module.h> | ||
18 | 19 | ||
19 | struct gen_74x164_chip { | 20 | struct gen_74x164_chip { |
20 | struct spi_device *spi; | 21 | struct spi_device *spi; |
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c new file mode 100644 index 000000000000..df0d59570a84 --- /dev/null +++ b/drivers/gpio/gpio-davinci.c | |||
@@ -0,0 +1,455 @@ | |||
1 | /* | ||
2 | * TI DaVinci GPIO Support | ||
3 | * | ||
4 | * Copyright (c) 2006-2007 David Brownell | ||
5 | * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <asm/mach/irq.h> | ||
20 | |||
21 | struct davinci_gpio_regs { | ||
22 | u32 dir; | ||
23 | u32 out_data; | ||
24 | u32 set_data; | ||
25 | u32 clr_data; | ||
26 | u32 in_data; | ||
27 | u32 set_rising; | ||
28 | u32 clr_rising; | ||
29 | u32 set_falling; | ||
30 | u32 clr_falling; | ||
31 | u32 intstat; | ||
32 | }; | ||
33 | |||
34 | #define chip2controller(chip) \ | ||
35 | container_of(chip, struct davinci_gpio_controller, chip) | ||
36 | |||
37 | static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | ||
38 | static void __iomem *gpio_base; | ||
39 | |||
40 | static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio) | ||
41 | { | ||
42 | void __iomem *ptr; | ||
43 | |||
44 | if (gpio < 32 * 1) | ||
45 | ptr = gpio_base + 0x10; | ||
46 | else if (gpio < 32 * 2) | ||
47 | ptr = gpio_base + 0x38; | ||
48 | else if (gpio < 32 * 3) | ||
49 | ptr = gpio_base + 0x60; | ||
50 | else if (gpio < 32 * 4) | ||
51 | ptr = gpio_base + 0x88; | ||
52 | else if (gpio < 32 * 5) | ||
53 | ptr = gpio_base + 0xb0; | ||
54 | else | ||
55 | ptr = NULL; | ||
56 | return ptr; | ||
57 | } | ||
58 | |||
59 | static inline struct davinci_gpio_regs __iomem *irq2regs(int irq) | ||
60 | { | ||
61 | struct davinci_gpio_regs __iomem *g; | ||
62 | |||
63 | g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq); | ||
64 | |||
65 | return g; | ||
66 | } | ||
67 | |||
68 | static int __init davinci_gpio_irq_setup(void); | ||
69 | |||
70 | /*--------------------------------------------------------------------------*/ | ||
71 | |||
72 | /* board setup code *MUST* setup pinmux and enable the GPIO clock. */ | ||
73 | static inline int __davinci_direction(struct gpio_chip *chip, | ||
74 | unsigned offset, bool out, int value) | ||
75 | { | ||
76 | struct davinci_gpio_controller *d = chip2controller(chip); | ||
77 | struct davinci_gpio_regs __iomem *g = d->regs; | ||
78 | unsigned long flags; | ||
79 | u32 temp; | ||
80 | u32 mask = 1 << offset; | ||
81 | |||
82 | spin_lock_irqsave(&d->lock, flags); | ||
83 | temp = __raw_readl(&g->dir); | ||
84 | if (out) { | ||
85 | temp &= ~mask; | ||
86 | __raw_writel(mask, value ? &g->set_data : &g->clr_data); | ||
87 | } else { | ||
88 | temp |= mask; | ||
89 | } | ||
90 | __raw_writel(temp, &g->dir); | ||
91 | spin_unlock_irqrestore(&d->lock, flags); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int davinci_direction_in(struct gpio_chip *chip, unsigned offset) | ||
97 | { | ||
98 | return __davinci_direction(chip, offset, false, 0); | ||
99 | } | ||
100 | |||
101 | static int | ||
102 | davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) | ||
103 | { | ||
104 | return __davinci_direction(chip, offset, true, value); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Read the pin's value (works even if it's set up as output); | ||
109 | * returns zero/nonzero. | ||
110 | * | ||
111 | * Note that changes are synched to the GPIO clock, so reading values back | ||
112 | * right after you've set them may give old values. | ||
113 | */ | ||
114 | static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
115 | { | ||
116 | struct davinci_gpio_controller *d = chip2controller(chip); | ||
117 | struct davinci_gpio_regs __iomem *g = d->regs; | ||
118 | |||
119 | return (1 << offset) & __raw_readl(&g->in_data); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Assuming the pin is muxed as a gpio output, set its output value. | ||
124 | */ | ||
125 | static void | ||
126 | davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
127 | { | ||
128 | struct davinci_gpio_controller *d = chip2controller(chip); | ||
129 | struct davinci_gpio_regs __iomem *g = d->regs; | ||
130 | |||
131 | __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data); | ||
132 | } | ||
133 | |||
134 | static int __init davinci_gpio_setup(void) | ||
135 | { | ||
136 | int i, base; | ||
137 | unsigned ngpio; | ||
138 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
139 | struct davinci_gpio_regs *regs; | ||
140 | |||
141 | if (soc_info->gpio_type != GPIO_TYPE_DAVINCI) | ||
142 | return 0; | ||
143 | |||
144 | /* | ||
145 | * The gpio banks conceptually expose a segmented bitmap, | ||
146 | * and "ngpio" is one more than the largest zero-based | ||
147 | * bit index that's valid. | ||
148 | */ | ||
149 | ngpio = soc_info->gpio_num; | ||
150 | if (ngpio == 0) { | ||
151 | pr_err("GPIO setup: how many GPIOs?\n"); | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | if (WARN_ON(DAVINCI_N_GPIO < ngpio)) | ||
156 | ngpio = DAVINCI_N_GPIO; | ||
157 | |||
158 | gpio_base = ioremap(soc_info->gpio_base, SZ_4K); | ||
159 | if (WARN_ON(!gpio_base)) | ||
160 | return -ENOMEM; | ||
161 | |||
162 | for (i = 0, base = 0; base < ngpio; i++, base += 32) { | ||
163 | chips[i].chip.label = "DaVinci"; | ||
164 | |||
165 | chips[i].chip.direction_input = davinci_direction_in; | ||
166 | chips[i].chip.get = davinci_gpio_get; | ||
167 | chips[i].chip.direction_output = davinci_direction_out; | ||
168 | chips[i].chip.set = davinci_gpio_set; | ||
169 | |||
170 | chips[i].chip.base = base; | ||
171 | chips[i].chip.ngpio = ngpio - base; | ||
172 | if (chips[i].chip.ngpio > 32) | ||
173 | chips[i].chip.ngpio = 32; | ||
174 | |||
175 | spin_lock_init(&chips[i].lock); | ||
176 | |||
177 | regs = gpio2regs(base); | ||
178 | chips[i].regs = regs; | ||
179 | chips[i].set_data = ®s->set_data; | ||
180 | chips[i].clr_data = ®s->clr_data; | ||
181 | chips[i].in_data = ®s->in_data; | ||
182 | |||
183 | gpiochip_add(&chips[i].chip); | ||
184 | } | ||
185 | |||
186 | soc_info->gpio_ctlrs = chips; | ||
187 | soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); | ||
188 | |||
189 | davinci_gpio_irq_setup(); | ||
190 | return 0; | ||
191 | } | ||
192 | pure_initcall(davinci_gpio_setup); | ||
193 | |||
194 | /*--------------------------------------------------------------------------*/ | ||
195 | /* | ||
196 | * We expect irqs will normally be set up as input pins, but they can also be | ||
197 | * used as output pins ... which is convenient for testing. | ||
198 | * | ||
199 | * NOTE: The first few GPIOs also have direct INTC hookups in addition | ||
200 | * to their GPIOBNK0 irq, with a bit less overhead. | ||
201 | * | ||
202 | * All those INTC hookups (direct, plus several IRQ banks) can also | ||
203 | * serve as EDMA event triggers. | ||
204 | */ | ||
205 | |||
206 | static void gpio_irq_disable(struct irq_data *d) | ||
207 | { | ||
208 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); | ||
209 | u32 mask = (u32) irq_data_get_irq_handler_data(d); | ||
210 | |||
211 | __raw_writel(mask, &g->clr_falling); | ||
212 | __raw_writel(mask, &g->clr_rising); | ||
213 | } | ||
214 | |||
215 | static void gpio_irq_enable(struct irq_data *d) | ||
216 | { | ||
217 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); | ||
218 | u32 mask = (u32) irq_data_get_irq_handler_data(d); | ||
219 | unsigned status = irqd_get_trigger_type(d); | ||
220 | |||
221 | status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | ||
222 | if (!status) | ||
223 | status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | ||
224 | |||
225 | if (status & IRQ_TYPE_EDGE_FALLING) | ||
226 | __raw_writel(mask, &g->set_falling); | ||
227 | if (status & IRQ_TYPE_EDGE_RISING) | ||
228 | __raw_writel(mask, &g->set_rising); | ||
229 | } | ||
230 | |||
231 | static int gpio_irq_type(struct irq_data *d, unsigned trigger) | ||
232 | { | ||
233 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
234 | return -EINVAL; | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static struct irq_chip gpio_irqchip = { | ||
240 | .name = "GPIO", | ||
241 | .irq_enable = gpio_irq_enable, | ||
242 | .irq_disable = gpio_irq_disable, | ||
243 | .irq_set_type = gpio_irq_type, | ||
244 | .flags = IRQCHIP_SET_TYPE_MASKED, | ||
245 | }; | ||
246 | |||
247 | static void | ||
248 | gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
249 | { | ||
250 | struct davinci_gpio_regs __iomem *g; | ||
251 | u32 mask = 0xffff; | ||
252 | struct davinci_gpio_controller *d; | ||
253 | |||
254 | d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc); | ||
255 | g = (struct davinci_gpio_regs __iomem *)d->regs; | ||
256 | |||
257 | /* we only care about one bank */ | ||
258 | if (irq & 1) | ||
259 | mask <<= 16; | ||
260 | |||
261 | /* temporarily mask (level sensitive) parent IRQ */ | ||
262 | desc->irq_data.chip->irq_mask(&desc->irq_data); | ||
263 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
264 | while (1) { | ||
265 | u32 status; | ||
266 | int n; | ||
267 | int res; | ||
268 | |||
269 | /* ack any irqs */ | ||
270 | status = __raw_readl(&g->intstat) & mask; | ||
271 | if (!status) | ||
272 | break; | ||
273 | __raw_writel(status, &g->intstat); | ||
274 | |||
275 | /* now demux them to the right lowlevel handler */ | ||
276 | n = d->irq_base; | ||
277 | if (irq & 1) { | ||
278 | n += 16; | ||
279 | status >>= 16; | ||
280 | } | ||
281 | |||
282 | while (status) { | ||
283 | res = ffs(status); | ||
284 | n += res; | ||
285 | generic_handle_irq(n - 1); | ||
286 | status >>= res; | ||
287 | } | ||
288 | } | ||
289 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | ||
290 | /* now it may re-trigger */ | ||
291 | } | ||
292 | |||
293 | static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset) | ||
294 | { | ||
295 | struct davinci_gpio_controller *d = chip2controller(chip); | ||
296 | |||
297 | if (d->irq_base >= 0) | ||
298 | return d->irq_base + offset; | ||
299 | else | ||
300 | return -ENODEV; | ||
301 | } | ||
302 | |||
303 | static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset) | ||
304 | { | ||
305 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
306 | |||
307 | /* NOTE: we assume for now that only irqs in the first gpio_chip | ||
308 | * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs). | ||
309 | */ | ||
310 | if (offset < soc_info->gpio_unbanked) | ||
311 | return soc_info->gpio_irq + offset; | ||
312 | else | ||
313 | return -ENODEV; | ||
314 | } | ||
315 | |||
316 | static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger) | ||
317 | { | ||
318 | struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); | ||
319 | u32 mask = (u32) irq_data_get_irq_handler_data(d); | ||
320 | |||
321 | if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
322 | return -EINVAL; | ||
323 | |||
324 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) | ||
325 | ? &g->set_falling : &g->clr_falling); | ||
326 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | ||
327 | ? &g->set_rising : &g->clr_rising); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * NOTE: for suspend/resume, probably best to make a platform_device with | ||
334 | * suspend_late/resume_resume calls hooking into results of the set_wake() | ||
335 | * calls ... so if no gpios are wakeup events the clock can be disabled, | ||
336 | * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0 | ||
337 | * (dm6446) can be set appropriately for GPIOV33 pins. | ||
338 | */ | ||
339 | |||
340 | static int __init davinci_gpio_irq_setup(void) | ||
341 | { | ||
342 | unsigned gpio, irq, bank; | ||
343 | struct clk *clk; | ||
344 | u32 binten = 0; | ||
345 | unsigned ngpio, bank_irq; | ||
346 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
347 | struct davinci_gpio_regs __iomem *g; | ||
348 | |||
349 | ngpio = soc_info->gpio_num; | ||
350 | |||
351 | bank_irq = soc_info->gpio_irq; | ||
352 | if (bank_irq == 0) { | ||
353 | printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | |||
357 | clk = clk_get(NULL, "gpio"); | ||
358 | if (IS_ERR(clk)) { | ||
359 | printk(KERN_ERR "Error %ld getting gpio clock?\n", | ||
360 | PTR_ERR(clk)); | ||
361 | return PTR_ERR(clk); | ||
362 | } | ||
363 | clk_enable(clk); | ||
364 | |||
365 | /* Arrange gpio_to_irq() support, handling either direct IRQs or | ||
366 | * banked IRQs. Having GPIOs in the first GPIO bank use direct | ||
367 | * IRQs, while the others use banked IRQs, would need some setup | ||
368 | * tweaks to recognize hardware which can do that. | ||
369 | */ | ||
370 | for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) { | ||
371 | chips[bank].chip.to_irq = gpio_to_irq_banked; | ||
372 | chips[bank].irq_base = soc_info->gpio_unbanked | ||
373 | ? -EINVAL | ||
374 | : (soc_info->intc_irq_num + gpio); | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * AINTC can handle direct/unbanked IRQs for GPIOs, with the GPIO | ||
379 | * controller only handling trigger modes. We currently assume no | ||
380 | * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs. | ||
381 | */ | ||
382 | if (soc_info->gpio_unbanked) { | ||
383 | static struct irq_chip gpio_irqchip_unbanked; | ||
384 | |||
385 | /* pass "bank 0" GPIO IRQs to AINTC */ | ||
386 | chips[0].chip.to_irq = gpio_to_irq_unbanked; | ||
387 | binten = BIT(0); | ||
388 | |||
389 | /* AINTC handles mask/unmask; GPIO handles triggering */ | ||
390 | irq = bank_irq; | ||
391 | gpio_irqchip_unbanked = *irq_get_chip(irq); | ||
392 | gpio_irqchip_unbanked.name = "GPIO-AINTC"; | ||
393 | gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked; | ||
394 | |||
395 | /* default trigger: both edges */ | ||
396 | g = gpio2regs(0); | ||
397 | __raw_writel(~0, &g->set_falling); | ||
398 | __raw_writel(~0, &g->set_rising); | ||
399 | |||
400 | /* set the direct IRQs up to use that irqchip */ | ||
401 | for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) { | ||
402 | irq_set_chip(irq, &gpio_irqchip_unbanked); | ||
403 | irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); | ||
404 | irq_set_chip_data(irq, (__force void *)g); | ||
405 | irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH); | ||
406 | } | ||
407 | |||
408 | goto done; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we | ||
413 | * then chain through our own handler. | ||
414 | */ | ||
415 | for (gpio = 0, irq = gpio_to_irq(0), bank = 0; | ||
416 | gpio < ngpio; | ||
417 | bank++, bank_irq++) { | ||
418 | unsigned i; | ||
419 | |||
420 | /* disabled by default, enabled only as needed */ | ||
421 | g = gpio2regs(gpio); | ||
422 | __raw_writel(~0, &g->clr_falling); | ||
423 | __raw_writel(~0, &g->clr_rising); | ||
424 | |||
425 | /* set up all irqs in this bank */ | ||
426 | irq_set_chained_handler(bank_irq, gpio_irq_handler); | ||
427 | |||
428 | /* | ||
429 | * Each chip handles 32 gpios, and each irq bank consists of 16 | ||
430 | * gpio irqs. Pass the irq bank's corresponding controller to | ||
431 | * the chained irq handler. | ||
432 | */ | ||
433 | irq_set_handler_data(bank_irq, &chips[gpio / 32]); | ||
434 | |||
435 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { | ||
436 | irq_set_chip(irq, &gpio_irqchip); | ||
437 | irq_set_chip_data(irq, (__force void *)g); | ||
438 | irq_set_handler_data(irq, (void *)__gpio_mask(gpio)); | ||
439 | irq_set_handler(irq, handle_simple_irq); | ||
440 | set_irq_flags(irq, IRQF_VALID); | ||
441 | } | ||
442 | |||
443 | binten |= BIT(bank); | ||
444 | } | ||
445 | |||
446 | done: | ||
447 | /* BINTEN -- per-bank interrupt enable. genirq would also let these | ||
448 | * bits be set/cleared dynamically. | ||
449 | */ | ||
450 | __raw_writel(binten, gpio_base + 0x08); | ||
451 | |||
452 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 72fb9c665320..1c0fc3756cb1 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/module.h> | ||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
20 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
@@ -23,6 +24,9 @@ | |||
23 | #include <linux/basic_mmio_gpio.h> | 24 | #include <linux/basic_mmio_gpio.h> |
24 | 25 | ||
25 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <mach/gpio-ep93xx.h> | ||
28 | |||
29 | #define irq_to_gpio(irq) ((irq) - gpio_to_irq(0)) | ||
26 | 30 | ||
27 | struct ep93xx_gpio { | 31 | struct ep93xx_gpio { |
28 | void __iomem *mmio_base; | 32 | void __iomem *mmio_base; |
@@ -307,6 +311,21 @@ static int ep93xx_gpio_set_debounce(struct gpio_chip *chip, | |||
307 | return 0; | 311 | return 0; |
308 | } | 312 | } |
309 | 313 | ||
314 | /* | ||
315 | * Map GPIO A0..A7 (0..7) to irq 64..71, | ||
316 | * B0..B7 (7..15) to irq 72..79, and | ||
317 | * F0..F7 (16..24) to irq 80..87. | ||
318 | */ | ||
319 | static int ep93xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
320 | { | ||
321 | int gpio = chip->base + offset; | ||
322 | |||
323 | if (gpio > EP93XX_GPIO_LINE_MAX_IRQ) | ||
324 | return -EINVAL; | ||
325 | |||
326 | return 64 + gpio; | ||
327 | } | ||
328 | |||
310 | static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, | 329 | static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, |
311 | void __iomem *mmio_base, struct ep93xx_gpio_bank *bank) | 330 | void __iomem *mmio_base, struct ep93xx_gpio_bank *bank) |
312 | { | 331 | { |
@@ -321,8 +340,10 @@ static int ep93xx_gpio_add_bank(struct bgpio_chip *bgc, struct device *dev, | |||
321 | bgc->gc.label = bank->label; | 340 | bgc->gc.label = bank->label; |
322 | bgc->gc.base = bank->base; | 341 | bgc->gc.base = bank->base; |
323 | 342 | ||
324 | if (bank->has_debounce) | 343 | if (bank->has_debounce) { |
325 | bgc->gc.set_debounce = ep93xx_gpio_set_debounce; | 344 | bgc->gc.set_debounce = ep93xx_gpio_set_debounce; |
345 | bgc->gc.to_irq = ep93xx_gpio_to_irq; | ||
346 | } | ||
326 | 347 | ||
327 | return gpiochip_add(&bgc->gc); | 348 | return gpiochip_add(&bgc->gc); |
328 | } | 349 | } |
diff --git a/drivers/gpio/gpio-exynos4.c b/drivers/gpio/gpio-exynos4.c deleted file mode 100644 index d24b337cf1ac..000000000000 --- a/drivers/gpio/gpio-exynos4.c +++ /dev/null | |||
@@ -1,385 +0,0 @@ | |||
1 | /* | ||
2 | * EXYNOS4 - GPIOlib support | ||
3 | * | ||
4 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/gpio.h> | ||
16 | |||
17 | #include <mach/map.h> | ||
18 | |||
19 | #include <plat/gpio-core.h> | ||
20 | #include <plat/gpio-cfg.h> | ||
21 | #include <plat/gpio-cfg-helpers.h> | ||
22 | |||
23 | int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip, | ||
24 | unsigned int off, s3c_gpio_pull_t pull) | ||
25 | { | ||
26 | if (pull == S3C_GPIO_PULL_UP) | ||
27 | pull = 3; | ||
28 | |||
29 | return s3c_gpio_setpull_updown(chip, off, pull); | ||
30 | } | ||
31 | |||
32 | s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip, | ||
33 | unsigned int off) | ||
34 | { | ||
35 | s3c_gpio_pull_t pull; | ||
36 | |||
37 | pull = s3c_gpio_getpull_updown(chip, off); | ||
38 | if (pull == 3) | ||
39 | pull = S3C_GPIO_PULL_UP; | ||
40 | |||
41 | return pull; | ||
42 | } | ||
43 | |||
44 | static struct s3c_gpio_cfg gpio_cfg = { | ||
45 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
46 | .set_pull = s3c_gpio_setpull_exynos4, | ||
47 | .get_pull = s3c_gpio_getpull_exynos4, | ||
48 | }; | ||
49 | |||
50 | static struct s3c_gpio_cfg gpio_cfg_noint = { | ||
51 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
52 | .set_pull = s3c_gpio_setpull_exynos4, | ||
53 | .get_pull = s3c_gpio_getpull_exynos4, | ||
54 | }; | ||
55 | |||
56 | /* | ||
57 | * Following are the gpio banks in v310. | ||
58 | * | ||
59 | * The 'config' member when left to NULL, is initialized to the default | ||
60 | * structure gpio_cfg in the init function below. | ||
61 | * | ||
62 | * The 'base' member is also initialized in the init function below. | ||
63 | * Note: The initialization of 'base' member of s3c_gpio_chip structure | ||
64 | * uses the above macro and depends on the banks being listed in order here. | ||
65 | */ | ||
66 | static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = { | ||
67 | { | ||
68 | .chip = { | ||
69 | .base = EXYNOS4_GPA0(0), | ||
70 | .ngpio = EXYNOS4_GPIO_A0_NR, | ||
71 | .label = "GPA0", | ||
72 | }, | ||
73 | }, { | ||
74 | .chip = { | ||
75 | .base = EXYNOS4_GPA1(0), | ||
76 | .ngpio = EXYNOS4_GPIO_A1_NR, | ||
77 | .label = "GPA1", | ||
78 | }, | ||
79 | }, { | ||
80 | .chip = { | ||
81 | .base = EXYNOS4_GPB(0), | ||
82 | .ngpio = EXYNOS4_GPIO_B_NR, | ||
83 | .label = "GPB", | ||
84 | }, | ||
85 | }, { | ||
86 | .chip = { | ||
87 | .base = EXYNOS4_GPC0(0), | ||
88 | .ngpio = EXYNOS4_GPIO_C0_NR, | ||
89 | .label = "GPC0", | ||
90 | }, | ||
91 | }, { | ||
92 | .chip = { | ||
93 | .base = EXYNOS4_GPC1(0), | ||
94 | .ngpio = EXYNOS4_GPIO_C1_NR, | ||
95 | .label = "GPC1", | ||
96 | }, | ||
97 | }, { | ||
98 | .chip = { | ||
99 | .base = EXYNOS4_GPD0(0), | ||
100 | .ngpio = EXYNOS4_GPIO_D0_NR, | ||
101 | .label = "GPD0", | ||
102 | }, | ||
103 | }, { | ||
104 | .chip = { | ||
105 | .base = EXYNOS4_GPD1(0), | ||
106 | .ngpio = EXYNOS4_GPIO_D1_NR, | ||
107 | .label = "GPD1", | ||
108 | }, | ||
109 | }, { | ||
110 | .chip = { | ||
111 | .base = EXYNOS4_GPE0(0), | ||
112 | .ngpio = EXYNOS4_GPIO_E0_NR, | ||
113 | .label = "GPE0", | ||
114 | }, | ||
115 | }, { | ||
116 | .chip = { | ||
117 | .base = EXYNOS4_GPE1(0), | ||
118 | .ngpio = EXYNOS4_GPIO_E1_NR, | ||
119 | .label = "GPE1", | ||
120 | }, | ||
121 | }, { | ||
122 | .chip = { | ||
123 | .base = EXYNOS4_GPE2(0), | ||
124 | .ngpio = EXYNOS4_GPIO_E2_NR, | ||
125 | .label = "GPE2", | ||
126 | }, | ||
127 | }, { | ||
128 | .chip = { | ||
129 | .base = EXYNOS4_GPE3(0), | ||
130 | .ngpio = EXYNOS4_GPIO_E3_NR, | ||
131 | .label = "GPE3", | ||
132 | }, | ||
133 | }, { | ||
134 | .chip = { | ||
135 | .base = EXYNOS4_GPE4(0), | ||
136 | .ngpio = EXYNOS4_GPIO_E4_NR, | ||
137 | .label = "GPE4", | ||
138 | }, | ||
139 | }, { | ||
140 | .chip = { | ||
141 | .base = EXYNOS4_GPF0(0), | ||
142 | .ngpio = EXYNOS4_GPIO_F0_NR, | ||
143 | .label = "GPF0", | ||
144 | }, | ||
145 | }, { | ||
146 | .chip = { | ||
147 | .base = EXYNOS4_GPF1(0), | ||
148 | .ngpio = EXYNOS4_GPIO_F1_NR, | ||
149 | .label = "GPF1", | ||
150 | }, | ||
151 | }, { | ||
152 | .chip = { | ||
153 | .base = EXYNOS4_GPF2(0), | ||
154 | .ngpio = EXYNOS4_GPIO_F2_NR, | ||
155 | .label = "GPF2", | ||
156 | }, | ||
157 | }, { | ||
158 | .chip = { | ||
159 | .base = EXYNOS4_GPF3(0), | ||
160 | .ngpio = EXYNOS4_GPIO_F3_NR, | ||
161 | .label = "GPF3", | ||
162 | }, | ||
163 | }, | ||
164 | }; | ||
165 | |||
166 | static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = { | ||
167 | { | ||
168 | .chip = { | ||
169 | .base = EXYNOS4_GPJ0(0), | ||
170 | .ngpio = EXYNOS4_GPIO_J0_NR, | ||
171 | .label = "GPJ0", | ||
172 | }, | ||
173 | }, { | ||
174 | .chip = { | ||
175 | .base = EXYNOS4_GPJ1(0), | ||
176 | .ngpio = EXYNOS4_GPIO_J1_NR, | ||
177 | .label = "GPJ1", | ||
178 | }, | ||
179 | }, { | ||
180 | .chip = { | ||
181 | .base = EXYNOS4_GPK0(0), | ||
182 | .ngpio = EXYNOS4_GPIO_K0_NR, | ||
183 | .label = "GPK0", | ||
184 | }, | ||
185 | }, { | ||
186 | .chip = { | ||
187 | .base = EXYNOS4_GPK1(0), | ||
188 | .ngpio = EXYNOS4_GPIO_K1_NR, | ||
189 | .label = "GPK1", | ||
190 | }, | ||
191 | }, { | ||
192 | .chip = { | ||
193 | .base = EXYNOS4_GPK2(0), | ||
194 | .ngpio = EXYNOS4_GPIO_K2_NR, | ||
195 | .label = "GPK2", | ||
196 | }, | ||
197 | }, { | ||
198 | .chip = { | ||
199 | .base = EXYNOS4_GPK3(0), | ||
200 | .ngpio = EXYNOS4_GPIO_K3_NR, | ||
201 | .label = "GPK3", | ||
202 | }, | ||
203 | }, { | ||
204 | .chip = { | ||
205 | .base = EXYNOS4_GPL0(0), | ||
206 | .ngpio = EXYNOS4_GPIO_L0_NR, | ||
207 | .label = "GPL0", | ||
208 | }, | ||
209 | }, { | ||
210 | .chip = { | ||
211 | .base = EXYNOS4_GPL1(0), | ||
212 | .ngpio = EXYNOS4_GPIO_L1_NR, | ||
213 | .label = "GPL1", | ||
214 | }, | ||
215 | }, { | ||
216 | .chip = { | ||
217 | .base = EXYNOS4_GPL2(0), | ||
218 | .ngpio = EXYNOS4_GPIO_L2_NR, | ||
219 | .label = "GPL2", | ||
220 | }, | ||
221 | }, { | ||
222 | .config = &gpio_cfg_noint, | ||
223 | .chip = { | ||
224 | .base = EXYNOS4_GPY0(0), | ||
225 | .ngpio = EXYNOS4_GPIO_Y0_NR, | ||
226 | .label = "GPY0", | ||
227 | }, | ||
228 | }, { | ||
229 | .config = &gpio_cfg_noint, | ||
230 | .chip = { | ||
231 | .base = EXYNOS4_GPY1(0), | ||
232 | .ngpio = EXYNOS4_GPIO_Y1_NR, | ||
233 | .label = "GPY1", | ||
234 | }, | ||
235 | }, { | ||
236 | .config = &gpio_cfg_noint, | ||
237 | .chip = { | ||
238 | .base = EXYNOS4_GPY2(0), | ||
239 | .ngpio = EXYNOS4_GPIO_Y2_NR, | ||
240 | .label = "GPY2", | ||
241 | }, | ||
242 | }, { | ||
243 | .config = &gpio_cfg_noint, | ||
244 | .chip = { | ||
245 | .base = EXYNOS4_GPY3(0), | ||
246 | .ngpio = EXYNOS4_GPIO_Y3_NR, | ||
247 | .label = "GPY3", | ||
248 | }, | ||
249 | }, { | ||
250 | .config = &gpio_cfg_noint, | ||
251 | .chip = { | ||
252 | .base = EXYNOS4_GPY4(0), | ||
253 | .ngpio = EXYNOS4_GPIO_Y4_NR, | ||
254 | .label = "GPY4", | ||
255 | }, | ||
256 | }, { | ||
257 | .config = &gpio_cfg_noint, | ||
258 | .chip = { | ||
259 | .base = EXYNOS4_GPY5(0), | ||
260 | .ngpio = EXYNOS4_GPIO_Y5_NR, | ||
261 | .label = "GPY5", | ||
262 | }, | ||
263 | }, { | ||
264 | .config = &gpio_cfg_noint, | ||
265 | .chip = { | ||
266 | .base = EXYNOS4_GPY6(0), | ||
267 | .ngpio = EXYNOS4_GPIO_Y6_NR, | ||
268 | .label = "GPY6", | ||
269 | }, | ||
270 | }, { | ||
271 | .base = (S5P_VA_GPIO2 + 0xC00), | ||
272 | .config = &gpio_cfg_noint, | ||
273 | .irq_base = IRQ_EINT(0), | ||
274 | .chip = { | ||
275 | .base = EXYNOS4_GPX0(0), | ||
276 | .ngpio = EXYNOS4_GPIO_X0_NR, | ||
277 | .label = "GPX0", | ||
278 | .to_irq = samsung_gpiolib_to_irq, | ||
279 | }, | ||
280 | }, { | ||
281 | .base = (S5P_VA_GPIO2 + 0xC20), | ||
282 | .config = &gpio_cfg_noint, | ||
283 | .irq_base = IRQ_EINT(8), | ||
284 | .chip = { | ||
285 | .base = EXYNOS4_GPX1(0), | ||
286 | .ngpio = EXYNOS4_GPIO_X1_NR, | ||
287 | .label = "GPX1", | ||
288 | .to_irq = samsung_gpiolib_to_irq, | ||
289 | }, | ||
290 | }, { | ||
291 | .base = (S5P_VA_GPIO2 + 0xC40), | ||
292 | .config = &gpio_cfg_noint, | ||
293 | .irq_base = IRQ_EINT(16), | ||
294 | .chip = { | ||
295 | .base = EXYNOS4_GPX2(0), | ||
296 | .ngpio = EXYNOS4_GPIO_X2_NR, | ||
297 | .label = "GPX2", | ||
298 | .to_irq = samsung_gpiolib_to_irq, | ||
299 | }, | ||
300 | }, { | ||
301 | .base = (S5P_VA_GPIO2 + 0xC60), | ||
302 | .config = &gpio_cfg_noint, | ||
303 | .irq_base = IRQ_EINT(24), | ||
304 | .chip = { | ||
305 | .base = EXYNOS4_GPX3(0), | ||
306 | .ngpio = EXYNOS4_GPIO_X3_NR, | ||
307 | .label = "GPX3", | ||
308 | .to_irq = samsung_gpiolib_to_irq, | ||
309 | }, | ||
310 | }, | ||
311 | }; | ||
312 | |||
313 | static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = { | ||
314 | { | ||
315 | .chip = { | ||
316 | .base = EXYNOS4_GPZ(0), | ||
317 | .ngpio = EXYNOS4_GPIO_Z_NR, | ||
318 | .label = "GPZ", | ||
319 | }, | ||
320 | }, | ||
321 | }; | ||
322 | |||
323 | static __init int exynos4_gpiolib_init(void) | ||
324 | { | ||
325 | struct s3c_gpio_chip *chip; | ||
326 | int i; | ||
327 | int group = 0; | ||
328 | int nr_chips; | ||
329 | |||
330 | /* GPIO part 1 */ | ||
331 | |||
332 | chip = exynos4_gpio_part1_4bit; | ||
333 | nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit); | ||
334 | |||
335 | for (i = 0; i < nr_chips; i++, chip++) { | ||
336 | if (chip->config == NULL) { | ||
337 | chip->config = &gpio_cfg; | ||
338 | /* Assign the GPIO interrupt group */ | ||
339 | chip->group = group++; | ||
340 | } | ||
341 | if (chip->base == NULL) | ||
342 | chip->base = S5P_VA_GPIO1 + (i) * 0x20; | ||
343 | } | ||
344 | |||
345 | samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips); | ||
346 | |||
347 | /* GPIO part 2 */ | ||
348 | |||
349 | chip = exynos4_gpio_part2_4bit; | ||
350 | nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit); | ||
351 | |||
352 | for (i = 0; i < nr_chips; i++, chip++) { | ||
353 | if (chip->config == NULL) { | ||
354 | chip->config = &gpio_cfg; | ||
355 | /* Assign the GPIO interrupt group */ | ||
356 | chip->group = group++; | ||
357 | } | ||
358 | if (chip->base == NULL) | ||
359 | chip->base = S5P_VA_GPIO2 + (i) * 0x20; | ||
360 | } | ||
361 | |||
362 | samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips); | ||
363 | |||
364 | /* GPIO part 3 */ | ||
365 | |||
366 | chip = exynos4_gpio_part3_4bit; | ||
367 | nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit); | ||
368 | |||
369 | for (i = 0; i < nr_chips; i++, chip++) { | ||
370 | if (chip->config == NULL) { | ||
371 | chip->config = &gpio_cfg; | ||
372 | /* Assign the GPIO interrupt group */ | ||
373 | chip->group = group++; | ||
374 | } | ||
375 | if (chip->base == NULL) | ||
376 | chip->base = S5P_VA_GPIO3 + (i) * 0x20; | ||
377 | } | ||
378 | |||
379 | samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips); | ||
380 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); | ||
381 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | core_initcall(exynos4_gpiolib_init); | ||
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 231714def4d2..4e24436b0f82 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c | |||
@@ -351,7 +351,7 @@ static int bgpio_setup_direction(struct bgpio_chip *bgc, | |||
351 | return 0; | 351 | return 0; |
352 | } | 352 | } |
353 | 353 | ||
354 | int __devexit bgpio_remove(struct bgpio_chip *bgc) | 354 | int bgpio_remove(struct bgpio_chip *bgc) |
355 | { | 355 | { |
356 | int err = gpiochip_remove(&bgc->gc); | 356 | int err = gpiochip_remove(&bgc->gc); |
357 | 357 | ||
@@ -361,15 +361,10 @@ int __devexit bgpio_remove(struct bgpio_chip *bgc) | |||
361 | } | 361 | } |
362 | EXPORT_SYMBOL_GPL(bgpio_remove); | 362 | EXPORT_SYMBOL_GPL(bgpio_remove); |
363 | 363 | ||
364 | int __devinit bgpio_init(struct bgpio_chip *bgc, | 364 | int bgpio_init(struct bgpio_chip *bgc, struct device *dev, |
365 | struct device *dev, | 365 | unsigned long sz, void __iomem *dat, void __iomem *set, |
366 | unsigned long sz, | 366 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, |
367 | void __iomem *dat, | 367 | bool big_endian) |
368 | void __iomem *set, | ||
369 | void __iomem *clr, | ||
370 | void __iomem *dirout, | ||
371 | void __iomem *dirin, | ||
372 | bool big_endian) | ||
373 | { | 368 | { |
374 | int ret; | 369 | int ret; |
375 | 370 | ||
diff --git a/drivers/gpio/gpio-ks8695.c b/drivers/gpio/gpio-ks8695.c new file mode 100644 index 000000000000..a3ac66ea364b --- /dev/null +++ b/drivers/gpio/gpio-ks8695.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ks8695/gpio.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Andrew Victor | ||
5 | * Updated to GPIOLIB, Copyright 2008 Simtec Electronics | ||
6 | * Daniel Silverstone <dsilvers@simtec.co.uk> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/debugfs.h> | ||
26 | #include <linux/seq_file.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/io.h> | ||
29 | |||
30 | #include <mach/hardware.h> | ||
31 | #include <asm/mach/irq.h> | ||
32 | |||
33 | #include <mach/regs-gpio.h> | ||
34 | #include <mach/gpio-ks8695.h> | ||
35 | |||
36 | /* | ||
37 | * Configure a GPIO line for either GPIO function, or its internal | ||
38 | * function (Interrupt, Timer, etc). | ||
39 | */ | ||
40 | static void ks8695_gpio_mode(unsigned int pin, short gpio) | ||
41 | { | ||
42 | unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN }; | ||
43 | unsigned long x, flags; | ||
44 | |||
45 | if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */ | ||
46 | return; | ||
47 | |||
48 | local_irq_save(flags); | ||
49 | |||
50 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); | ||
51 | if (gpio) /* GPIO: set bit to 0 */ | ||
52 | x &= ~enable[pin]; | ||
53 | else /* Internal function: set bit to 1 */ | ||
54 | x |= enable[pin]; | ||
55 | __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC); | ||
56 | |||
57 | local_irq_restore(flags); | ||
58 | } | ||
59 | |||
60 | |||
61 | static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 }; | ||
62 | |||
63 | /* | ||
64 | * Configure GPIO pin as external interrupt source. | ||
65 | */ | ||
66 | int ks8695_gpio_interrupt(unsigned int pin, unsigned int type) | ||
67 | { | ||
68 | unsigned long x, flags; | ||
69 | |||
70 | if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */ | ||
71 | return -EINVAL; | ||
72 | |||
73 | local_irq_save(flags); | ||
74 | |||
75 | /* set pin as input */ | ||
76 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); | ||
77 | x &= ~IOPM(pin); | ||
78 | __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); | ||
79 | |||
80 | local_irq_restore(flags); | ||
81 | |||
82 | /* Set IRQ triggering type */ | ||
83 | irq_set_irq_type(gpio_irq[pin], type); | ||
84 | |||
85 | /* enable interrupt mode */ | ||
86 | ks8695_gpio_mode(pin, 0); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | EXPORT_SYMBOL(ks8695_gpio_interrupt); | ||
91 | |||
92 | |||
93 | |||
94 | /* .... Generic GPIO interface .............................................. */ | ||
95 | |||
96 | /* | ||
97 | * Configure the GPIO line as an input. | ||
98 | */ | ||
99 | static int ks8695_gpio_direction_input(struct gpio_chip *gc, unsigned int pin) | ||
100 | { | ||
101 | unsigned long x, flags; | ||
102 | |||
103 | if (pin > KS8695_GPIO_15) | ||
104 | return -EINVAL; | ||
105 | |||
106 | /* set pin to GPIO mode */ | ||
107 | ks8695_gpio_mode(pin, 1); | ||
108 | |||
109 | local_irq_save(flags); | ||
110 | |||
111 | /* set pin as input */ | ||
112 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); | ||
113 | x &= ~IOPM(pin); | ||
114 | __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); | ||
115 | |||
116 | local_irq_restore(flags); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | |||
122 | /* | ||
123 | * Configure the GPIO line as an output, with default state. | ||
124 | */ | ||
125 | static int ks8695_gpio_direction_output(struct gpio_chip *gc, | ||
126 | unsigned int pin, int state) | ||
127 | { | ||
128 | unsigned long x, flags; | ||
129 | |||
130 | if (pin > KS8695_GPIO_15) | ||
131 | return -EINVAL; | ||
132 | |||
133 | /* set pin to GPIO mode */ | ||
134 | ks8695_gpio_mode(pin, 1); | ||
135 | |||
136 | local_irq_save(flags); | ||
137 | |||
138 | /* set line state */ | ||
139 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); | ||
140 | if (state) | ||
141 | x |= IOPD(pin); | ||
142 | else | ||
143 | x &= ~IOPD(pin); | ||
144 | __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); | ||
145 | |||
146 | /* set pin as output */ | ||
147 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); | ||
148 | x |= IOPM(pin); | ||
149 | __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM); | ||
150 | |||
151 | local_irq_restore(flags); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | |||
157 | /* | ||
158 | * Set the state of an output GPIO line. | ||
159 | */ | ||
160 | static void ks8695_gpio_set_value(struct gpio_chip *gc, | ||
161 | unsigned int pin, int state) | ||
162 | { | ||
163 | unsigned long x, flags; | ||
164 | |||
165 | if (pin > KS8695_GPIO_15) | ||
166 | return; | ||
167 | |||
168 | local_irq_save(flags); | ||
169 | |||
170 | /* set output line state */ | ||
171 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); | ||
172 | if (state) | ||
173 | x |= IOPD(pin); | ||
174 | else | ||
175 | x &= ~IOPD(pin); | ||
176 | __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD); | ||
177 | |||
178 | local_irq_restore(flags); | ||
179 | } | ||
180 | |||
181 | |||
182 | /* | ||
183 | * Read the state of a GPIO line. | ||
184 | */ | ||
185 | static int ks8695_gpio_get_value(struct gpio_chip *gc, unsigned int pin) | ||
186 | { | ||
187 | unsigned long x; | ||
188 | |||
189 | if (pin > KS8695_GPIO_15) | ||
190 | return -EINVAL; | ||
191 | |||
192 | x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); | ||
193 | return (x & IOPD(pin)) != 0; | ||
194 | } | ||
195 | |||
196 | |||
197 | /* | ||
198 | * Map GPIO line to IRQ number. | ||
199 | */ | ||
200 | static int ks8695_gpio_to_irq(struct gpio_chip *gc, unsigned int pin) | ||
201 | { | ||
202 | if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */ | ||
203 | return -EINVAL; | ||
204 | |||
205 | return gpio_irq[pin]; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Map IRQ number to GPIO line. | ||
210 | */ | ||
211 | int irq_to_gpio(unsigned int irq) | ||
212 | { | ||
213 | if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3)) | ||
214 | return -EINVAL; | ||
215 | |||
216 | return (irq - KS8695_IRQ_EXTERN0); | ||
217 | } | ||
218 | EXPORT_SYMBOL(irq_to_gpio); | ||
219 | |||
220 | /* GPIOLIB interface */ | ||
221 | |||
222 | static struct gpio_chip ks8695_gpio_chip = { | ||
223 | .label = "KS8695", | ||
224 | .direction_input = ks8695_gpio_direction_input, | ||
225 | .direction_output = ks8695_gpio_direction_output, | ||
226 | .get = ks8695_gpio_get_value, | ||
227 | .set = ks8695_gpio_set_value, | ||
228 | .to_irq = ks8695_gpio_to_irq, | ||
229 | .base = 0, | ||
230 | .ngpio = 16, | ||
231 | .can_sleep = 0, | ||
232 | }; | ||
233 | |||
234 | /* Register the GPIOs */ | ||
235 | void ks8695_register_gpios(void) | ||
236 | { | ||
237 | if (gpiochip_add(&ks8695_gpio_chip)) | ||
238 | printk(KERN_ERR "Unable to register core GPIOs\n"); | ||
239 | } | ||
240 | |||
241 | /* .... Debug interface ..................................................... */ | ||
242 | |||
243 | #ifdef CONFIG_DEBUG_FS | ||
244 | |||
245 | static int ks8695_gpio_show(struct seq_file *s, void *unused) | ||
246 | { | ||
247 | unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN }; | ||
248 | unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM }; | ||
249 | unsigned long mode, ctrl, data; | ||
250 | int i; | ||
251 | |||
252 | mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM); | ||
253 | ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC); | ||
254 | data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD); | ||
255 | |||
256 | seq_printf(s, "Pin\tI/O\tFunction\tState\n\n"); | ||
257 | |||
258 | for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) { | ||
259 | seq_printf(s, "%i:\t", i); | ||
260 | |||
261 | seq_printf(s, "%s\t", (mode & IOPM(i)) ? "Output" : "Input"); | ||
262 | |||
263 | if (i <= KS8695_GPIO_3) { | ||
264 | if (ctrl & enable[i]) { | ||
265 | seq_printf(s, "EXT%i ", i); | ||
266 | |||
267 | switch ((ctrl & intmask[i]) >> (4 * i)) { | ||
268 | case IOPC_TM_LOW: | ||
269 | seq_printf(s, "(Low)"); break; | ||
270 | case IOPC_TM_HIGH: | ||
271 | seq_printf(s, "(High)"); break; | ||
272 | case IOPC_TM_RISING: | ||
273 | seq_printf(s, "(Rising)"); break; | ||
274 | case IOPC_TM_FALLING: | ||
275 | seq_printf(s, "(Falling)"); break; | ||
276 | case IOPC_TM_EDGE: | ||
277 | seq_printf(s, "(Edges)"); break; | ||
278 | } | ||
279 | } | ||
280 | else | ||
281 | seq_printf(s, "GPIO\t"); | ||
282 | } | ||
283 | else if (i <= KS8695_GPIO_5) { | ||
284 | if (ctrl & enable[i]) | ||
285 | seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4); | ||
286 | else | ||
287 | seq_printf(s, "GPIO\t"); | ||
288 | } | ||
289 | else | ||
290 | seq_printf(s, "GPIO\t"); | ||
291 | |||
292 | seq_printf(s, "\t"); | ||
293 | |||
294 | seq_printf(s, "%i\n", (data & IOPD(i)) ? 1 : 0); | ||
295 | } | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int ks8695_gpio_open(struct inode *inode, struct file *file) | ||
300 | { | ||
301 | return single_open(file, ks8695_gpio_show, NULL); | ||
302 | } | ||
303 | |||
304 | static const struct file_operations ks8695_gpio_operations = { | ||
305 | .open = ks8695_gpio_open, | ||
306 | .read = seq_read, | ||
307 | .llseek = seq_lseek, | ||
308 | .release = single_release, | ||
309 | }; | ||
310 | |||
311 | static int __init ks8695_gpio_debugfs_init(void) | ||
312 | { | ||
313 | /* /sys/kernel/debug/ks8695_gpio */ | ||
314 | (void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL, &ks8695_gpio_operations); | ||
315 | return 0; | ||
316 | } | ||
317 | postcore_initcall(ks8695_gpio_debugfs_init); | ||
318 | |||
319 | #endif | ||
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index d2eb57c60e0e..00692e89ef87 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c | |||
@@ -59,6 +59,7 @@ enum GPIO_REG { | |||
59 | GRER, /* rising edge detect */ | 59 | GRER, /* rising edge detect */ |
60 | GFER, /* falling edge detect */ | 60 | GFER, /* falling edge detect */ |
61 | GEDR, /* edge detect result */ | 61 | GEDR, /* edge detect result */ |
62 | GAFR, /* alt function */ | ||
62 | }; | 63 | }; |
63 | 64 | ||
64 | struct lnw_gpio { | 65 | struct lnw_gpio { |
@@ -81,6 +82,31 @@ static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, | |||
81 | return ptr; | 82 | return ptr; |
82 | } | 83 | } |
83 | 84 | ||
85 | static void __iomem *gpio_reg_2bit(struct gpio_chip *chip, unsigned offset, | ||
86 | enum GPIO_REG reg_type) | ||
87 | { | ||
88 | struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip); | ||
89 | unsigned nreg = chip->ngpio / 32; | ||
90 | u8 reg = offset / 16; | ||
91 | void __iomem *ptr; | ||
92 | |||
93 | ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4); | ||
94 | return ptr; | ||
95 | } | ||
96 | |||
97 | static int lnw_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
98 | { | ||
99 | void __iomem *gafr = gpio_reg_2bit(chip, offset, GAFR); | ||
100 | u32 value = readl(gafr); | ||
101 | int shift = (offset % 16) << 1, af = (value >> shift) & 3; | ||
102 | |||
103 | if (af) { | ||
104 | value &= ~(3 << shift); | ||
105 | writel(value, gafr); | ||
106 | } | ||
107 | return 0; | ||
108 | } | ||
109 | |||
84 | static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) | 110 | static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset) |
85 | { | 111 | { |
86 | void __iomem *gplr = gpio_reg(chip, offset, GPLR); | 112 | void __iomem *gplr = gpio_reg(chip, offset, GPLR); |
@@ -321,6 +347,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
321 | lnw->reg_base = base; | 347 | lnw->reg_base = base; |
322 | lnw->irq_base = irq_base; | 348 | lnw->irq_base = irq_base; |
323 | lnw->chip.label = dev_name(&pdev->dev); | 349 | lnw->chip.label = dev_name(&pdev->dev); |
350 | lnw->chip.request = lnw_gpio_request; | ||
324 | lnw->chip.direction_input = lnw_gpio_direction_input; | 351 | lnw->chip.direction_input = lnw_gpio_direction_input; |
325 | lnw->chip.direction_output = lnw_gpio_direction_output; | 352 | lnw->chip.direction_output = lnw_gpio_direction_output; |
326 | lnw->chip.get = lnw_gpio_get; | 353 | lnw->chip.get = lnw_gpio_get; |
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c new file mode 100644 index 000000000000..5b6948081f8f --- /dev/null +++ b/drivers/gpio/gpio-lpc32xx.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-lpc32xx/gpiolib.c | ||
3 | * | ||
4 | * Author: Kevin Wells <kevin.wells@nxp.com> | ||
5 | * | ||
6 | * Copyright (C) 2010 NXP Semiconductors | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/gpio.h> | ||
24 | |||
25 | #include <mach/hardware.h> | ||
26 | #include <mach/platform.h> | ||
27 | #include <mach/gpio-lpc32xx.h> | ||
28 | |||
29 | #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000) | ||
30 | #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004) | ||
31 | #define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008) | ||
32 | #define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C) | ||
33 | #define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010) | ||
34 | #define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014) | ||
35 | #define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018) | ||
36 | #define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C) | ||
37 | #define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020) | ||
38 | #define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024) | ||
39 | #define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028) | ||
40 | #define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C) | ||
41 | #define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030) | ||
42 | #define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040) | ||
43 | #define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044) | ||
44 | #define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048) | ||
45 | #define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C) | ||
46 | #define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050) | ||
47 | #define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054) | ||
48 | #define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058) | ||
49 | #define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060) | ||
50 | #define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064) | ||
51 | #define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068) | ||
52 | #define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C) | ||
53 | #define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070) | ||
54 | #define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074) | ||
55 | #define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078) | ||
56 | |||
57 | #define GPIO012_PIN_TO_BIT(x) (1 << (x)) | ||
58 | #define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25)) | ||
59 | #define GPO3_PIN_TO_BIT(x) (1 << (x)) | ||
60 | #define GPIO012_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) | ||
61 | #define GPIO3_PIN_IN_SHIFT(x) ((x) == 5 ? 24 : 10 + (x)) | ||
62 | #define GPIO3_PIN_IN_SEL(x, y) ((x) >> GPIO3_PIN_IN_SHIFT(y)) | ||
63 | #define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1) | ||
64 | #define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) | ||
65 | |||
66 | struct gpio_regs { | ||
67 | void __iomem *inp_state; | ||
68 | void __iomem *outp_set; | ||
69 | void __iomem *outp_clr; | ||
70 | void __iomem *dir_set; | ||
71 | void __iomem *dir_clr; | ||
72 | }; | ||
73 | |||
74 | /* | ||
75 | * GPIO names | ||
76 | */ | ||
77 | static const char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = { | ||
78 | "p0.0", "p0.1", "p0.2", "p0.3", | ||
79 | "p0.4", "p0.5", "p0.6", "p0.7" | ||
80 | }; | ||
81 | |||
82 | static const char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = { | ||
83 | "p1.0", "p1.1", "p1.2", "p1.3", | ||
84 | "p1.4", "p1.5", "p1.6", "p1.7", | ||
85 | "p1.8", "p1.9", "p1.10", "p1.11", | ||
86 | "p1.12", "p1.13", "p1.14", "p1.15", | ||
87 | "p1.16", "p1.17", "p1.18", "p1.19", | ||
88 | "p1.20", "p1.21", "p1.22", "p1.23", | ||
89 | }; | ||
90 | |||
91 | static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = { | ||
92 | "p2.0", "p2.1", "p2.2", "p2.3", | ||
93 | "p2.4", "p2.5", "p2.6", "p2.7", | ||
94 | "p2.8", "p2.9", "p2.10", "p2.11", | ||
95 | "p2.12" | ||
96 | }; | ||
97 | |||
98 | static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = { | ||
99 | "gpi000", "gpio01", "gpio02", "gpio03", | ||
100 | "gpio04", "gpio05" | ||
101 | }; | ||
102 | |||
103 | static const char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = { | ||
104 | "gpi00", "gpi01", "gpi02", "gpi03", | ||
105 | "gpi04", "gpi05", "gpi06", "gpi07", | ||
106 | "gpi08", "gpi09", NULL, NULL, | ||
107 | NULL, NULL, NULL, "gpi15", | ||
108 | "gpi16", "gpi17", "gpi18", "gpi19", | ||
109 | "gpi20", "gpi21", "gpi22", "gpi23", | ||
110 | "gpi24", "gpi25", "gpi26", "gpi27" | ||
111 | }; | ||
112 | |||
113 | static const char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = { | ||
114 | "gpo00", "gpo01", "gpo02", "gpo03", | ||
115 | "gpo04", "gpo05", "gpo06", "gpo07", | ||
116 | "gpo08", "gpo09", "gpo10", "gpo11", | ||
117 | "gpo12", "gpo13", "gpo14", "gpo15", | ||
118 | "gpo16", "gpo17", "gpo18", "gpo19", | ||
119 | "gpo20", "gpo21", "gpo22", "gpo23" | ||
120 | }; | ||
121 | |||
122 | static struct gpio_regs gpio_grp_regs_p0 = { | ||
123 | .inp_state = LPC32XX_GPIO_P0_INP_STATE, | ||
124 | .outp_set = LPC32XX_GPIO_P0_OUTP_SET, | ||
125 | .outp_clr = LPC32XX_GPIO_P0_OUTP_CLR, | ||
126 | .dir_set = LPC32XX_GPIO_P0_DIR_SET, | ||
127 | .dir_clr = LPC32XX_GPIO_P0_DIR_CLR, | ||
128 | }; | ||
129 | |||
130 | static struct gpio_regs gpio_grp_regs_p1 = { | ||
131 | .inp_state = LPC32XX_GPIO_P1_INP_STATE, | ||
132 | .outp_set = LPC32XX_GPIO_P1_OUTP_SET, | ||
133 | .outp_clr = LPC32XX_GPIO_P1_OUTP_CLR, | ||
134 | .dir_set = LPC32XX_GPIO_P1_DIR_SET, | ||
135 | .dir_clr = LPC32XX_GPIO_P1_DIR_CLR, | ||
136 | }; | ||
137 | |||
138 | static struct gpio_regs gpio_grp_regs_p2 = { | ||
139 | .inp_state = LPC32XX_GPIO_P2_INP_STATE, | ||
140 | .outp_set = LPC32XX_GPIO_P2_OUTP_SET, | ||
141 | .outp_clr = LPC32XX_GPIO_P2_OUTP_CLR, | ||
142 | .dir_set = LPC32XX_GPIO_P2_DIR_SET, | ||
143 | .dir_clr = LPC32XX_GPIO_P2_DIR_CLR, | ||
144 | }; | ||
145 | |||
146 | static struct gpio_regs gpio_grp_regs_p3 = { | ||
147 | .inp_state = LPC32XX_GPIO_P3_INP_STATE, | ||
148 | .outp_set = LPC32XX_GPIO_P3_OUTP_SET, | ||
149 | .outp_clr = LPC32XX_GPIO_P3_OUTP_CLR, | ||
150 | .dir_set = LPC32XX_GPIO_P2_DIR_SET, | ||
151 | .dir_clr = LPC32XX_GPIO_P2_DIR_CLR, | ||
152 | }; | ||
153 | |||
154 | struct lpc32xx_gpio_chip { | ||
155 | struct gpio_chip chip; | ||
156 | struct gpio_regs *gpio_grp; | ||
157 | }; | ||
158 | |||
159 | static inline struct lpc32xx_gpio_chip *to_lpc32xx_gpio( | ||
160 | struct gpio_chip *gpc) | ||
161 | { | ||
162 | return container_of(gpc, struct lpc32xx_gpio_chip, chip); | ||
163 | } | ||
164 | |||
165 | static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group, | ||
166 | unsigned pin, int input) | ||
167 | { | ||
168 | if (input) | ||
169 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | ||
170 | group->gpio_grp->dir_clr); | ||
171 | else | ||
172 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | ||
173 | group->gpio_grp->dir_set); | ||
174 | } | ||
175 | |||
176 | static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group, | ||
177 | unsigned pin, int input) | ||
178 | { | ||
179 | u32 u = GPIO3_PIN_TO_BIT(pin); | ||
180 | |||
181 | if (input) | ||
182 | __raw_writel(u, group->gpio_grp->dir_clr); | ||
183 | else | ||
184 | __raw_writel(u, group->gpio_grp->dir_set); | ||
185 | } | ||
186 | |||
187 | static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group, | ||
188 | unsigned pin, int high) | ||
189 | { | ||
190 | if (high) | ||
191 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | ||
192 | group->gpio_grp->outp_set); | ||
193 | else | ||
194 | __raw_writel(GPIO012_PIN_TO_BIT(pin), | ||
195 | group->gpio_grp->outp_clr); | ||
196 | } | ||
197 | |||
198 | static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group, | ||
199 | unsigned pin, int high) | ||
200 | { | ||
201 | u32 u = GPIO3_PIN_TO_BIT(pin); | ||
202 | |||
203 | if (high) | ||
204 | __raw_writel(u, group->gpio_grp->outp_set); | ||
205 | else | ||
206 | __raw_writel(u, group->gpio_grp->outp_clr); | ||
207 | } | ||
208 | |||
209 | static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group, | ||
210 | unsigned pin, int high) | ||
211 | { | ||
212 | if (high) | ||
213 | __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set); | ||
214 | else | ||
215 | __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr); | ||
216 | } | ||
217 | |||
218 | static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group, | ||
219 | unsigned pin) | ||
220 | { | ||
221 | return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), | ||
222 | pin); | ||
223 | } | ||
224 | |||
225 | static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group, | ||
226 | unsigned pin) | ||
227 | { | ||
228 | int state = __raw_readl(group->gpio_grp->inp_state); | ||
229 | |||
230 | /* | ||
231 | * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped | ||
232 | * to bits 10..14, while GPIOP3-5 is mapped to bit 24. | ||
233 | */ | ||
234 | return GPIO3_PIN_IN_SEL(state, pin); | ||
235 | } | ||
236 | |||
237 | static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group, | ||
238 | unsigned pin) | ||
239 | { | ||
240 | return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin); | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * GENERIC_GPIO primitives. | ||
245 | */ | ||
246 | static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip, | ||
247 | unsigned pin) | ||
248 | { | ||
249 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
250 | |||
251 | __set_gpio_dir_p012(group, pin, 1); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip, | ||
257 | unsigned pin) | ||
258 | { | ||
259 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
260 | |||
261 | __set_gpio_dir_p3(group, pin, 1); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip, | ||
267 | unsigned pin) | ||
268 | { | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin) | ||
273 | { | ||
274 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
275 | |||
276 | return __get_gpio_state_p012(group, pin); | ||
277 | } | ||
278 | |||
279 | static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin) | ||
280 | { | ||
281 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
282 | |||
283 | return __get_gpio_state_p3(group, pin); | ||
284 | } | ||
285 | |||
286 | static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin) | ||
287 | { | ||
288 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
289 | |||
290 | return __get_gpi_state_p3(group, pin); | ||
291 | } | ||
292 | |||
293 | static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin, | ||
294 | int value) | ||
295 | { | ||
296 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
297 | |||
298 | __set_gpio_dir_p012(group, pin, 0); | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin, | ||
304 | int value) | ||
305 | { | ||
306 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
307 | |||
308 | __set_gpio_dir_p3(group, pin, 0); | ||
309 | |||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin, | ||
314 | int value) | ||
315 | { | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin, | ||
320 | int value) | ||
321 | { | ||
322 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
323 | |||
324 | __set_gpio_level_p012(group, pin, value); | ||
325 | } | ||
326 | |||
327 | static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin, | ||
328 | int value) | ||
329 | { | ||
330 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
331 | |||
332 | __set_gpio_level_p3(group, pin, value); | ||
333 | } | ||
334 | |||
335 | static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin, | ||
336 | int value) | ||
337 | { | ||
338 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
339 | |||
340 | __set_gpo_level_p3(group, pin, value); | ||
341 | } | ||
342 | |||
343 | static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin) | ||
344 | { | ||
345 | if (pin < chip->ngpio) | ||
346 | return 0; | ||
347 | |||
348 | return -EINVAL; | ||
349 | } | ||
350 | |||
351 | static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = { | ||
352 | { | ||
353 | .chip = { | ||
354 | .label = "gpio_p0", | ||
355 | .direction_input = lpc32xx_gpio_dir_input_p012, | ||
356 | .get = lpc32xx_gpio_get_value_p012, | ||
357 | .direction_output = lpc32xx_gpio_dir_output_p012, | ||
358 | .set = lpc32xx_gpio_set_value_p012, | ||
359 | .request = lpc32xx_gpio_request, | ||
360 | .base = LPC32XX_GPIO_P0_GRP, | ||
361 | .ngpio = LPC32XX_GPIO_P0_MAX, | ||
362 | .names = gpio_p0_names, | ||
363 | .can_sleep = 0, | ||
364 | }, | ||
365 | .gpio_grp = &gpio_grp_regs_p0, | ||
366 | }, | ||
367 | { | ||
368 | .chip = { | ||
369 | .label = "gpio_p1", | ||
370 | .direction_input = lpc32xx_gpio_dir_input_p012, | ||
371 | .get = lpc32xx_gpio_get_value_p012, | ||
372 | .direction_output = lpc32xx_gpio_dir_output_p012, | ||
373 | .set = lpc32xx_gpio_set_value_p012, | ||
374 | .request = lpc32xx_gpio_request, | ||
375 | .base = LPC32XX_GPIO_P1_GRP, | ||
376 | .ngpio = LPC32XX_GPIO_P1_MAX, | ||
377 | .names = gpio_p1_names, | ||
378 | .can_sleep = 0, | ||
379 | }, | ||
380 | .gpio_grp = &gpio_grp_regs_p1, | ||
381 | }, | ||
382 | { | ||
383 | .chip = { | ||
384 | .label = "gpio_p2", | ||
385 | .direction_input = lpc32xx_gpio_dir_input_p012, | ||
386 | .get = lpc32xx_gpio_get_value_p012, | ||
387 | .direction_output = lpc32xx_gpio_dir_output_p012, | ||
388 | .set = lpc32xx_gpio_set_value_p012, | ||
389 | .request = lpc32xx_gpio_request, | ||
390 | .base = LPC32XX_GPIO_P2_GRP, | ||
391 | .ngpio = LPC32XX_GPIO_P2_MAX, | ||
392 | .names = gpio_p2_names, | ||
393 | .can_sleep = 0, | ||
394 | }, | ||
395 | .gpio_grp = &gpio_grp_regs_p2, | ||
396 | }, | ||
397 | { | ||
398 | .chip = { | ||
399 | .label = "gpio_p3", | ||
400 | .direction_input = lpc32xx_gpio_dir_input_p3, | ||
401 | .get = lpc32xx_gpio_get_value_p3, | ||
402 | .direction_output = lpc32xx_gpio_dir_output_p3, | ||
403 | .set = lpc32xx_gpio_set_value_p3, | ||
404 | .request = lpc32xx_gpio_request, | ||
405 | .base = LPC32XX_GPIO_P3_GRP, | ||
406 | .ngpio = LPC32XX_GPIO_P3_MAX, | ||
407 | .names = gpio_p3_names, | ||
408 | .can_sleep = 0, | ||
409 | }, | ||
410 | .gpio_grp = &gpio_grp_regs_p3, | ||
411 | }, | ||
412 | { | ||
413 | .chip = { | ||
414 | .label = "gpi_p3", | ||
415 | .direction_input = lpc32xx_gpio_dir_in_always, | ||
416 | .get = lpc32xx_gpi_get_value, | ||
417 | .request = lpc32xx_gpio_request, | ||
418 | .base = LPC32XX_GPI_P3_GRP, | ||
419 | .ngpio = LPC32XX_GPI_P3_MAX, | ||
420 | .names = gpi_p3_names, | ||
421 | .can_sleep = 0, | ||
422 | }, | ||
423 | .gpio_grp = &gpio_grp_regs_p3, | ||
424 | }, | ||
425 | { | ||
426 | .chip = { | ||
427 | .label = "gpo_p3", | ||
428 | .direction_output = lpc32xx_gpio_dir_out_always, | ||
429 | .set = lpc32xx_gpo_set_value, | ||
430 | .request = lpc32xx_gpio_request, | ||
431 | .base = LPC32XX_GPO_P3_GRP, | ||
432 | .ngpio = LPC32XX_GPO_P3_MAX, | ||
433 | .names = gpo_p3_names, | ||
434 | .can_sleep = 0, | ||
435 | }, | ||
436 | .gpio_grp = &gpio_grp_regs_p3, | ||
437 | }, | ||
438 | }; | ||
439 | |||
440 | void __init lpc32xx_gpio_init(void) | ||
441 | { | ||
442 | int i; | ||
443 | |||
444 | for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) | ||
445 | gpiochip_add(&lpc32xx_gpiochip[i].chip); | ||
446 | } | ||
diff --git a/drivers/gpio/gpio-mc33880.c b/drivers/gpio/gpio-mc33880.c index b3b4652e89ec..2de57ce5feb6 100644 --- a/drivers/gpio/gpio-mc33880.c +++ b/drivers/gpio/gpio-mc33880.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/spi/mc33880.h> | 26 | #include <linux/spi/mc33880.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/module.h> | ||
29 | 30 | ||
30 | #define DRIVER_NAME "mc33880" | 31 | #define DRIVER_NAME "mc33880" |
31 | 32 | ||
diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 1ef46e6c2a2a..c5d83a8a91c2 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/device.h> | 6 | #include <linux/device.h> |
7 | #include <linux/mutex.h> | 7 | #include <linux/mutex.h> |
8 | #include <linux/module.h> | ||
8 | #include <linux/gpio.h> | 9 | #include <linux/gpio.h> |
9 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
10 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index a9016f56ed7e..ea8e73869250 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
@@ -14,10 +14,22 @@ | |||
14 | * along with this program; if not, write to the Free Software | 14 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
16 | */ | 16 | */ |
17 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
20 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/irq.h> | ||
24 | |||
25 | #define IOH_EDGE_FALLING 0 | ||
26 | #define IOH_EDGE_RISING BIT(0) | ||
27 | #define IOH_LEVEL_L BIT(1) | ||
28 | #define IOH_LEVEL_H (BIT(0) | BIT(1)) | ||
29 | #define IOH_EDGE_BOTH BIT(2) | ||
30 | #define IOH_IM_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
31 | |||
32 | #define IOH_IRQ_BASE 0 | ||
21 | 33 | ||
22 | #define PCI_VENDOR_ID_ROHM 0x10DB | 34 | #define PCI_VENDOR_ID_ROHM 0x10DB |
23 | 35 | ||
@@ -46,12 +58,22 @@ struct ioh_regs { | |||
46 | 58 | ||
47 | /** | 59 | /** |
48 | * struct ioh_gpio_reg_data - The register store data. | 60 | * struct ioh_gpio_reg_data - The register store data. |
61 | * @ien_reg To store contents of interrupt enable register. | ||
62 | * @imask_reg: To store contents of interrupt mask regist | ||
49 | * @po_reg: To store contents of PO register. | 63 | * @po_reg: To store contents of PO register. |
50 | * @pm_reg: To store contents of PM register. | 64 | * @pm_reg: To store contents of PM register. |
65 | * @im0_reg: To store contents of interrupt mode regist0 | ||
66 | * @im1_reg: To store contents of interrupt mode regist1 | ||
67 | * @use_sel_reg: To store contents of GPIO_USE_SEL0~3 | ||
51 | */ | 68 | */ |
52 | struct ioh_gpio_reg_data { | 69 | struct ioh_gpio_reg_data { |
70 | u32 ien_reg; | ||
71 | u32 imask_reg; | ||
53 | u32 po_reg; | 72 | u32 po_reg; |
54 | u32 pm_reg; | 73 | u32 pm_reg; |
74 | u32 im0_reg; | ||
75 | u32 im1_reg; | ||
76 | u32 use_sel_reg; | ||
55 | }; | 77 | }; |
56 | 78 | ||
57 | /** | 79 | /** |
@@ -62,7 +84,11 @@ struct ioh_gpio_reg_data { | |||
62 | * @gpio: Data for GPIO infrastructure. | 84 | * @gpio: Data for GPIO infrastructure. |
63 | * @ioh_gpio_reg: Memory mapped Register data is saved here | 85 | * @ioh_gpio_reg: Memory mapped Register data is saved here |
64 | * when suspend. | 86 | * when suspend. |
87 | * @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM | ||
65 | * @ch: Indicate GPIO channel | 88 | * @ch: Indicate GPIO channel |
89 | * @irq_base: Save base of IRQ number for interrupt | ||
90 | * @spinlock: Used for register access protection in | ||
91 | * interrupt context ioh_irq_type and PM; | ||
66 | */ | 92 | */ |
67 | struct ioh_gpio { | 93 | struct ioh_gpio { |
68 | void __iomem *base; | 94 | void __iomem *base; |
@@ -70,8 +96,11 @@ struct ioh_gpio { | |||
70 | struct device *dev; | 96 | struct device *dev; |
71 | struct gpio_chip gpio; | 97 | struct gpio_chip gpio; |
72 | struct ioh_gpio_reg_data ioh_gpio_reg; | 98 | struct ioh_gpio_reg_data ioh_gpio_reg; |
99 | u32 gpio_use_sel; | ||
73 | struct mutex lock; | 100 | struct mutex lock; |
74 | int ch; | 101 | int ch; |
102 | int irq_base; | ||
103 | spinlock_t spinlock; | ||
75 | }; | 104 | }; |
76 | 105 | ||
77 | static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12}; | 106 | static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12}; |
@@ -145,8 +174,25 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | |||
145 | */ | 174 | */ |
146 | static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) | 175 | static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) |
147 | { | 176 | { |
148 | chip->ioh_gpio_reg.po_reg = ioread32(&chip->reg->regs[chip->ch].po); | 177 | int i; |
149 | chip->ioh_gpio_reg.pm_reg = ioread32(&chip->reg->regs[chip->ch].pm); | 178 | |
179 | for (i = 0; i < 8; i ++, chip++) { | ||
180 | chip->ioh_gpio_reg.po_reg = | ||
181 | ioread32(&chip->reg->regs[chip->ch].po); | ||
182 | chip->ioh_gpio_reg.pm_reg = | ||
183 | ioread32(&chip->reg->regs[chip->ch].pm); | ||
184 | chip->ioh_gpio_reg.ien_reg = | ||
185 | ioread32(&chip->reg->regs[chip->ch].ien); | ||
186 | chip->ioh_gpio_reg.imask_reg = | ||
187 | ioread32(&chip->reg->regs[chip->ch].imask); | ||
188 | chip->ioh_gpio_reg.im0_reg = | ||
189 | ioread32(&chip->reg->regs[chip->ch].im_0); | ||
190 | chip->ioh_gpio_reg.im1_reg = | ||
191 | ioread32(&chip->reg->regs[chip->ch].im_1); | ||
192 | if (i < 4) | ||
193 | chip->ioh_gpio_reg.use_sel_reg = | ||
194 | ioread32(&chip->reg->ioh_sel_reg[i]); | ||
195 | } | ||
150 | } | 196 | } |
151 | 197 | ||
152 | /* | 198 | /* |
@@ -154,13 +200,34 @@ static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) | |||
154 | */ | 200 | */ |
155 | static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) | 201 | static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) |
156 | { | 202 | { |
157 | /* to store contents of PO register */ | 203 | int i; |
158 | iowrite32(chip->ioh_gpio_reg.po_reg, &chip->reg->regs[chip->ch].po); | 204 | |
159 | /* to store contents of PM register */ | 205 | for (i = 0; i < 8; i ++, chip++) { |
160 | iowrite32(chip->ioh_gpio_reg.pm_reg, &chip->reg->regs[chip->ch].pm); | 206 | iowrite32(chip->ioh_gpio_reg.po_reg, |
207 | &chip->reg->regs[chip->ch].po); | ||
208 | iowrite32(chip->ioh_gpio_reg.pm_reg, | ||
209 | &chip->reg->regs[chip->ch].pm); | ||
210 | iowrite32(chip->ioh_gpio_reg.ien_reg, | ||
211 | &chip->reg->regs[chip->ch].ien); | ||
212 | iowrite32(chip->ioh_gpio_reg.imask_reg, | ||
213 | &chip->reg->regs[chip->ch].imask); | ||
214 | iowrite32(chip->ioh_gpio_reg.im0_reg, | ||
215 | &chip->reg->regs[chip->ch].im_0); | ||
216 | iowrite32(chip->ioh_gpio_reg.im1_reg, | ||
217 | &chip->reg->regs[chip->ch].im_1); | ||
218 | if (i < 4) | ||
219 | iowrite32(chip->ioh_gpio_reg.use_sel_reg, | ||
220 | &chip->reg->ioh_sel_reg[i]); | ||
221 | } | ||
161 | } | 222 | } |
162 | #endif | 223 | #endif |
163 | 224 | ||
225 | static int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) | ||
226 | { | ||
227 | struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); | ||
228 | return chip->irq_base + offset; | ||
229 | } | ||
230 | |||
164 | static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) | 231 | static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) |
165 | { | 232 | { |
166 | struct gpio_chip *gpio = &chip->gpio; | 233 | struct gpio_chip *gpio = &chip->gpio; |
@@ -175,16 +242,148 @@ static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) | |||
175 | gpio->base = -1; | 242 | gpio->base = -1; |
176 | gpio->ngpio = num_port; | 243 | gpio->ngpio = num_port; |
177 | gpio->can_sleep = 0; | 244 | gpio->can_sleep = 0; |
245 | gpio->to_irq = ioh_gpio_to_irq; | ||
246 | } | ||
247 | |||
248 | static int ioh_irq_type(struct irq_data *d, unsigned int type) | ||
249 | { | ||
250 | u32 im; | ||
251 | u32 *im_reg; | ||
252 | u32 ien; | ||
253 | u32 im_pos; | ||
254 | int ch; | ||
255 | unsigned long flags; | ||
256 | u32 val; | ||
257 | int irq = d->irq; | ||
258 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
259 | struct ioh_gpio *chip = gc->private; | ||
260 | |||
261 | ch = irq - chip->irq_base; | ||
262 | if (irq <= chip->irq_base + 7) { | ||
263 | im_reg = &chip->reg->regs[chip->ch].im_0; | ||
264 | im_pos = ch; | ||
265 | } else { | ||
266 | im_reg = &chip->reg->regs[chip->ch].im_1; | ||
267 | im_pos = ch - 8; | ||
268 | } | ||
269 | dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n", | ||
270 | __func__, irq, type, ch, im_pos, type); | ||
271 | |||
272 | spin_lock_irqsave(&chip->spinlock, flags); | ||
273 | |||
274 | switch (type) { | ||
275 | case IRQ_TYPE_EDGE_RISING: | ||
276 | val = IOH_EDGE_RISING; | ||
277 | break; | ||
278 | case IRQ_TYPE_EDGE_FALLING: | ||
279 | val = IOH_EDGE_FALLING; | ||
280 | break; | ||
281 | case IRQ_TYPE_EDGE_BOTH: | ||
282 | val = IOH_EDGE_BOTH; | ||
283 | break; | ||
284 | case IRQ_TYPE_LEVEL_HIGH: | ||
285 | val = IOH_LEVEL_H; | ||
286 | break; | ||
287 | case IRQ_TYPE_LEVEL_LOW: | ||
288 | val = IOH_LEVEL_L; | ||
289 | break; | ||
290 | case IRQ_TYPE_PROBE: | ||
291 | goto end; | ||
292 | default: | ||
293 | dev_warn(chip->dev, "%s: unknown type(%dd)", | ||
294 | __func__, type); | ||
295 | goto end; | ||
296 | } | ||
297 | |||
298 | /* Set interrupt mode */ | ||
299 | im = ioread32(im_reg) & ~(IOH_IM_MASK << (im_pos * 4)); | ||
300 | iowrite32(im | (val << (im_pos * 4)), im_reg); | ||
301 | |||
302 | /* iclr */ | ||
303 | iowrite32(BIT(ch), &chip->reg->regs[chip->ch].iclr); | ||
304 | |||
305 | /* IMASKCLR */ | ||
306 | iowrite32(BIT(ch), &chip->reg->regs[chip->ch].imaskclr); | ||
307 | |||
308 | /* Enable interrupt */ | ||
309 | ien = ioread32(&chip->reg->regs[chip->ch].ien); | ||
310 | iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien); | ||
311 | end: | ||
312 | spin_unlock_irqrestore(&chip->spinlock, flags); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static void ioh_irq_unmask(struct irq_data *d) | ||
318 | { | ||
319 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
320 | struct ioh_gpio *chip = gc->private; | ||
321 | |||
322 | iowrite32(1 << (d->irq - chip->irq_base), | ||
323 | &chip->reg->regs[chip->ch].imaskclr); | ||
324 | } | ||
325 | |||
326 | static void ioh_irq_mask(struct irq_data *d) | ||
327 | { | ||
328 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
329 | struct ioh_gpio *chip = gc->private; | ||
330 | |||
331 | iowrite32(1 << (d->irq - chip->irq_base), | ||
332 | &chip->reg->regs[chip->ch].imask); | ||
333 | } | ||
334 | |||
335 | static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) | ||
336 | { | ||
337 | struct ioh_gpio *chip = dev_id; | ||
338 | u32 reg_val; | ||
339 | int i, j; | ||
340 | int ret = IRQ_NONE; | ||
341 | |||
342 | for (i = 0; i < 8; i++) { | ||
343 | reg_val = ioread32(&chip->reg->regs[i].istatus); | ||
344 | for (j = 0; j < num_ports[i]; j++) { | ||
345 | if (reg_val & BIT(j)) { | ||
346 | dev_dbg(chip->dev, | ||
347 | "%s:[%d]:irq=%d status=0x%x\n", | ||
348 | __func__, j, irq, reg_val); | ||
349 | iowrite32(BIT(j), | ||
350 | &chip->reg->regs[chip->ch].iclr); | ||
351 | generic_handle_irq(chip->irq_base + j); | ||
352 | ret = IRQ_HANDLED; | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | return ret; | ||
357 | } | ||
358 | |||
359 | static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, | ||
360 | unsigned int irq_start, unsigned int num) | ||
361 | { | ||
362 | struct irq_chip_generic *gc; | ||
363 | struct irq_chip_type *ct; | ||
364 | |||
365 | gc = irq_alloc_generic_chip("ioh_gpio", 1, irq_start, chip->base, | ||
366 | handle_simple_irq); | ||
367 | gc->private = chip; | ||
368 | ct = gc->chip_types; | ||
369 | |||
370 | ct->chip.irq_mask = ioh_irq_mask; | ||
371 | ct->chip.irq_unmask = ioh_irq_unmask; | ||
372 | ct->chip.irq_set_type = ioh_irq_type; | ||
373 | |||
374 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | ||
375 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
178 | } | 376 | } |
179 | 377 | ||
180 | static int __devinit ioh_gpio_probe(struct pci_dev *pdev, | 378 | static int __devinit ioh_gpio_probe(struct pci_dev *pdev, |
181 | const struct pci_device_id *id) | 379 | const struct pci_device_id *id) |
182 | { | 380 | { |
183 | int ret; | 381 | int ret; |
184 | int i; | 382 | int i, j; |
185 | struct ioh_gpio *chip; | 383 | struct ioh_gpio *chip; |
186 | void __iomem *base; | 384 | void __iomem *base; |
187 | void __iomem *chip_save; | 385 | void __iomem *chip_save; |
386 | int irq_base; | ||
188 | 387 | ||
189 | ret = pci_enable_device(pdev); | 388 | ret = pci_enable_device(pdev); |
190 | if (ret) { | 389 | if (ret) { |
@@ -228,10 +427,41 @@ static int __devinit ioh_gpio_probe(struct pci_dev *pdev, | |||
228 | } | 427 | } |
229 | 428 | ||
230 | chip = chip_save; | 429 | chip = chip_save; |
430 | for (j = 0; j < 8; j++, chip++) { | ||
431 | irq_base = irq_alloc_descs(-1, IOH_IRQ_BASE, num_ports[j], | ||
432 | NUMA_NO_NODE); | ||
433 | if (irq_base < 0) { | ||
434 | dev_warn(&pdev->dev, | ||
435 | "ml_ioh_gpio: Failed to get IRQ base num\n"); | ||
436 | chip->irq_base = -1; | ||
437 | goto err_irq_alloc_descs; | ||
438 | } | ||
439 | chip->irq_base = irq_base; | ||
440 | ioh_gpio_alloc_generic_chip(chip, irq_base, num_ports[j]); | ||
441 | } | ||
442 | |||
443 | chip = chip_save; | ||
444 | ret = request_irq(pdev->irq, ioh_gpio_handler, | ||
445 | IRQF_SHARED, KBUILD_MODNAME, chip); | ||
446 | if (ret != 0) { | ||
447 | dev_err(&pdev->dev, | ||
448 | "%s request_irq failed\n", __func__); | ||
449 | goto err_request_irq; | ||
450 | } | ||
451 | |||
231 | pci_set_drvdata(pdev, chip); | 452 | pci_set_drvdata(pdev, chip); |
232 | 453 | ||
233 | return 0; | 454 | return 0; |
234 | 455 | ||
456 | err_request_irq: | ||
457 | chip = chip_save; | ||
458 | err_irq_alloc_descs: | ||
459 | while (--j >= 0) { | ||
460 | chip--; | ||
461 | irq_free_descs(chip->irq_base, num_ports[j]); | ||
462 | } | ||
463 | |||
464 | chip = chip_save; | ||
235 | err_gpiochip_add: | 465 | err_gpiochip_add: |
236 | while (--i >= 0) { | 466 | while (--i >= 0) { |
237 | chip--; | 467 | chip--; |
@@ -264,7 +494,11 @@ static void __devexit ioh_gpio_remove(struct pci_dev *pdev) | |||
264 | void __iomem *chip_save; | 494 | void __iomem *chip_save; |
265 | 495 | ||
266 | chip_save = chip; | 496 | chip_save = chip; |
497 | |||
498 | free_irq(pdev->irq, chip); | ||
499 | |||
267 | for (i = 0; i < 8; i++, chip++) { | 500 | for (i = 0; i < 8; i++, chip++) { |
501 | irq_free_descs(chip->irq_base, num_ports[i]); | ||
268 | err = gpiochip_remove(&chip->gpio); | 502 | err = gpiochip_remove(&chip->gpio); |
269 | if (err) | 503 | if (err) |
270 | dev_err(&pdev->dev, "Failed gpiochip_remove\n"); | 504 | dev_err(&pdev->dev, "Failed gpiochip_remove\n"); |
@@ -282,9 +516,11 @@ static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state) | |||
282 | { | 516 | { |
283 | s32 ret; | 517 | s32 ret; |
284 | struct ioh_gpio *chip = pci_get_drvdata(pdev); | 518 | struct ioh_gpio *chip = pci_get_drvdata(pdev); |
519 | unsigned long flags; | ||
285 | 520 | ||
521 | spin_lock_irqsave(&chip->spinlock, flags); | ||
286 | ioh_gpio_save_reg_conf(chip); | 522 | ioh_gpio_save_reg_conf(chip); |
287 | ioh_gpio_restore_reg_conf(chip); | 523 | spin_unlock_irqrestore(&chip->spinlock, flags); |
288 | 524 | ||
289 | ret = pci_save_state(pdev); | 525 | ret = pci_save_state(pdev); |
290 | if (ret) { | 526 | if (ret) { |
@@ -304,6 +540,7 @@ static int ioh_gpio_resume(struct pci_dev *pdev) | |||
304 | { | 540 | { |
305 | s32 ret; | 541 | s32 ret; |
306 | struct ioh_gpio *chip = pci_get_drvdata(pdev); | 542 | struct ioh_gpio *chip = pci_get_drvdata(pdev); |
543 | unsigned long flags; | ||
307 | 544 | ||
308 | ret = pci_enable_wake(pdev, PCI_D0, 0); | 545 | ret = pci_enable_wake(pdev, PCI_D0, 0); |
309 | 546 | ||
@@ -315,9 +552,11 @@ static int ioh_gpio_resume(struct pci_dev *pdev) | |||
315 | } | 552 | } |
316 | pci_restore_state(pdev); | 553 | pci_restore_state(pdev); |
317 | 554 | ||
555 | spin_lock_irqsave(&chip->spinlock, flags); | ||
318 | iowrite32(0x01, &chip->reg->srst); | 556 | iowrite32(0x01, &chip->reg->srst); |
319 | iowrite32(0x00, &chip->reg->srst); | 557 | iowrite32(0x00, &chip->reg->srst); |
320 | ioh_gpio_restore_reg_conf(chip); | 558 | ioh_gpio_restore_reg_conf(chip); |
559 | spin_unlock_irqrestore(&chip->spinlock, flags); | ||
321 | 560 | ||
322 | return 0; | 561 | return 0; |
323 | } | 562 | } |
diff --git a/drivers/gpio/gpio-mpc5200.c b/drivers/gpio/gpio-mpc5200.c index 52d3ed208105..2c7cef367fc0 100644 --- a/drivers/gpio/gpio-mpc5200.c +++ b/drivers/gpio/gpio-mpc5200.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/of_gpio.h> | 23 | #include <linux/of_gpio.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
26 | #include <linux/module.h> | ||
26 | 27 | ||
27 | #include <asm/gpio.h> | 28 | #include <asm/gpio.h> |
28 | #include <asm/mpc52xx.h> | 29 | #include <asm/mpc52xx.h> |
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c new file mode 100644 index 000000000000..ec3fcf0a7e12 --- /dev/null +++ b/drivers/gpio/gpio-mpc8xxx.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * GPIOs on MPC512x/8349/8572/8610 and compatible | ||
3 | * | ||
4 | * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_gpio.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/irq.h> | ||
20 | |||
21 | #define MPC8XXX_GPIO_PINS 32 | ||
22 | |||
23 | #define GPIO_DIR 0x00 | ||
24 | #define GPIO_ODR 0x04 | ||
25 | #define GPIO_DAT 0x08 | ||
26 | #define GPIO_IER 0x0c | ||
27 | #define GPIO_IMR 0x10 | ||
28 | #define GPIO_ICR 0x14 | ||
29 | #define GPIO_ICR2 0x18 | ||
30 | |||
31 | struct mpc8xxx_gpio_chip { | ||
32 | struct of_mm_gpio_chip mm_gc; | ||
33 | spinlock_t lock; | ||
34 | |||
35 | /* | ||
36 | * shadowed data register to be able to clear/set output pins in | ||
37 | * open drain mode safely | ||
38 | */ | ||
39 | u32 data; | ||
40 | struct irq_host *irq; | ||
41 | void *of_dev_id_data; | ||
42 | }; | ||
43 | |||
44 | static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) | ||
45 | { | ||
46 | return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); | ||
47 | } | ||
48 | |||
49 | static inline struct mpc8xxx_gpio_chip * | ||
50 | to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm) | ||
51 | { | ||
52 | return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc); | ||
53 | } | ||
54 | |||
55 | static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm) | ||
56 | { | ||
57 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
58 | |||
59 | mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT); | ||
60 | } | ||
61 | |||
62 | /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs | ||
63 | * defined as output cannot be determined by reading GPDAT register, | ||
64 | * so we use shadow data register instead. The status of input pins | ||
65 | * is determined by reading GPDAT register. | ||
66 | */ | ||
67 | static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
68 | { | ||
69 | u32 val; | ||
70 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
71 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
72 | |||
73 | val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR); | ||
74 | |||
75 | return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio); | ||
76 | } | ||
77 | |||
78 | static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
79 | { | ||
80 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
81 | |||
82 | return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio); | ||
83 | } | ||
84 | |||
85 | static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
86 | { | ||
87 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
88 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
89 | unsigned long flags; | ||
90 | |||
91 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
92 | |||
93 | if (val) | ||
94 | mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio); | ||
95 | else | ||
96 | mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio); | ||
97 | |||
98 | out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data); | ||
99 | |||
100 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
101 | } | ||
102 | |||
103 | static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
104 | { | ||
105 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
106 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
107 | unsigned long flags; | ||
108 | |||
109 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
110 | |||
111 | clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
112 | |||
113 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
119 | { | ||
120 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
121 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
122 | unsigned long flags; | ||
123 | |||
124 | mpc8xxx_gpio_set(gc, gpio, val); | ||
125 | |||
126 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
127 | |||
128 | setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio)); | ||
129 | |||
130 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
136 | { | ||
137 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
138 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
139 | |||
140 | if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) | ||
141 | return irq_create_mapping(mpc8xxx_gc->irq, offset); | ||
142 | else | ||
143 | return -ENXIO; | ||
144 | } | ||
145 | |||
146 | static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) | ||
147 | { | ||
148 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); | ||
149 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
150 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
151 | unsigned int mask; | ||
152 | |||
153 | mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR); | ||
154 | if (mask) | ||
155 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, | ||
156 | 32 - ffs(mask))); | ||
157 | chip->irq_eoi(&desc->irq_data); | ||
158 | } | ||
159 | |||
160 | static void mpc8xxx_irq_unmask(struct irq_data *d) | ||
161 | { | ||
162 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
163 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
164 | unsigned long flags; | ||
165 | |||
166 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
167 | |||
168 | setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
169 | |||
170 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
171 | } | ||
172 | |||
173 | static void mpc8xxx_irq_mask(struct irq_data *d) | ||
174 | { | ||
175 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
176 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
177 | unsigned long flags; | ||
178 | |||
179 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
180 | |||
181 | clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
182 | |||
183 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
184 | } | ||
185 | |||
186 | static void mpc8xxx_irq_ack(struct irq_data *d) | ||
187 | { | ||
188 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
189 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
190 | |||
191 | out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
192 | } | ||
193 | |||
194 | static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
195 | { | ||
196 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
197 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
198 | unsigned long flags; | ||
199 | |||
200 | switch (flow_type) { | ||
201 | case IRQ_TYPE_EDGE_FALLING: | ||
202 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
203 | setbits32(mm->regs + GPIO_ICR, | ||
204 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
205 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
206 | break; | ||
207 | |||
208 | case IRQ_TYPE_EDGE_BOTH: | ||
209 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
210 | clrbits32(mm->regs + GPIO_ICR, | ||
211 | mpc8xxx_gpio2mask(irqd_to_hwirq(d))); | ||
212 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
213 | break; | ||
214 | |||
215 | default: | ||
216 | return -EINVAL; | ||
217 | } | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
223 | { | ||
224 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d); | ||
225 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
226 | unsigned long gpio = irqd_to_hwirq(d); | ||
227 | void __iomem *reg; | ||
228 | unsigned int shift; | ||
229 | unsigned long flags; | ||
230 | |||
231 | if (gpio < 16) { | ||
232 | reg = mm->regs + GPIO_ICR; | ||
233 | shift = (15 - gpio) * 2; | ||
234 | } else { | ||
235 | reg = mm->regs + GPIO_ICR2; | ||
236 | shift = (15 - (gpio % 16)) * 2; | ||
237 | } | ||
238 | |||
239 | switch (flow_type) { | ||
240 | case IRQ_TYPE_EDGE_FALLING: | ||
241 | case IRQ_TYPE_LEVEL_LOW: | ||
242 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
243 | clrsetbits_be32(reg, 3 << shift, 2 << shift); | ||
244 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
245 | break; | ||
246 | |||
247 | case IRQ_TYPE_EDGE_RISING: | ||
248 | case IRQ_TYPE_LEVEL_HIGH: | ||
249 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
250 | clrsetbits_be32(reg, 3 << shift, 1 << shift); | ||
251 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
252 | break; | ||
253 | |||
254 | case IRQ_TYPE_EDGE_BOTH: | ||
255 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
256 | clrbits32(reg, 3 << shift); | ||
257 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
258 | break; | ||
259 | |||
260 | default: | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static struct irq_chip mpc8xxx_irq_chip = { | ||
268 | .name = "mpc8xxx-gpio", | ||
269 | .irq_unmask = mpc8xxx_irq_unmask, | ||
270 | .irq_mask = mpc8xxx_irq_mask, | ||
271 | .irq_ack = mpc8xxx_irq_ack, | ||
272 | .irq_set_type = mpc8xxx_irq_set_type, | ||
273 | }; | ||
274 | |||
275 | static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, | ||
276 | irq_hw_number_t hw) | ||
277 | { | ||
278 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; | ||
279 | |||
280 | if (mpc8xxx_gc->of_dev_id_data) | ||
281 | mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data; | ||
282 | |||
283 | irq_set_chip_data(virq, h->host_data); | ||
284 | irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); | ||
285 | irq_set_irq_type(virq, IRQ_TYPE_NONE); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, | ||
291 | const u32 *intspec, unsigned int intsize, | ||
292 | irq_hw_number_t *out_hwirq, | ||
293 | unsigned int *out_flags) | ||
294 | |||
295 | { | ||
296 | /* interrupt sense values coming from the device tree equal either | ||
297 | * EDGE_FALLING or EDGE_BOTH | ||
298 | */ | ||
299 | *out_hwirq = intspec[0]; | ||
300 | *out_flags = intspec[1]; | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static struct irq_host_ops mpc8xxx_gpio_irq_ops = { | ||
306 | .map = mpc8xxx_gpio_irq_map, | ||
307 | .xlate = mpc8xxx_gpio_irq_xlate, | ||
308 | }; | ||
309 | |||
310 | static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { | ||
311 | { .compatible = "fsl,mpc8349-gpio", }, | ||
312 | { .compatible = "fsl,mpc8572-gpio", }, | ||
313 | { .compatible = "fsl,mpc8610-gpio", }, | ||
314 | { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, }, | ||
315 | { .compatible = "fsl,pq3-gpio", }, | ||
316 | { .compatible = "fsl,qoriq-gpio", }, | ||
317 | {} | ||
318 | }; | ||
319 | |||
320 | static void __init mpc8xxx_add_controller(struct device_node *np) | ||
321 | { | ||
322 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | ||
323 | struct of_mm_gpio_chip *mm_gc; | ||
324 | struct gpio_chip *gc; | ||
325 | const struct of_device_id *id; | ||
326 | unsigned hwirq; | ||
327 | int ret; | ||
328 | |||
329 | mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); | ||
330 | if (!mpc8xxx_gc) { | ||
331 | ret = -ENOMEM; | ||
332 | goto err; | ||
333 | } | ||
334 | |||
335 | spin_lock_init(&mpc8xxx_gc->lock); | ||
336 | |||
337 | mm_gc = &mpc8xxx_gc->mm_gc; | ||
338 | gc = &mm_gc->gc; | ||
339 | |||
340 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | ||
341 | gc->ngpio = MPC8XXX_GPIO_PINS; | ||
342 | gc->direction_input = mpc8xxx_gpio_dir_in; | ||
343 | gc->direction_output = mpc8xxx_gpio_dir_out; | ||
344 | if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) | ||
345 | gc->get = mpc8572_gpio_get; | ||
346 | else | ||
347 | gc->get = mpc8xxx_gpio_get; | ||
348 | gc->set = mpc8xxx_gpio_set; | ||
349 | gc->to_irq = mpc8xxx_gpio_to_irq; | ||
350 | |||
351 | ret = of_mm_gpiochip_add(np, mm_gc); | ||
352 | if (ret) | ||
353 | goto err; | ||
354 | |||
355 | hwirq = irq_of_parse_and_map(np, 0); | ||
356 | if (hwirq == NO_IRQ) | ||
357 | goto skip_irq; | ||
358 | |||
359 | mpc8xxx_gc->irq = | ||
360 | irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, | ||
361 | &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); | ||
362 | if (!mpc8xxx_gc->irq) | ||
363 | goto skip_irq; | ||
364 | |||
365 | id = of_match_node(mpc8xxx_gpio_ids, np); | ||
366 | if (id) | ||
367 | mpc8xxx_gc->of_dev_id_data = id->data; | ||
368 | |||
369 | mpc8xxx_gc->irq->host_data = mpc8xxx_gc; | ||
370 | |||
371 | /* ack and mask all irqs */ | ||
372 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); | ||
373 | out_be32(mm_gc->regs + GPIO_IMR, 0); | ||
374 | |||
375 | irq_set_handler_data(hwirq, mpc8xxx_gc); | ||
376 | irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); | ||
377 | |||
378 | skip_irq: | ||
379 | return; | ||
380 | |||
381 | err: | ||
382 | pr_err("%s: registration failed with status %d\n", | ||
383 | np->full_name, ret); | ||
384 | kfree(mpc8xxx_gc); | ||
385 | |||
386 | return; | ||
387 | } | ||
388 | |||
389 | static int __init mpc8xxx_add_gpiochips(void) | ||
390 | { | ||
391 | struct device_node *np; | ||
392 | |||
393 | for_each_matching_node(np, mpc8xxx_gpio_ids) | ||
394 | mpc8xxx_add_controller(np); | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | arch_initcall(mpc8xxx_add_gpiochips); | ||
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 4340acae3bd3..e79147634573 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -29,7 +29,11 @@ | |||
29 | #include <linux/basic_mmio_gpio.h> | 29 | #include <linux/basic_mmio_gpio.h> |
30 | #include <linux/of.h> | 30 | #include <linux/of.h> |
31 | #include <linux/of_device.h> | 31 | #include <linux/of_device.h> |
32 | #include <linux/module.h> | ||
32 | #include <asm-generic/bug.h> | 33 | #include <asm-generic/bug.h> |
34 | #include <asm/mach/irq.h> | ||
35 | |||
36 | #define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) | ||
33 | 37 | ||
34 | enum mxc_gpio_hwtype { | 38 | enum mxc_gpio_hwtype { |
35 | IMX1_GPIO, /* runs on i.mx1 */ | 39 | IMX1_GPIO, /* runs on i.mx1 */ |
@@ -232,10 +236,15 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) | |||
232 | { | 236 | { |
233 | u32 irq_stat; | 237 | u32 irq_stat; |
234 | struct mxc_gpio_port *port = irq_get_handler_data(irq); | 238 | struct mxc_gpio_port *port = irq_get_handler_data(irq); |
239 | struct irq_chip *chip = irq_get_chip(irq); | ||
240 | |||
241 | chained_irq_enter(chip, desc); | ||
235 | 242 | ||
236 | irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR); | 243 | irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR); |
237 | 244 | ||
238 | mxc_gpio_irq_handler(port, irq_stat); | 245 | mxc_gpio_irq_handler(port, irq_stat); |
246 | |||
247 | chained_irq_exit(chip, desc); | ||
239 | } | 248 | } |
240 | 249 | ||
241 | /* MX2 has one interrupt *for all* gpio ports */ | 250 | /* MX2 has one interrupt *for all* gpio ports */ |
@@ -337,6 +346,15 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev) | |||
337 | mxc_gpio_hwtype = hwtype; | 346 | mxc_gpio_hwtype = hwtype; |
338 | } | 347 | } |
339 | 348 | ||
349 | static int mxc_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
350 | { | ||
351 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | ||
352 | struct mxc_gpio_port *port = | ||
353 | container_of(bgc, struct mxc_gpio_port, bgc); | ||
354 | |||
355 | return port->virtual_irq_start + offset; | ||
356 | } | ||
357 | |||
340 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) | 358 | static int __devinit mxc_gpio_probe(struct platform_device *pdev) |
341 | { | 359 | { |
342 | struct device_node *np = pdev->dev.of_node; | 360 | struct device_node *np = pdev->dev.of_node; |
@@ -403,6 +421,7 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
403 | if (err) | 421 | if (err) |
404 | goto out_iounmap; | 422 | goto out_iounmap; |
405 | 423 | ||
424 | port->bgc.gc.to_irq = mxc_gpio_to_irq; | ||
406 | port->bgc.gc.base = pdev->id * 32; | 425 | port->bgc.gc.base = pdev->id * 32; |
407 | port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); | 426 | port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); |
408 | port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); | 427 | port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); |
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c index af55a8577c2e..385c58e8405b 100644 --- a/drivers/gpio/gpio-mxs.c +++ b/drivers/gpio/gpio-mxs.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/basic_mmio_gpio.h> | 30 | #include <linux/basic_mmio_gpio.h> |
31 | #include <linux/module.h> | ||
31 | #include <mach/mxs.h> | 32 | #include <mach/mxs.h> |
32 | 33 | ||
33 | #define MXS_SET 0x4 | 34 | #define MXS_SET 0x4 |
@@ -49,6 +50,8 @@ | |||
49 | #define GPIO_INT_LEV_MASK (1 << 0) | 50 | #define GPIO_INT_LEV_MASK (1 << 0) |
50 | #define GPIO_INT_POL_MASK (1 << 1) | 51 | #define GPIO_INT_POL_MASK (1 << 1) |
51 | 52 | ||
53 | #define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) | ||
54 | |||
52 | struct mxs_gpio_port { | 55 | struct mxs_gpio_port { |
53 | void __iomem *base; | 56 | void __iomem *base; |
54 | int id; | 57 | int id; |
diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 2c212c732d76..1ebedfb6d46d 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c | |||
@@ -27,8 +27,9 @@ | |||
27 | #include <asm/mach/irq.h> | 27 | #include <asm/mach/irq.h> |
28 | 28 | ||
29 | #include <plat/pincfg.h> | 29 | #include <plat/pincfg.h> |
30 | #include <plat/gpio-nomadik.h> | ||
30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
31 | #include <mach/gpio.h> | 32 | #include <asm/gpio.h> |
32 | 33 | ||
33 | /* | 34 | /* |
34 | * The GPIO module in the Nomadik family of Systems-on-Chip is an | 35 | * The GPIO module in the Nomadik family of Systems-on-Chip is an |
@@ -58,7 +59,6 @@ struct nmk_gpio_chip { | |||
58 | u32 rwimsc; | 59 | u32 rwimsc; |
59 | u32 fwimsc; | 60 | u32 fwimsc; |
60 | u32 slpm; | 61 | u32 slpm; |
61 | u32 enabled; | ||
62 | u32 pull_up; | 62 | u32 pull_up; |
63 | }; | 63 | }; |
64 | 64 | ||
@@ -276,6 +276,8 @@ static void nmk_gpio_glitch_slpm_init(unsigned int *slpm) | |||
276 | if (!chip) | 276 | if (!chip) |
277 | break; | 277 | break; |
278 | 278 | ||
279 | clk_enable(chip->clk); | ||
280 | |||
279 | slpm[i] = readl(chip->addr + NMK_GPIO_SLPC); | 281 | slpm[i] = readl(chip->addr + NMK_GPIO_SLPC); |
280 | writel(temp, chip->addr + NMK_GPIO_SLPC); | 282 | writel(temp, chip->addr + NMK_GPIO_SLPC); |
281 | } | 283 | } |
@@ -292,6 +294,8 @@ static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm) | |||
292 | break; | 294 | break; |
293 | 295 | ||
294 | writel(slpm[i], chip->addr + NMK_GPIO_SLPC); | 296 | writel(slpm[i], chip->addr + NMK_GPIO_SLPC); |
297 | |||
298 | clk_disable(chip->clk); | ||
295 | } | 299 | } |
296 | } | 300 | } |
297 | 301 | ||
@@ -336,10 +340,12 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) | |||
336 | break; | 340 | break; |
337 | } | 341 | } |
338 | 342 | ||
343 | clk_enable(nmk_chip->clk); | ||
339 | spin_lock(&nmk_chip->lock); | 344 | spin_lock(&nmk_chip->lock); |
340 | __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base, | 345 | __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base, |
341 | cfgs[i], sleep, glitch ? slpm : NULL); | 346 | cfgs[i], sleep, glitch ? slpm : NULL); |
342 | spin_unlock(&nmk_chip->lock); | 347 | spin_unlock(&nmk_chip->lock); |
348 | clk_disable(nmk_chip->clk); | ||
343 | } | 349 | } |
344 | 350 | ||
345 | if (glitch) | 351 | if (glitch) |
@@ -424,6 +430,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | |||
424 | if (!nmk_chip) | 430 | if (!nmk_chip) |
425 | return -EINVAL; | 431 | return -EINVAL; |
426 | 432 | ||
433 | clk_enable(nmk_chip->clk); | ||
427 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | 434 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
428 | spin_lock(&nmk_chip->lock); | 435 | spin_lock(&nmk_chip->lock); |
429 | 436 | ||
@@ -431,6 +438,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | |||
431 | 438 | ||
432 | spin_unlock(&nmk_chip->lock); | 439 | spin_unlock(&nmk_chip->lock); |
433 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | 440 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); |
441 | clk_disable(nmk_chip->clk); | ||
434 | 442 | ||
435 | return 0; | 443 | return 0; |
436 | } | 444 | } |
@@ -457,9 +465,11 @@ int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull) | |||
457 | if (!nmk_chip) | 465 | if (!nmk_chip) |
458 | return -EINVAL; | 466 | return -EINVAL; |
459 | 467 | ||
468 | clk_enable(nmk_chip->clk); | ||
460 | spin_lock_irqsave(&nmk_chip->lock, flags); | 469 | spin_lock_irqsave(&nmk_chip->lock, flags); |
461 | __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull); | 470 | __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull); |
462 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 471 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
472 | clk_disable(nmk_chip->clk); | ||
463 | 473 | ||
464 | return 0; | 474 | return 0; |
465 | } | 475 | } |
@@ -483,9 +493,11 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode) | |||
483 | if (!nmk_chip) | 493 | if (!nmk_chip) |
484 | return -EINVAL; | 494 | return -EINVAL; |
485 | 495 | ||
496 | clk_enable(nmk_chip->clk); | ||
486 | spin_lock_irqsave(&nmk_chip->lock, flags); | 497 | spin_lock_irqsave(&nmk_chip->lock, flags); |
487 | __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode); | 498 | __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode); |
488 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 499 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
500 | clk_disable(nmk_chip->clk); | ||
489 | 501 | ||
490 | return 0; | 502 | return 0; |
491 | } | 503 | } |
@@ -502,9 +514,13 @@ int nmk_gpio_get_mode(int gpio) | |||
502 | 514 | ||
503 | bit = 1 << (gpio - nmk_chip->chip.base); | 515 | bit = 1 << (gpio - nmk_chip->chip.base); |
504 | 516 | ||
517 | clk_enable(nmk_chip->clk); | ||
518 | |||
505 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit; | 519 | afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit; |
506 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit; | 520 | bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit; |
507 | 521 | ||
522 | clk_disable(nmk_chip->clk); | ||
523 | |||
508 | return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); | 524 | return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); |
509 | } | 525 | } |
510 | EXPORT_SYMBOL(nmk_gpio_get_mode); | 526 | EXPORT_SYMBOL(nmk_gpio_get_mode); |
@@ -525,7 +541,10 @@ static void nmk_gpio_irq_ack(struct irq_data *d) | |||
525 | nmk_chip = irq_data_get_irq_chip_data(d); | 541 | nmk_chip = irq_data_get_irq_chip_data(d); |
526 | if (!nmk_chip) | 542 | if (!nmk_chip) |
527 | return; | 543 | return; |
544 | |||
545 | clk_enable(nmk_chip->clk); | ||
528 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); | 546 | writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); |
547 | clk_disable(nmk_chip->clk); | ||
529 | } | 548 | } |
530 | 549 | ||
531 | enum nmk_gpio_irq_type { | 550 | enum nmk_gpio_irq_type { |
@@ -586,11 +605,7 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) | |||
586 | if (!nmk_chip) | 605 | if (!nmk_chip) |
587 | return -EINVAL; | 606 | return -EINVAL; |
588 | 607 | ||
589 | if (enable) | 608 | clk_enable(nmk_chip->clk); |
590 | nmk_chip->enabled |= bitmask; | ||
591 | else | ||
592 | nmk_chip->enabled &= ~bitmask; | ||
593 | |||
594 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | 609 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
595 | spin_lock(&nmk_chip->lock); | 610 | spin_lock(&nmk_chip->lock); |
596 | 611 | ||
@@ -601,6 +616,7 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable) | |||
601 | 616 | ||
602 | spin_unlock(&nmk_chip->lock); | 617 | spin_unlock(&nmk_chip->lock); |
603 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | 618 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); |
619 | clk_disable(nmk_chip->clk); | ||
604 | 620 | ||
605 | return 0; | 621 | return 0; |
606 | } | 622 | } |
@@ -628,10 +644,11 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | |||
628 | return -EINVAL; | 644 | return -EINVAL; |
629 | bitmask = nmk_gpio_get_bitmask(gpio); | 645 | bitmask = nmk_gpio_get_bitmask(gpio); |
630 | 646 | ||
647 | clk_enable(nmk_chip->clk); | ||
631 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); | 648 | spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); |
632 | spin_lock(&nmk_chip->lock); | 649 | spin_lock(&nmk_chip->lock); |
633 | 650 | ||
634 | if (!(nmk_chip->enabled & bitmask)) | 651 | if (irqd_irq_disabled(d)) |
635 | __nmk_gpio_set_wake(nmk_chip, gpio, on); | 652 | __nmk_gpio_set_wake(nmk_chip, gpio, on); |
636 | 653 | ||
637 | if (on) | 654 | if (on) |
@@ -641,13 +658,15 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on) | |||
641 | 658 | ||
642 | spin_unlock(&nmk_chip->lock); | 659 | spin_unlock(&nmk_chip->lock); |
643 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); | 660 | spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); |
661 | clk_disable(nmk_chip->clk); | ||
644 | 662 | ||
645 | return 0; | 663 | return 0; |
646 | } | 664 | } |
647 | 665 | ||
648 | static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | 666 | static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
649 | { | 667 | { |
650 | bool enabled, wake = irqd_is_wakeup_set(d); | 668 | bool enabled = !irqd_irq_disabled(d); |
669 | bool wake = irqd_is_wakeup_set(d); | ||
651 | int gpio; | 670 | int gpio; |
652 | struct nmk_gpio_chip *nmk_chip; | 671 | struct nmk_gpio_chip *nmk_chip; |
653 | unsigned long flags; | 672 | unsigned long flags; |
@@ -664,8 +683,7 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
664 | if (type & IRQ_TYPE_LEVEL_LOW) | 683 | if (type & IRQ_TYPE_LEVEL_LOW) |
665 | return -EINVAL; | 684 | return -EINVAL; |
666 | 685 | ||
667 | enabled = nmk_chip->enabled & bitmask; | 686 | clk_enable(nmk_chip->clk); |
668 | |||
669 | spin_lock_irqsave(&nmk_chip->lock, flags); | 687 | spin_lock_irqsave(&nmk_chip->lock, flags); |
670 | 688 | ||
671 | if (enabled) | 689 | if (enabled) |
@@ -689,10 +707,28 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
689 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); | 707 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true); |
690 | 708 | ||
691 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | 709 | spin_unlock_irqrestore(&nmk_chip->lock, flags); |
710 | clk_disable(nmk_chip->clk); | ||
692 | 711 | ||
693 | return 0; | 712 | return 0; |
694 | } | 713 | } |
695 | 714 | ||
715 | static unsigned int nmk_gpio_irq_startup(struct irq_data *d) | ||
716 | { | ||
717 | struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); | ||
718 | |||
719 | clk_enable(nmk_chip->clk); | ||
720 | nmk_gpio_irq_unmask(d); | ||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | static void nmk_gpio_irq_shutdown(struct irq_data *d) | ||
725 | { | ||
726 | struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d); | ||
727 | |||
728 | nmk_gpio_irq_mask(d); | ||
729 | clk_disable(nmk_chip->clk); | ||
730 | } | ||
731 | |||
696 | static struct irq_chip nmk_gpio_irq_chip = { | 732 | static struct irq_chip nmk_gpio_irq_chip = { |
697 | .name = "Nomadik-GPIO", | 733 | .name = "Nomadik-GPIO", |
698 | .irq_ack = nmk_gpio_irq_ack, | 734 | .irq_ack = nmk_gpio_irq_ack, |
@@ -700,6 +736,8 @@ static struct irq_chip nmk_gpio_irq_chip = { | |||
700 | .irq_unmask = nmk_gpio_irq_unmask, | 736 | .irq_unmask = nmk_gpio_irq_unmask, |
701 | .irq_set_type = nmk_gpio_irq_set_type, | 737 | .irq_set_type = nmk_gpio_irq_set_type, |
702 | .irq_set_wake = nmk_gpio_irq_set_wake, | 738 | .irq_set_wake = nmk_gpio_irq_set_wake, |
739 | .irq_startup = nmk_gpio_irq_startup, | ||
740 | .irq_shutdown = nmk_gpio_irq_shutdown, | ||
703 | }; | 741 | }; |
704 | 742 | ||
705 | static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | 743 | static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, |
@@ -726,7 +764,11 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc, | |||
726 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 764 | static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) |
727 | { | 765 | { |
728 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); | 766 | struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq); |
729 | u32 status = readl(nmk_chip->addr + NMK_GPIO_IS); | 767 | u32 status; |
768 | |||
769 | clk_enable(nmk_chip->clk); | ||
770 | status = readl(nmk_chip->addr + NMK_GPIO_IS); | ||
771 | clk_disable(nmk_chip->clk); | ||
730 | 772 | ||
731 | __nmk_gpio_irq_handler(irq, desc, status); | 773 | __nmk_gpio_irq_handler(irq, desc, status); |
732 | } | 774 | } |
@@ -772,7 +814,12 @@ static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset) | |||
772 | struct nmk_gpio_chip *nmk_chip = | 814 | struct nmk_gpio_chip *nmk_chip = |
773 | container_of(chip, struct nmk_gpio_chip, chip); | 815 | container_of(chip, struct nmk_gpio_chip, chip); |
774 | 816 | ||
817 | clk_enable(nmk_chip->clk); | ||
818 | |||
775 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | 819 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); |
820 | |||
821 | clk_disable(nmk_chip->clk); | ||
822 | |||
776 | return 0; | 823 | return 0; |
777 | } | 824 | } |
778 | 825 | ||
@@ -781,8 +828,15 @@ static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset) | |||
781 | struct nmk_gpio_chip *nmk_chip = | 828 | struct nmk_gpio_chip *nmk_chip = |
782 | container_of(chip, struct nmk_gpio_chip, chip); | 829 | container_of(chip, struct nmk_gpio_chip, chip); |
783 | u32 bit = 1 << offset; | 830 | u32 bit = 1 << offset; |
831 | int value; | ||
832 | |||
833 | clk_enable(nmk_chip->clk); | ||
784 | 834 | ||
785 | return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0; | 835 | value = (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0; |
836 | |||
837 | clk_disable(nmk_chip->clk); | ||
838 | |||
839 | return value; | ||
786 | } | 840 | } |
787 | 841 | ||
788 | static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | 842 | static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, |
@@ -791,7 +845,11 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | |||
791 | struct nmk_gpio_chip *nmk_chip = | 845 | struct nmk_gpio_chip *nmk_chip = |
792 | container_of(chip, struct nmk_gpio_chip, chip); | 846 | container_of(chip, struct nmk_gpio_chip, chip); |
793 | 847 | ||
848 | clk_enable(nmk_chip->clk); | ||
849 | |||
794 | __nmk_gpio_set_output(nmk_chip, offset, val); | 850 | __nmk_gpio_set_output(nmk_chip, offset, val); |
851 | |||
852 | clk_disable(nmk_chip->clk); | ||
795 | } | 853 | } |
796 | 854 | ||
797 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | 855 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, |
@@ -800,8 +858,12 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | |||
800 | struct nmk_gpio_chip *nmk_chip = | 858 | struct nmk_gpio_chip *nmk_chip = |
801 | container_of(chip, struct nmk_gpio_chip, chip); | 859 | container_of(chip, struct nmk_gpio_chip, chip); |
802 | 860 | ||
861 | clk_enable(nmk_chip->clk); | ||
862 | |||
803 | __nmk_gpio_make_output(nmk_chip, offset, val); | 863 | __nmk_gpio_make_output(nmk_chip, offset, val); |
804 | 864 | ||
865 | clk_disable(nmk_chip->clk); | ||
866 | |||
805 | return 0; | 867 | return 0; |
806 | } | 868 | } |
807 | 869 | ||
@@ -832,6 +894,8 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
832 | [NMK_GPIO_ALT_C] = "altC", | 894 | [NMK_GPIO_ALT_C] = "altC", |
833 | }; | 895 | }; |
834 | 896 | ||
897 | clk_enable(nmk_chip->clk); | ||
898 | |||
835 | for (i = 0; i < chip->ngpio; i++, gpio++) { | 899 | for (i = 0; i < chip->ngpio; i++, gpio++) { |
836 | const char *label = gpiochip_is_requested(chip, i); | 900 | const char *label = gpiochip_is_requested(chip, i); |
837 | bool pull; | 901 | bool pull; |
@@ -876,6 +940,8 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
876 | 940 | ||
877 | seq_printf(s, "\n"); | 941 | seq_printf(s, "\n"); |
878 | } | 942 | } |
943 | |||
944 | clk_disable(nmk_chip->clk); | ||
879 | } | 945 | } |
880 | 946 | ||
881 | #else | 947 | #else |
@@ -893,6 +959,34 @@ static struct gpio_chip nmk_gpio_template = { | |||
893 | .can_sleep = 0, | 959 | .can_sleep = 0, |
894 | }; | 960 | }; |
895 | 961 | ||
962 | void nmk_gpio_clocks_enable(void) | ||
963 | { | ||
964 | int i; | ||
965 | |||
966 | for (i = 0; i < NUM_BANKS; i++) { | ||
967 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
968 | |||
969 | if (!chip) | ||
970 | continue; | ||
971 | |||
972 | clk_enable(chip->clk); | ||
973 | } | ||
974 | } | ||
975 | |||
976 | void nmk_gpio_clocks_disable(void) | ||
977 | { | ||
978 | int i; | ||
979 | |||
980 | for (i = 0; i < NUM_BANKS; i++) { | ||
981 | struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; | ||
982 | |||
983 | if (!chip) | ||
984 | continue; | ||
985 | |||
986 | clk_disable(chip->clk); | ||
987 | } | ||
988 | } | ||
989 | |||
896 | /* | 990 | /* |
897 | * Called from the suspend/resume path to only keep the real wakeup interrupts | 991 | * Called from the suspend/resume path to only keep the real wakeup interrupts |
898 | * (those that have had set_irq_wake() called on them) as wakeup interrupts, | 992 | * (those that have had set_irq_wake() called on them) as wakeup interrupts, |
@@ -912,6 +1006,8 @@ void nmk_gpio_wakeups_suspend(void) | |||
912 | if (!chip) | 1006 | if (!chip) |
913 | break; | 1007 | break; |
914 | 1008 | ||
1009 | clk_enable(chip->clk); | ||
1010 | |||
915 | chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC); | 1011 | chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC); |
916 | chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC); | 1012 | chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC); |
917 | 1013 | ||
@@ -926,6 +1022,8 @@ void nmk_gpio_wakeups_suspend(void) | |||
926 | /* 0 -> wakeup enable */ | 1022 | /* 0 -> wakeup enable */ |
927 | writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC); | 1023 | writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC); |
928 | } | 1024 | } |
1025 | |||
1026 | clk_disable(chip->clk); | ||
929 | } | 1027 | } |
930 | } | 1028 | } |
931 | 1029 | ||
@@ -939,11 +1037,15 @@ void nmk_gpio_wakeups_resume(void) | |||
939 | if (!chip) | 1037 | if (!chip) |
940 | break; | 1038 | break; |
941 | 1039 | ||
1040 | clk_enable(chip->clk); | ||
1041 | |||
942 | writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC); | 1042 | writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC); |
943 | writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC); | 1043 | writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC); |
944 | 1044 | ||
945 | if (chip->sleepmode) | 1045 | if (chip->sleepmode) |
946 | writel(chip->slpm, chip->addr + NMK_GPIO_SLPC); | 1046 | writel(chip->slpm, chip->addr + NMK_GPIO_SLPC); |
1047 | |||
1048 | clk_disable(chip->clk); | ||
947 | } | 1049 | } |
948 | } | 1050 | } |
949 | 1051 | ||
@@ -1010,8 +1112,6 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
1010 | goto out_release; | 1112 | goto out_release; |
1011 | } | 1113 | } |
1012 | 1114 | ||
1013 | clk_enable(clk); | ||
1014 | |||
1015 | nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); | 1115 | nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL); |
1016 | if (!nmk_chip) { | 1116 | if (!nmk_chip) { |
1017 | ret = -ENOMEM; | 1117 | ret = -ENOMEM; |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0599854e2217..0b0562979171 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <mach/irqs.h> | 27 | #include <mach/irqs.h> |
28 | #include <mach/gpio.h> | 28 | #include <asm/gpio.h> |
29 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
30 | 30 | ||
31 | struct gpio_bank { | 31 | struct gpio_bank { |
@@ -34,8 +34,8 @@ struct gpio_bank { | |||
34 | u16 irq; | 34 | u16 irq; |
35 | u16 virtual_irq_start; | 35 | u16 virtual_irq_start; |
36 | int method; | 36 | int method; |
37 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) | ||
38 | u32 suspend_wakeup; | 37 | u32 suspend_wakeup; |
38 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS) | ||
39 | u32 saved_wakeup; | 39 | u32 saved_wakeup; |
40 | #endif | 40 | #endif |
41 | u32 non_wakeup_gpios; | 41 | u32 non_wakeup_gpios; |
@@ -148,13 +148,17 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) | |||
148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; | 148 | return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | #define MOD_REG_BIT(reg, bit_mask, set) \ | 151 | static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) |
152 | do { \ | 152 | { |
153 | int l = __raw_readl(base + reg); \ | 153 | int l = __raw_readl(base + reg); |
154 | if (set) l |= bit_mask; \ | 154 | |
155 | else l &= ~bit_mask; \ | 155 | if (set) |
156 | __raw_writel(l, base + reg); \ | 156 | l |= mask; |
157 | } while(0) | 157 | else |
158 | l &= ~mask; | ||
159 | |||
160 | __raw_writel(l, base + reg); | ||
161 | } | ||
158 | 162 | ||
159 | /** | 163 | /** |
160 | * _set_gpio_debounce - low level gpio debounce time | 164 | * _set_gpio_debounce - low level gpio debounce time |
@@ -210,28 +214,28 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
210 | u32 gpio_bit = 1 << gpio; | 214 | u32 gpio_bit = 1 << gpio; |
211 | 215 | ||
212 | if (cpu_is_omap44xx()) { | 216 | if (cpu_is_omap44xx()) { |
213 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, | 217 | _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit, |
214 | trigger & IRQ_TYPE_LEVEL_LOW); | 218 | trigger & IRQ_TYPE_LEVEL_LOW); |
215 | MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, | 219 | _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit, |
216 | trigger & IRQ_TYPE_LEVEL_HIGH); | 220 | trigger & IRQ_TYPE_LEVEL_HIGH); |
217 | MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, | 221 | _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit, |
218 | trigger & IRQ_TYPE_EDGE_RISING); | 222 | trigger & IRQ_TYPE_EDGE_RISING); |
219 | MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, | 223 | _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit, |
220 | trigger & IRQ_TYPE_EDGE_FALLING); | 224 | trigger & IRQ_TYPE_EDGE_FALLING); |
221 | } else { | 225 | } else { |
222 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, | 226 | _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, |
223 | trigger & IRQ_TYPE_LEVEL_LOW); | 227 | trigger & IRQ_TYPE_LEVEL_LOW); |
224 | MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, | 228 | _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, |
225 | trigger & IRQ_TYPE_LEVEL_HIGH); | 229 | trigger & IRQ_TYPE_LEVEL_HIGH); |
226 | MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, | 230 | _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit, |
227 | trigger & IRQ_TYPE_EDGE_RISING); | 231 | trigger & IRQ_TYPE_EDGE_RISING); |
228 | MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, | 232 | _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, |
229 | trigger & IRQ_TYPE_EDGE_FALLING); | 233 | trigger & IRQ_TYPE_EDGE_FALLING); |
230 | } | 234 | } |
231 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { | 235 | if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { |
232 | if (cpu_is_omap44xx()) { | 236 | if (cpu_is_omap44xx()) { |
233 | MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit, | 237 | _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit, |
234 | trigger != 0); | 238 | trigger != 0); |
235 | } else { | 239 | } else { |
236 | /* | 240 | /* |
237 | * GPIO wakeup request can only be generated on edge | 241 | * GPIO wakeup request can only be generated on edge |
@@ -1086,6 +1090,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, | |||
1086 | 1090 | ||
1087 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, | 1091 | gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, |
1088 | handle_simple_irq); | 1092 | handle_simple_irq); |
1093 | if (!gc) { | ||
1094 | dev_err(bank->dev, "Memory alloc failed for gc\n"); | ||
1095 | return; | ||
1096 | } | ||
1097 | |||
1089 | ct = gc->chip_types; | 1098 | ct = gc->chip_types; |
1090 | 1099 | ||
1091 | /* NOTE: No ack required, reading IRQ status clears it. */ | 1100 | /* NOTE: No ack required, reading IRQ status clears it. */ |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index c43b8ff626a7..147df8ae79db 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
@@ -577,6 +577,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | |||
577 | void | 577 | void |
578 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) | 578 | pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert) |
579 | { | 579 | { |
580 | *gpio_base = -1; | ||
580 | } | 581 | } |
581 | #endif | 582 | #endif |
582 | 583 | ||
@@ -595,9 +596,6 @@ static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) | |||
595 | 596 | ||
596 | /* set platform specific polarity inversion */ | 597 | /* set platform specific polarity inversion */ |
597 | ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); | 598 | ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); |
598 | if (ret) | ||
599 | goto out; | ||
600 | return 0; | ||
601 | out: | 599 | out: |
602 | return ret; | 600 | return ret; |
603 | } | 601 | } |
@@ -639,7 +637,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
639 | struct pca953x_platform_data *pdata; | 637 | struct pca953x_platform_data *pdata; |
640 | struct pca953x_chip *chip; | 638 | struct pca953x_chip *chip; |
641 | int irq_base=0, invert=0; | 639 | int irq_base=0, invert=0; |
642 | int ret = 0; | 640 | int ret; |
643 | 641 | ||
644 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 642 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
645 | if (chip == NULL) | 643 | if (chip == NULL) |
@@ -672,10 +670,10 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
672 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); | 670 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); |
673 | 671 | ||
674 | if (chip->chip_type == PCA953X_TYPE) | 672 | if (chip->chip_type == PCA953X_TYPE) |
675 | device_pca953x_init(chip, invert); | 673 | ret = device_pca953x_init(chip, invert); |
676 | else if (chip->chip_type == PCA957X_TYPE) | ||
677 | device_pca957x_init(chip, invert); | ||
678 | else | 674 | else |
675 | ret = device_pca957x_init(chip, invert); | ||
676 | if (ret) | ||
679 | goto out_failed; | 677 | goto out_failed; |
680 | 678 | ||
681 | ret = pca953x_irq_setup(chip, id, irq_base); | 679 | ret = pca953x_irq_setup(chip, id, irq_base); |
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 7369fdda92b0..3e1f1ecd07be 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/i2c/pcf857x.h> | 25 | #include <linux/i2c/pcf857x.h> |
26 | #include <linux/module.h> | ||
26 | 27 | ||
27 | 28 | ||
28 | static const struct i2c_device_id pcf857x_id[] = { | 29 | static const struct i2c_device_id pcf857x_id[] = { |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 36919e77c495..a6008e123d04 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
@@ -14,12 +14,21 @@ | |||
14 | * along with this program; if not, write to the Free Software | 14 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
16 | */ | 16 | */ |
17 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
18 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
19 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/irq.h> | ||
20 | 23 | ||
21 | #define PCH_GPIO_ALL_PINS 0xfff /* Mask for GPIO pins 0 to 11 */ | 24 | #define PCH_EDGE_FALLING 0 |
22 | #define GPIO_NUM_PINS 12 /* Specifies number of GPIO PINS GPIO0-GPIO11 */ | 25 | #define PCH_EDGE_RISING BIT(0) |
26 | #define PCH_LEVEL_L BIT(1) | ||
27 | #define PCH_LEVEL_H (BIT(0) | BIT(1)) | ||
28 | #define PCH_EDGE_BOTH BIT(2) | ||
29 | #define PCH_IM_MASK (BIT(0) | BIT(1) | BIT(2)) | ||
30 | |||
31 | #define PCH_IRQ_BASE 24 | ||
23 | 32 | ||
24 | struct pch_regs { | 33 | struct pch_regs { |
25 | u32 ien; | 34 | u32 ien; |
@@ -33,18 +42,43 @@ struct pch_regs { | |||
33 | u32 pm; | 42 | u32 pm; |
34 | u32 im0; | 43 | u32 im0; |
35 | u32 im1; | 44 | u32 im1; |
36 | u32 reserved[4]; | 45 | u32 reserved[3]; |
46 | u32 gpio_use_sel; | ||
37 | u32 reset; | 47 | u32 reset; |
38 | }; | 48 | }; |
39 | 49 | ||
50 | enum pch_type_t { | ||
51 | INTEL_EG20T_PCH, | ||
52 | OKISEMI_ML7223m_IOH, /* OKISEMI ML7223 IOH PCIe Bus-m */ | ||
53 | OKISEMI_ML7223n_IOH /* OKISEMI ML7223 IOH PCIe Bus-n */ | ||
54 | }; | ||
55 | |||
56 | /* Specifies number of GPIO PINS */ | ||
57 | static int gpio_pins[] = { | ||
58 | [INTEL_EG20T_PCH] = 12, | ||
59 | [OKISEMI_ML7223m_IOH] = 8, | ||
60 | [OKISEMI_ML7223n_IOH] = 8, | ||
61 | }; | ||
62 | |||
40 | /** | 63 | /** |
41 | * struct pch_gpio_reg_data - The register store data. | 64 | * struct pch_gpio_reg_data - The register store data. |
65 | * @ien_reg: To store contents of IEN register. | ||
66 | * @imask_reg: To store contents of IMASK register. | ||
42 | * @po_reg: To store contents of PO register. | 67 | * @po_reg: To store contents of PO register. |
43 | * @pm_reg: To store contents of PM register. | 68 | * @pm_reg: To store contents of PM register. |
69 | * @im0_reg: To store contents of IM0 register. | ||
70 | * @im1_reg: To store contents of IM1 register. | ||
71 | * @gpio_use_sel_reg : To store contents of GPIO_USE_SEL register. | ||
72 | * (Only ML7223 Bus-n) | ||
44 | */ | 73 | */ |
45 | struct pch_gpio_reg_data { | 74 | struct pch_gpio_reg_data { |
75 | u32 ien_reg; | ||
76 | u32 imask_reg; | ||
46 | u32 po_reg; | 77 | u32 po_reg; |
47 | u32 pm_reg; | 78 | u32 pm_reg; |
79 | u32 im0_reg; | ||
80 | u32 im1_reg; | ||
81 | u32 gpio_use_sel_reg; | ||
48 | }; | 82 | }; |
49 | 83 | ||
50 | /** | 84 | /** |
@@ -55,6 +89,12 @@ struct pch_gpio_reg_data { | |||
55 | * @gpio: Data for GPIO infrastructure. | 89 | * @gpio: Data for GPIO infrastructure. |
56 | * @pch_gpio_reg: Memory mapped Register data is saved here | 90 | * @pch_gpio_reg: Memory mapped Register data is saved here |
57 | * when suspend. | 91 | * when suspend. |
92 | * @lock: Used for register access protection | ||
93 | * @irq_base: Save base of IRQ number for interrupt | ||
94 | * @ioh: IOH ID | ||
95 | * @spinlock: Used for register access protection in | ||
96 | * interrupt context pch_irq_mask, | ||
97 | * pch_irq_unmask and pch_irq_type; | ||
58 | */ | 98 | */ |
59 | struct pch_gpio { | 99 | struct pch_gpio { |
60 | void __iomem *base; | 100 | void __iomem *base; |
@@ -63,6 +103,9 @@ struct pch_gpio { | |||
63 | struct gpio_chip gpio; | 103 | struct gpio_chip gpio; |
64 | struct pch_gpio_reg_data pch_gpio_reg; | 104 | struct pch_gpio_reg_data pch_gpio_reg; |
65 | struct mutex lock; | 105 | struct mutex lock; |
106 | int irq_base; | ||
107 | enum pch_type_t ioh; | ||
108 | spinlock_t spinlock; | ||
66 | }; | 109 | }; |
67 | 110 | ||
68 | static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) | 111 | static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) |
@@ -96,7 +139,7 @@ static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | |||
96 | u32 reg_val; | 139 | u32 reg_val; |
97 | 140 | ||
98 | mutex_lock(&chip->lock); | 141 | mutex_lock(&chip->lock); |
99 | pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; | 142 | pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1); |
100 | pm |= (1 << nr); | 143 | pm |= (1 << nr); |
101 | iowrite32(pm, &chip->reg->pm); | 144 | iowrite32(pm, &chip->reg->pm); |
102 | 145 | ||
@@ -118,7 +161,7 @@ static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | |||
118 | u32 pm; | 161 | u32 pm; |
119 | 162 | ||
120 | mutex_lock(&chip->lock); | 163 | mutex_lock(&chip->lock); |
121 | pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; /*bits 0-11*/ | 164 | pm = ioread32(&chip->reg->pm) & ((1 << gpio_pins[chip->ioh]) - 1); |
122 | pm &= ~(1 << nr); | 165 | pm &= ~(1 << nr); |
123 | iowrite32(pm, &chip->reg->pm); | 166 | iowrite32(pm, &chip->reg->pm); |
124 | mutex_unlock(&chip->lock); | 167 | mutex_unlock(&chip->lock); |
@@ -131,8 +174,16 @@ static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | |||
131 | */ | 174 | */ |
132 | static void pch_gpio_save_reg_conf(struct pch_gpio *chip) | 175 | static void pch_gpio_save_reg_conf(struct pch_gpio *chip) |
133 | { | 176 | { |
177 | chip->pch_gpio_reg.ien_reg = ioread32(&chip->reg->ien); | ||
178 | chip->pch_gpio_reg.imask_reg = ioread32(&chip->reg->imask); | ||
134 | chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po); | 179 | chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po); |
135 | chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm); | 180 | chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm); |
181 | chip->pch_gpio_reg.im0_reg = ioread32(&chip->reg->im0); | ||
182 | if (chip->ioh == INTEL_EG20T_PCH) | ||
183 | chip->pch_gpio_reg.im1_reg = ioread32(&chip->reg->im1); | ||
184 | if (chip->ioh == OKISEMI_ML7223n_IOH) | ||
185 | chip->pch_gpio_reg.gpio_use_sel_reg =\ | ||
186 | ioread32(&chip->reg->gpio_use_sel); | ||
136 | } | 187 | } |
137 | 188 | ||
138 | /* | 189 | /* |
@@ -140,10 +191,24 @@ static void pch_gpio_save_reg_conf(struct pch_gpio *chip) | |||
140 | */ | 191 | */ |
141 | static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) | 192 | static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) |
142 | { | 193 | { |
194 | iowrite32(chip->pch_gpio_reg.ien_reg, &chip->reg->ien); | ||
195 | iowrite32(chip->pch_gpio_reg.imask_reg, &chip->reg->imask); | ||
143 | /* to store contents of PO register */ | 196 | /* to store contents of PO register */ |
144 | iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po); | 197 | iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po); |
145 | /* to store contents of PM register */ | 198 | /* to store contents of PM register */ |
146 | iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm); | 199 | iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm); |
200 | iowrite32(chip->pch_gpio_reg.im0_reg, &chip->reg->im0); | ||
201 | if (chip->ioh == INTEL_EG20T_PCH) | ||
202 | iowrite32(chip->pch_gpio_reg.im1_reg, &chip->reg->im1); | ||
203 | if (chip->ioh == OKISEMI_ML7223n_IOH) | ||
204 | iowrite32(chip->pch_gpio_reg.gpio_use_sel_reg, | ||
205 | &chip->reg->gpio_use_sel); | ||
206 | } | ||
207 | |||
208 | static int pch_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) | ||
209 | { | ||
210 | struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); | ||
211 | return chip->irq_base + offset; | ||
147 | } | 212 | } |
148 | 213 | ||
149 | static void pch_gpio_setup(struct pch_gpio *chip) | 214 | static void pch_gpio_setup(struct pch_gpio *chip) |
@@ -158,8 +223,132 @@ static void pch_gpio_setup(struct pch_gpio *chip) | |||
158 | gpio->set = pch_gpio_set; | 223 | gpio->set = pch_gpio_set; |
159 | gpio->dbg_show = NULL; | 224 | gpio->dbg_show = NULL; |
160 | gpio->base = -1; | 225 | gpio->base = -1; |
161 | gpio->ngpio = GPIO_NUM_PINS; | 226 | gpio->ngpio = gpio_pins[chip->ioh]; |
162 | gpio->can_sleep = 0; | 227 | gpio->can_sleep = 0; |
228 | gpio->to_irq = pch_gpio_to_irq; | ||
229 | } | ||
230 | |||
231 | static int pch_irq_type(struct irq_data *d, unsigned int type) | ||
232 | { | ||
233 | u32 im; | ||
234 | u32 *im_reg; | ||
235 | u32 ien; | ||
236 | u32 im_pos; | ||
237 | int ch; | ||
238 | unsigned long flags; | ||
239 | u32 val; | ||
240 | int irq = d->irq; | ||
241 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
242 | struct pch_gpio *chip = gc->private; | ||
243 | |||
244 | ch = irq - chip->irq_base; | ||
245 | if (irq <= chip->irq_base + 7) { | ||
246 | im_reg = &chip->reg->im0; | ||
247 | im_pos = ch; | ||
248 | } else { | ||
249 | im_reg = &chip->reg->im1; | ||
250 | im_pos = ch - 8; | ||
251 | } | ||
252 | dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d\n", | ||
253 | __func__, irq, type, ch, im_pos); | ||
254 | |||
255 | spin_lock_irqsave(&chip->spinlock, flags); | ||
256 | |||
257 | switch (type) { | ||
258 | case IRQ_TYPE_EDGE_RISING: | ||
259 | val = PCH_EDGE_RISING; | ||
260 | break; | ||
261 | case IRQ_TYPE_EDGE_FALLING: | ||
262 | val = PCH_EDGE_FALLING; | ||
263 | break; | ||
264 | case IRQ_TYPE_EDGE_BOTH: | ||
265 | val = PCH_EDGE_BOTH; | ||
266 | break; | ||
267 | case IRQ_TYPE_LEVEL_HIGH: | ||
268 | val = PCH_LEVEL_H; | ||
269 | break; | ||
270 | case IRQ_TYPE_LEVEL_LOW: | ||
271 | val = PCH_LEVEL_L; | ||
272 | break; | ||
273 | case IRQ_TYPE_PROBE: | ||
274 | goto end; | ||
275 | default: | ||
276 | dev_warn(chip->dev, "%s: unknown type(%dd)", | ||
277 | __func__, type); | ||
278 | goto end; | ||
279 | } | ||
280 | |||
281 | /* Set interrupt mode */ | ||
282 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); | ||
283 | iowrite32(im | (val << (im_pos * 4)), im_reg); | ||
284 | |||
285 | /* iclr */ | ||
286 | iowrite32(BIT(ch), &chip->reg->iclr); | ||
287 | |||
288 | /* IMASKCLR */ | ||
289 | iowrite32(BIT(ch), &chip->reg->imaskclr); | ||
290 | |||
291 | /* Enable interrupt */ | ||
292 | ien = ioread32(&chip->reg->ien); | ||
293 | iowrite32(ien | BIT(ch), &chip->reg->ien); | ||
294 | end: | ||
295 | spin_unlock_irqrestore(&chip->spinlock, flags); | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static void pch_irq_unmask(struct irq_data *d) | ||
301 | { | ||
302 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
303 | struct pch_gpio *chip = gc->private; | ||
304 | |||
305 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imaskclr); | ||
306 | } | ||
307 | |||
308 | static void pch_irq_mask(struct irq_data *d) | ||
309 | { | ||
310 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
311 | struct pch_gpio *chip = gc->private; | ||
312 | |||
313 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); | ||
314 | } | ||
315 | |||
316 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) | ||
317 | { | ||
318 | struct pch_gpio *chip = dev_id; | ||
319 | u32 reg_val = ioread32(&chip->reg->istatus); | ||
320 | int i; | ||
321 | int ret = IRQ_NONE; | ||
322 | |||
323 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { | ||
324 | if (reg_val & BIT(i)) { | ||
325 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", | ||
326 | __func__, i, irq, reg_val); | ||
327 | iowrite32(BIT(i), &chip->reg->iclr); | ||
328 | generic_handle_irq(chip->irq_base + i); | ||
329 | ret = IRQ_HANDLED; | ||
330 | } | ||
331 | } | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, | ||
336 | unsigned int irq_start, unsigned int num) | ||
337 | { | ||
338 | struct irq_chip_generic *gc; | ||
339 | struct irq_chip_type *ct; | ||
340 | |||
341 | gc = irq_alloc_generic_chip("pch_gpio", 1, irq_start, chip->base, | ||
342 | handle_simple_irq); | ||
343 | gc->private = chip; | ||
344 | ct = gc->chip_types; | ||
345 | |||
346 | ct->chip.irq_mask = pch_irq_mask; | ||
347 | ct->chip.irq_unmask = pch_irq_unmask; | ||
348 | ct->chip.irq_set_type = pch_irq_type; | ||
349 | |||
350 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | ||
351 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
163 | } | 352 | } |
164 | 353 | ||
165 | static int __devinit pch_gpio_probe(struct pci_dev *pdev, | 354 | static int __devinit pch_gpio_probe(struct pci_dev *pdev, |
@@ -167,6 +356,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
167 | { | 356 | { |
168 | s32 ret; | 357 | s32 ret; |
169 | struct pch_gpio *chip; | 358 | struct pch_gpio *chip; |
359 | int irq_base; | ||
170 | 360 | ||
171 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 361 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
172 | if (chip == NULL) | 362 | if (chip == NULL) |
@@ -192,6 +382,13 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
192 | goto err_iomap; | 382 | goto err_iomap; |
193 | } | 383 | } |
194 | 384 | ||
385 | if (pdev->device == 0x8803) | ||
386 | chip->ioh = INTEL_EG20T_PCH; | ||
387 | else if (pdev->device == 0x8014) | ||
388 | chip->ioh = OKISEMI_ML7223m_IOH; | ||
389 | else if (pdev->device == 0x8043) | ||
390 | chip->ioh = OKISEMI_ML7223n_IOH; | ||
391 | |||
195 | chip->reg = chip->base; | 392 | chip->reg = chip->base; |
196 | pci_set_drvdata(pdev, chip); | 393 | pci_set_drvdata(pdev, chip); |
197 | mutex_init(&chip->lock); | 394 | mutex_init(&chip->lock); |
@@ -202,8 +399,36 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
202 | goto err_gpiochip_add; | 399 | goto err_gpiochip_add; |
203 | } | 400 | } |
204 | 401 | ||
402 | irq_base = irq_alloc_descs(-1, 0, gpio_pins[chip->ioh], NUMA_NO_NODE); | ||
403 | if (irq_base < 0) { | ||
404 | dev_warn(&pdev->dev, "PCH gpio: Failed to get IRQ base num\n"); | ||
405 | chip->irq_base = -1; | ||
406 | goto end; | ||
407 | } | ||
408 | chip->irq_base = irq_base; | ||
409 | |||
410 | ret = request_irq(pdev->irq, pch_gpio_handler, | ||
411 | IRQF_SHARED, KBUILD_MODNAME, chip); | ||
412 | if (ret != 0) { | ||
413 | dev_err(&pdev->dev, | ||
414 | "%s request_irq failed\n", __func__); | ||
415 | goto err_request_irq; | ||
416 | } | ||
417 | |||
418 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); | ||
419 | |||
420 | /* Initialize interrupt ien register */ | ||
421 | iowrite32(0, &chip->reg->ien); | ||
422 | end: | ||
205 | return 0; | 423 | return 0; |
206 | 424 | ||
425 | err_request_irq: | ||
426 | irq_free_descs(irq_base, gpio_pins[chip->ioh]); | ||
427 | |||
428 | ret = gpiochip_remove(&chip->gpio); | ||
429 | if (ret) | ||
430 | dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__); | ||
431 | |||
207 | err_gpiochip_add: | 432 | err_gpiochip_add: |
208 | pci_iounmap(pdev, chip->base); | 433 | pci_iounmap(pdev, chip->base); |
209 | 434 | ||
@@ -224,6 +449,12 @@ static void __devexit pch_gpio_remove(struct pci_dev *pdev) | |||
224 | int err; | 449 | int err; |
225 | struct pch_gpio *chip = pci_get_drvdata(pdev); | 450 | struct pch_gpio *chip = pci_get_drvdata(pdev); |
226 | 451 | ||
452 | if (chip->irq_base != -1) { | ||
453 | free_irq(pdev->irq, chip); | ||
454 | |||
455 | irq_free_descs(chip->irq_base, gpio_pins[chip->ioh]); | ||
456 | } | ||
457 | |||
227 | err = gpiochip_remove(&chip->gpio); | 458 | err = gpiochip_remove(&chip->gpio); |
228 | if (err) | 459 | if (err) |
229 | dev_err(&pdev->dev, "Failed gpiochip_remove\n"); | 460 | dev_err(&pdev->dev, "Failed gpiochip_remove\n"); |
@@ -239,9 +470,11 @@ static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state) | |||
239 | { | 470 | { |
240 | s32 ret; | 471 | s32 ret; |
241 | struct pch_gpio *chip = pci_get_drvdata(pdev); | 472 | struct pch_gpio *chip = pci_get_drvdata(pdev); |
473 | unsigned long flags; | ||
242 | 474 | ||
475 | spin_lock_irqsave(&chip->spinlock, flags); | ||
243 | pch_gpio_save_reg_conf(chip); | 476 | pch_gpio_save_reg_conf(chip); |
244 | pch_gpio_restore_reg_conf(chip); | 477 | spin_unlock_irqrestore(&chip->spinlock, flags); |
245 | 478 | ||
246 | ret = pci_save_state(pdev); | 479 | ret = pci_save_state(pdev); |
247 | if (ret) { | 480 | if (ret) { |
@@ -261,6 +494,7 @@ static int pch_gpio_resume(struct pci_dev *pdev) | |||
261 | { | 494 | { |
262 | s32 ret; | 495 | s32 ret; |
263 | struct pch_gpio *chip = pci_get_drvdata(pdev); | 496 | struct pch_gpio *chip = pci_get_drvdata(pdev); |
497 | unsigned long flags; | ||
264 | 498 | ||
265 | ret = pci_enable_wake(pdev, PCI_D0, 0); | 499 | ret = pci_enable_wake(pdev, PCI_D0, 0); |
266 | 500 | ||
@@ -272,9 +506,11 @@ static int pch_gpio_resume(struct pci_dev *pdev) | |||
272 | } | 506 | } |
273 | pci_restore_state(pdev); | 507 | pci_restore_state(pdev); |
274 | 508 | ||
509 | spin_lock_irqsave(&chip->spinlock, flags); | ||
275 | iowrite32(0x01, &chip->reg->reset); | 510 | iowrite32(0x01, &chip->reg->reset); |
276 | iowrite32(0x00, &chip->reg->reset); | 511 | iowrite32(0x00, &chip->reg->reset); |
277 | pch_gpio_restore_reg_conf(chip); | 512 | pch_gpio_restore_reg_conf(chip); |
513 | spin_unlock_irqrestore(&chip->spinlock, flags); | ||
278 | 514 | ||
279 | return 0; | 515 | return 0; |
280 | } | 516 | } |
@@ -287,6 +523,7 @@ static int pch_gpio_resume(struct pci_dev *pdev) | |||
287 | static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { | 523 | static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { |
288 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, | 524 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, |
289 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, | 525 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) }, |
526 | { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8043) }, | ||
290 | { 0, } | 527 | { 0, } |
291 | }; | 528 | }; |
292 | MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); | 529 | MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id); |
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 2c5a18f32bf3..093c90bd3c1d 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c | |||
@@ -118,7 +118,7 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset) | |||
118 | { | 118 | { |
119 | struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); | 119 | struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); |
120 | 120 | ||
121 | if (chip->irq_base == (unsigned) -1) | 121 | if (chip->irq_base == NO_IRQ) |
122 | return -EINVAL; | 122 | return -EINVAL; |
123 | 123 | ||
124 | return chip->irq_base + offset; | 124 | return chip->irq_base + offset; |
@@ -246,6 +246,18 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
246 | if (chip == NULL) | 246 | if (chip == NULL) |
247 | return -ENOMEM; | 247 | return -ENOMEM; |
248 | 248 | ||
249 | pdata = dev->dev.platform_data; | ||
250 | if (pdata) { | ||
251 | chip->gc.base = pdata->gpio_base; | ||
252 | chip->irq_base = pdata->irq_base; | ||
253 | } else if (dev->dev.of_node) { | ||
254 | chip->gc.base = -1; | ||
255 | chip->irq_base = NO_IRQ; | ||
256 | } else { | ||
257 | ret = -ENODEV; | ||
258 | goto free_mem; | ||
259 | } | ||
260 | |||
249 | if (!request_mem_region(dev->res.start, | 261 | if (!request_mem_region(dev->res.start, |
250 | resource_size(&dev->res), "pl061")) { | 262 | resource_size(&dev->res), "pl061")) { |
251 | ret = -EBUSY; | 263 | ret = -EBUSY; |
@@ -267,14 +279,11 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
267 | chip->gc.get = pl061_get_value; | 279 | chip->gc.get = pl061_get_value; |
268 | chip->gc.set = pl061_set_value; | 280 | chip->gc.set = pl061_set_value; |
269 | chip->gc.to_irq = pl061_to_irq; | 281 | chip->gc.to_irq = pl061_to_irq; |
270 | chip->gc.base = pdata->gpio_base; | ||
271 | chip->gc.ngpio = PL061_GPIO_NR; | 282 | chip->gc.ngpio = PL061_GPIO_NR; |
272 | chip->gc.label = dev_name(&dev->dev); | 283 | chip->gc.label = dev_name(&dev->dev); |
273 | chip->gc.dev = &dev->dev; | 284 | chip->gc.dev = &dev->dev; |
274 | chip->gc.owner = THIS_MODULE; | 285 | chip->gc.owner = THIS_MODULE; |
275 | 286 | ||
276 | chip->irq_base = pdata->irq_base; | ||
277 | |||
278 | ret = gpiochip_add(&chip->gc); | 287 | ret = gpiochip_add(&chip->gc); |
279 | if (ret) | 288 | if (ret) |
280 | goto iounmap; | 289 | goto iounmap; |
@@ -283,7 +292,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
283 | * irq_chip support | 292 | * irq_chip support |
284 | */ | 293 | */ |
285 | 294 | ||
286 | if (chip->irq_base == (unsigned) -1) | 295 | if (chip->irq_base == NO_IRQ) |
287 | return 0; | 296 | return 0; |
288 | 297 | ||
289 | writeb(0, chip->base + GPIOIE); /* disable irqs */ | 298 | writeb(0, chip->base + GPIOIE); /* disable irqs */ |
@@ -307,11 +316,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
307 | list_add(&chip->list, chip_list); | 316 | list_add(&chip->list, chip_list); |
308 | 317 | ||
309 | for (i = 0; i < PL061_GPIO_NR; i++) { | 318 | for (i = 0; i < PL061_GPIO_NR; i++) { |
310 | if (pdata->directions & (1 << i)) | 319 | if (pdata) { |
311 | pl061_direction_output(&chip->gc, i, | 320 | if (pdata->directions & (1 << i)) |
312 | pdata->values & (1 << i)); | 321 | pl061_direction_output(&chip->gc, i, |
313 | else | 322 | pdata->values & (1 << i)); |
314 | pl061_direction_input(&chip->gc, i); | 323 | else |
324 | pl061_direction_input(&chip->gc, i); | ||
325 | } | ||
315 | 326 | ||
316 | irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip, | 327 | irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip, |
317 | handle_simple_irq); | 328 | handle_simple_irq); |
diff --git a/drivers/gpio/gpio-plat-samsung.c b/drivers/gpio/gpio-plat-samsung.c deleted file mode 100644 index ef67f1952a72..000000000000 --- a/drivers/gpio/gpio-plat-samsung.c +++ /dev/null | |||
@@ -1,205 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Openmoko, Inc. | ||
3 | * Copyright 2008 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * http://armlinux.simtec.co.uk/ | ||
6 | * | ||
7 | * Copyright (c) 2009 Samsung Electronics Co., Ltd. | ||
8 | * http://www.samsung.com/ | ||
9 | * | ||
10 | * SAMSUNG - GPIOlib support | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <plat/gpio-core.h> | ||
22 | #include <plat/gpio-cfg.h> | ||
23 | #include <plat/gpio-cfg-helpers.h> | ||
24 | |||
25 | #ifndef DEBUG_GPIO | ||
26 | #define gpio_dbg(x...) do { } while (0) | ||
27 | #else | ||
28 | #define gpio_dbg(x...) printk(KERN_DEBUG x) | ||
29 | #endif | ||
30 | |||
31 | /* The samsung_gpiolib_4bit routines are to control the gpio banks where | ||
32 | * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the | ||
33 | * following example: | ||
34 | * | ||
35 | * base + 0x00: Control register, 4 bits per gpio | ||
36 | * gpio n: 4 bits starting at (4*n) | ||
37 | * 0000 = input, 0001 = output, others mean special-function | ||
38 | * base + 0x04: Data register, 1 bit per gpio | ||
39 | * bit n: data bit n | ||
40 | * | ||
41 | * Note, since the data register is one bit per gpio and is at base + 0x4 | ||
42 | * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of | ||
43 | * the output. | ||
44 | */ | ||
45 | |||
46 | static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, | ||
47 | unsigned int offset) | ||
48 | { | ||
49 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
50 | void __iomem *base = ourchip->base; | ||
51 | unsigned long con; | ||
52 | |||
53 | con = __raw_readl(base + GPIOCON_OFF); | ||
54 | con &= ~(0xf << con_4bit_shift(offset)); | ||
55 | __raw_writel(con, base + GPIOCON_OFF); | ||
56 | |||
57 | gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, | ||
63 | unsigned int offset, int value) | ||
64 | { | ||
65 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
66 | void __iomem *base = ourchip->base; | ||
67 | unsigned long con; | ||
68 | unsigned long dat; | ||
69 | |||
70 | con = __raw_readl(base + GPIOCON_OFF); | ||
71 | con &= ~(0xf << con_4bit_shift(offset)); | ||
72 | con |= 0x1 << con_4bit_shift(offset); | ||
73 | |||
74 | dat = __raw_readl(base + GPIODAT_OFF); | ||
75 | |||
76 | if (value) | ||
77 | dat |= 1 << offset; | ||
78 | else | ||
79 | dat &= ~(1 << offset); | ||
80 | |||
81 | __raw_writel(dat, base + GPIODAT_OFF); | ||
82 | __raw_writel(con, base + GPIOCON_OFF); | ||
83 | __raw_writel(dat, base + GPIODAT_OFF); | ||
84 | |||
85 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | /* The next set of routines are for the case where the GPIO configuration | ||
91 | * registers are 4 bits per GPIO but there is more than one register (the | ||
92 | * bank has more than 8 GPIOs. | ||
93 | * | ||
94 | * This case is the similar to the 4 bit case, but the registers are as | ||
95 | * follows: | ||
96 | * | ||
97 | * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) | ||
98 | * gpio n: 4 bits starting at (4*n) | ||
99 | * 0000 = input, 0001 = output, others mean special-function | ||
100 | * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) | ||
101 | * gpio n: 4 bits starting at (4*n) | ||
102 | * 0000 = input, 0001 = output, others mean special-function | ||
103 | * base + 0x08: Data register, 1 bit per gpio | ||
104 | * bit n: data bit n | ||
105 | * | ||
106 | * To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we | ||
107 | * store the 'base + 0x4' address so that these routines see the data | ||
108 | * register at ourchip->base + 0x04. | ||
109 | */ | ||
110 | |||
111 | static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, | ||
112 | unsigned int offset) | ||
113 | { | ||
114 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
115 | void __iomem *base = ourchip->base; | ||
116 | void __iomem *regcon = base; | ||
117 | unsigned long con; | ||
118 | |||
119 | if (offset > 7) | ||
120 | offset -= 8; | ||
121 | else | ||
122 | regcon -= 4; | ||
123 | |||
124 | con = __raw_readl(regcon); | ||
125 | con &= ~(0xf << con_4bit_shift(offset)); | ||
126 | __raw_writel(con, regcon); | ||
127 | |||
128 | gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, | ||
134 | unsigned int offset, int value) | ||
135 | { | ||
136 | struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip); | ||
137 | void __iomem *base = ourchip->base; | ||
138 | void __iomem *regcon = base; | ||
139 | unsigned long con; | ||
140 | unsigned long dat; | ||
141 | unsigned con_offset = offset; | ||
142 | |||
143 | if (con_offset > 7) | ||
144 | con_offset -= 8; | ||
145 | else | ||
146 | regcon -= 4; | ||
147 | |||
148 | con = __raw_readl(regcon); | ||
149 | con &= ~(0xf << con_4bit_shift(con_offset)); | ||
150 | con |= 0x1 << con_4bit_shift(con_offset); | ||
151 | |||
152 | dat = __raw_readl(base + GPIODAT_OFF); | ||
153 | |||
154 | if (value) | ||
155 | dat |= 1 << offset; | ||
156 | else | ||
157 | dat &= ~(1 << offset); | ||
158 | |||
159 | __raw_writel(dat, base + GPIODAT_OFF); | ||
160 | __raw_writel(con, regcon); | ||
161 | __raw_writel(dat, base + GPIODAT_OFF); | ||
162 | |||
163 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | void __init samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip) | ||
169 | { | ||
170 | chip->chip.direction_input = samsung_gpiolib_4bit_input; | ||
171 | chip->chip.direction_output = samsung_gpiolib_4bit_output; | ||
172 | chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); | ||
173 | } | ||
174 | |||
175 | void __init samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip) | ||
176 | { | ||
177 | chip->chip.direction_input = samsung_gpiolib_4bit2_input; | ||
178 | chip->chip.direction_output = samsung_gpiolib_4bit2_output; | ||
179 | chip->pm = __gpio_pm(&s3c_gpio_pm_4bit); | ||
180 | } | ||
181 | |||
182 | void __init samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip, | ||
183 | int nr_chips) | ||
184 | { | ||
185 | for (; nr_chips > 0; nr_chips--, chip++) { | ||
186 | samsung_gpiolib_add_4bit(chip); | ||
187 | s3c_gpiolib_add(chip); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | void __init samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, | ||
192 | int nr_chips) | ||
193 | { | ||
194 | for (; nr_chips > 0; nr_chips--, chip++) { | ||
195 | samsung_gpiolib_add_4bit2(chip); | ||
196 | s3c_gpiolib_add(chip); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip, | ||
201 | int nr_chips) | ||
202 | { | ||
203 | for (; nr_chips > 0; nr_chips--, chip++) | ||
204 | s3c_gpiolib_add(chip); | ||
205 | } | ||
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c new file mode 100644 index 000000000000..ee137712f9db --- /dev/null +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -0,0 +1,338 @@ | |||
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/init.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/syscore_ops.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <mach/gpio-pxa.h> | ||
22 | |||
23 | int pxa_last_gpio; | ||
24 | |||
25 | struct pxa_gpio_chip { | ||
26 | struct gpio_chip chip; | ||
27 | void __iomem *regbase; | ||
28 | char label[10]; | ||
29 | |||
30 | unsigned long irq_mask; | ||
31 | unsigned long irq_edge_rise; | ||
32 | unsigned long irq_edge_fall; | ||
33 | |||
34 | #ifdef CONFIG_PM | ||
35 | unsigned long saved_gplr; | ||
36 | unsigned long saved_gpdr; | ||
37 | unsigned long saved_grer; | ||
38 | unsigned long saved_gfer; | ||
39 | #endif | ||
40 | }; | ||
41 | |||
42 | static DEFINE_SPINLOCK(gpio_lock); | ||
43 | static struct pxa_gpio_chip *pxa_gpio_chips; | ||
44 | |||
45 | #define for_each_gpio_chip(i, c) \ | ||
46 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) | ||
47 | |||
48 | static inline void __iomem *gpio_chip_base(struct gpio_chip *c) | ||
49 | { | ||
50 | return container_of(c, struct pxa_gpio_chip, chip)->regbase; | ||
51 | } | ||
52 | |||
53 | static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) | ||
54 | { | ||
55 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; | ||
56 | } | ||
57 | |||
58 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
59 | { | ||
60 | void __iomem *base = gpio_chip_base(chip); | ||
61 | uint32_t value, mask = 1 << offset; | ||
62 | unsigned long flags; | ||
63 | |||
64 | spin_lock_irqsave(&gpio_lock, flags); | ||
65 | |||
66 | value = __raw_readl(base + GPDR_OFFSET); | ||
67 | if (__gpio_is_inverted(chip->base + offset)) | ||
68 | value |= mask; | ||
69 | else | ||
70 | value &= ~mask; | ||
71 | __raw_writel(value, base + GPDR_OFFSET); | ||
72 | |||
73 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int pxa_gpio_direction_output(struct gpio_chip *chip, | ||
78 | unsigned offset, int value) | ||
79 | { | ||
80 | void __iomem *base = gpio_chip_base(chip); | ||
81 | uint32_t tmp, mask = 1 << offset; | ||
82 | unsigned long flags; | ||
83 | |||
84 | __raw_writel(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); | ||
85 | |||
86 | spin_lock_irqsave(&gpio_lock, flags); | ||
87 | |||
88 | tmp = __raw_readl(base + GPDR_OFFSET); | ||
89 | if (__gpio_is_inverted(chip->base + offset)) | ||
90 | tmp &= ~mask; | ||
91 | else | ||
92 | tmp |= mask; | ||
93 | __raw_writel(tmp, base + GPDR_OFFSET); | ||
94 | |||
95 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
100 | { | ||
101 | return __raw_readl(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); | ||
102 | } | ||
103 | |||
104 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
105 | { | ||
106 | __raw_writel(1 << offset, gpio_chip_base(chip) + | ||
107 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | ||
108 | } | ||
109 | |||
110 | static int __init pxa_init_gpio_chip(int gpio_end) | ||
111 | { | ||
112 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | ||
113 | struct pxa_gpio_chip *chips; | ||
114 | |||
115 | chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); | ||
116 | if (chips == NULL) { | ||
117 | pr_err("%s: failed to allocate GPIO chips\n", __func__); | ||
118 | return -ENOMEM; | ||
119 | } | ||
120 | |||
121 | for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { | ||
122 | struct gpio_chip *c = &chips[i].chip; | ||
123 | |||
124 | sprintf(chips[i].label, "gpio-%d", i); | ||
125 | chips[i].regbase = GPIO_BANK(i); | ||
126 | |||
127 | c->base = gpio; | ||
128 | c->label = chips[i].label; | ||
129 | |||
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; | ||
134 | |||
135 | /* number of GPIOs on last bank may be less than 32 */ | ||
136 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | ||
137 | gpiochip_add(c); | ||
138 | } | ||
139 | pxa_gpio_chips = chips; | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* Update only those GRERx and GFERx edge detection register bits if those | ||
144 | * bits are set in c->irq_mask | ||
145 | */ | ||
146 | static inline void update_edge_detect(struct pxa_gpio_chip *c) | ||
147 | { | ||
148 | uint32_t grer, gfer; | ||
149 | |||
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); | ||
156 | } | ||
157 | |||
158 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | ||
159 | { | ||
160 | struct pxa_gpio_chip *c; | ||
161 | int gpio = irq_to_gpio(d->irq); | ||
162 | unsigned long gpdr, mask = GPIO_bit(gpio); | ||
163 | |||
164 | c = gpio_to_pxachip(gpio); | ||
165 | |||
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 | ||
169 | */ | ||
170 | if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio)) | ||
171 | return 0; | ||
172 | |||
173 | if (__gpio_is_occupied(gpio)) | ||
174 | return 0; | ||
175 | |||
176 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | ||
177 | } | ||
178 | |||
179 | gpdr = __raw_readl(c->regbase + GPDR_OFFSET); | ||
180 | |||
181 | if (__gpio_is_inverted(gpio)) | ||
182 | __raw_writel(gpdr | mask, c->regbase + GPDR_OFFSET); | ||
183 | else | ||
184 | __raw_writel(gpdr & ~mask, c->regbase + GPDR_OFFSET); | ||
185 | |||
186 | if (type & IRQ_TYPE_EDGE_RISING) | ||
187 | c->irq_edge_rise |= mask; | ||
188 | else | ||
189 | c->irq_edge_rise &= ~mask; | ||
190 | |||
191 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
192 | c->irq_edge_fall |= mask; | ||
193 | else | ||
194 | c->irq_edge_fall &= ~mask; | ||
195 | |||
196 | update_edge_detect(c); | ||
197 | |||
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" : "")); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | ||
205 | { | ||
206 | struct pxa_gpio_chip *c; | ||
207 | int loop, gpio, gpio_base, n; | ||
208 | unsigned long gedr; | ||
209 | |||
210 | do { | ||
211 | loop = 0; | ||
212 | for_each_gpio_chip(gpio, c) { | ||
213 | gpio_base = c->chip.base; | ||
214 | |||
215 | gedr = __raw_readl(c->regbase + GEDR_OFFSET); | ||
216 | gedr = gedr & c->irq_mask; | ||
217 | __raw_writel(gedr, c->regbase + GEDR_OFFSET); | ||
218 | |||
219 | n = find_first_bit(&gedr, BITS_PER_LONG); | ||
220 | while (n < BITS_PER_LONG) { | ||
221 | loop = 1; | ||
222 | |||
223 | generic_handle_irq(gpio_to_irq(gpio_base + n)); | ||
224 | n = find_next_bit(&gedr, BITS_PER_LONG, n + 1); | ||
225 | } | ||
226 | } | ||
227 | } while (loop); | ||
228 | } | ||
229 | |||
230 | static void pxa_ack_muxed_gpio(struct irq_data *d) | ||
231 | { | ||
232 | int gpio = irq_to_gpio(d->irq); | ||
233 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | ||
234 | |||
235 | __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); | ||
236 | } | ||
237 | |||
238 | static void pxa_mask_muxed_gpio(struct irq_data *d) | ||
239 | { | ||
240 | int gpio = irq_to_gpio(d->irq); | ||
241 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | ||
242 | uint32_t grer, gfer; | ||
243 | |||
244 | c->irq_mask &= ~GPIO_bit(gpio); | ||
245 | |||
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); | ||
250 | } | ||
251 | |||
252 | static void pxa_unmask_muxed_gpio(struct irq_data *d) | ||
253 | { | ||
254 | int gpio = irq_to_gpio(d->irq); | ||
255 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | ||
256 | |||
257 | c->irq_mask |= GPIO_bit(gpio); | ||
258 | update_edge_detect(c); | ||
259 | } | ||
260 | |||
261 | static struct irq_chip pxa_muxed_gpio_chip = { | ||
262 | .name = "GPIO", | ||
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, | ||
267 | }; | ||
268 | |||
269 | void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) | ||
270 | { | ||
271 | struct pxa_gpio_chip *c; | ||
272 | int gpio, irq; | ||
273 | |||
274 | pxa_last_gpio = end; | ||
275 | |||
276 | /* Initialize GPIO chips */ | ||
277 | pxa_init_gpio_chip(end); | ||
278 | |||
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); | ||
284 | } | ||
285 | |||
286 | for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { | ||
287 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
288 | handle_edge_irq); | ||
289 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
290 | } | ||
291 | |||
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; | ||
295 | } | ||
296 | |||
297 | #ifdef CONFIG_PM | ||
298 | static int pxa_gpio_suspend(void) | ||
299 | { | ||
300 | struct pxa_gpio_chip *c; | ||
301 | int gpio; | ||
302 | |||
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); | ||
308 | |||
309 | /* Clear GPIO transition detect bits */ | ||
310 | __raw_writel(0xffffffff, c->regbase + GEDR_OFFSET); | ||
311 | } | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static void pxa_gpio_resume(void) | ||
316 | { | ||
317 | struct pxa_gpio_chip *c; | ||
318 | int gpio; | ||
319 | |||
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); | ||
324 | |||
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); | ||
328 | } | ||
329 | } | ||
330 | #else | ||
331 | #define pxa_gpio_suspend NULL | ||
332 | #define pxa_gpio_resume NULL | ||
333 | #endif | ||
334 | |||
335 | struct syscore_ops pxa_gpio_syscore_ops = { | ||
336 | .suspend = pxa_gpio_suspend, | ||
337 | .resume = pxa_gpio_resume, | ||
338 | }; | ||
diff --git a/drivers/gpio/gpio-s5pc100.c b/drivers/gpio/gpio-s5pc100.c deleted file mode 100644 index 7f87b0c76e0b..000000000000 --- a/drivers/gpio/gpio-s5pc100.c +++ /dev/null | |||
@@ -1,354 +0,0 @@ | |||
1 | /* | ||
2 | * S5PC100 - GPIOlib support | ||
3 | * | ||
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * Copyright 2009 Samsung Electronics Co | ||
8 | * Kyungmin Park <kyungmin.park@samsung.com> | ||
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 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/gpio.h> | ||
19 | |||
20 | #include <mach/map.h> | ||
21 | #include <mach/regs-gpio.h> | ||
22 | |||
23 | #include <plat/gpio-core.h> | ||
24 | #include <plat/gpio-cfg.h> | ||
25 | #include <plat/gpio-cfg-helpers.h> | ||
26 | |||
27 | /* S5PC100 GPIO bank summary: | ||
28 | * | ||
29 | * Bank GPIOs Style INT Type | ||
30 | * A0 8 4Bit GPIO_INT0 | ||
31 | * A1 5 4Bit GPIO_INT1 | ||
32 | * B 8 4Bit GPIO_INT2 | ||
33 | * C 5 4Bit GPIO_INT3 | ||
34 | * D 7 4Bit GPIO_INT4 | ||
35 | * E0 8 4Bit GPIO_INT5 | ||
36 | * E1 6 4Bit GPIO_INT6 | ||
37 | * F0 8 4Bit GPIO_INT7 | ||
38 | * F1 8 4Bit GPIO_INT8 | ||
39 | * F2 8 4Bit GPIO_INT9 | ||
40 | * F3 4 4Bit GPIO_INT10 | ||
41 | * G0 8 4Bit GPIO_INT11 | ||
42 | * G1 3 4Bit GPIO_INT12 | ||
43 | * G2 7 4Bit GPIO_INT13 | ||
44 | * G3 7 4Bit GPIO_INT14 | ||
45 | * H0 8 4Bit WKUP_INT | ||
46 | * H1 8 4Bit WKUP_INT | ||
47 | * H2 8 4Bit WKUP_INT | ||
48 | * H3 8 4Bit WKUP_INT | ||
49 | * I 8 4Bit GPIO_INT15 | ||
50 | * J0 8 4Bit GPIO_INT16 | ||
51 | * J1 5 4Bit GPIO_INT17 | ||
52 | * J2 8 4Bit GPIO_INT18 | ||
53 | * J3 8 4Bit GPIO_INT19 | ||
54 | * J4 4 4Bit GPIO_INT20 | ||
55 | * K0 8 4Bit None | ||
56 | * K1 6 4Bit None | ||
57 | * K2 8 4Bit None | ||
58 | * K3 8 4Bit None | ||
59 | * L0 8 4Bit None | ||
60 | * L1 8 4Bit None | ||
61 | * L2 8 4Bit None | ||
62 | * L3 8 4Bit None | ||
63 | */ | ||
64 | |||
65 | static struct s3c_gpio_cfg gpio_cfg = { | ||
66 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
67 | .set_pull = s3c_gpio_setpull_updown, | ||
68 | .get_pull = s3c_gpio_getpull_updown, | ||
69 | }; | ||
70 | |||
71 | static struct s3c_gpio_cfg gpio_cfg_eint = { | ||
72 | .cfg_eint = 0xf, | ||
73 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
74 | .set_pull = s3c_gpio_setpull_updown, | ||
75 | .get_pull = s3c_gpio_getpull_updown, | ||
76 | }; | ||
77 | |||
78 | static struct s3c_gpio_cfg gpio_cfg_noint = { | ||
79 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
80 | .set_pull = s3c_gpio_setpull_updown, | ||
81 | .get_pull = s3c_gpio_getpull_updown, | ||
82 | }; | ||
83 | |||
84 | /* | ||
85 | * GPIO bank's base address given the index of the bank in the | ||
86 | * list of all gpio banks. | ||
87 | */ | ||
88 | #define S5PC100_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20)) | ||
89 | |||
90 | /* | ||
91 | * Following are the gpio banks in S5PC100. | ||
92 | * | ||
93 | * The 'config' member when left to NULL, is initialized to the default | ||
94 | * structure gpio_cfg in the init function below. | ||
95 | * | ||
96 | * The 'base' member is also initialized in the init function below. | ||
97 | * Note: The initialization of 'base' member of s3c_gpio_chip structure | ||
98 | * uses the above macro and depends on the banks being listed in order here. | ||
99 | */ | ||
100 | static struct s3c_gpio_chip s5pc100_gpio_chips[] = { | ||
101 | { | ||
102 | .chip = { | ||
103 | .base = S5PC100_GPA0(0), | ||
104 | .ngpio = S5PC100_GPIO_A0_NR, | ||
105 | .label = "GPA0", | ||
106 | }, | ||
107 | }, { | ||
108 | .chip = { | ||
109 | .base = S5PC100_GPA1(0), | ||
110 | .ngpio = S5PC100_GPIO_A1_NR, | ||
111 | .label = "GPA1", | ||
112 | }, | ||
113 | }, { | ||
114 | .chip = { | ||
115 | .base = S5PC100_GPB(0), | ||
116 | .ngpio = S5PC100_GPIO_B_NR, | ||
117 | .label = "GPB", | ||
118 | }, | ||
119 | }, { | ||
120 | .chip = { | ||
121 | .base = S5PC100_GPC(0), | ||
122 | .ngpio = S5PC100_GPIO_C_NR, | ||
123 | .label = "GPC", | ||
124 | }, | ||
125 | }, { | ||
126 | .chip = { | ||
127 | .base = S5PC100_GPD(0), | ||
128 | .ngpio = S5PC100_GPIO_D_NR, | ||
129 | .label = "GPD", | ||
130 | }, | ||
131 | }, { | ||
132 | .chip = { | ||
133 | .base = S5PC100_GPE0(0), | ||
134 | .ngpio = S5PC100_GPIO_E0_NR, | ||
135 | .label = "GPE0", | ||
136 | }, | ||
137 | }, { | ||
138 | .chip = { | ||
139 | .base = S5PC100_GPE1(0), | ||
140 | .ngpio = S5PC100_GPIO_E1_NR, | ||
141 | .label = "GPE1", | ||
142 | }, | ||
143 | }, { | ||
144 | .chip = { | ||
145 | .base = S5PC100_GPF0(0), | ||
146 | .ngpio = S5PC100_GPIO_F0_NR, | ||
147 | .label = "GPF0", | ||
148 | }, | ||
149 | }, { | ||
150 | .chip = { | ||
151 | .base = S5PC100_GPF1(0), | ||
152 | .ngpio = S5PC100_GPIO_F1_NR, | ||
153 | .label = "GPF1", | ||
154 | }, | ||
155 | }, { | ||
156 | .chip = { | ||
157 | .base = S5PC100_GPF2(0), | ||
158 | .ngpio = S5PC100_GPIO_F2_NR, | ||
159 | .label = "GPF2", | ||
160 | }, | ||
161 | }, { | ||
162 | .chip = { | ||
163 | .base = S5PC100_GPF3(0), | ||
164 | .ngpio = S5PC100_GPIO_F3_NR, | ||
165 | .label = "GPF3", | ||
166 | }, | ||
167 | }, { | ||
168 | .chip = { | ||
169 | .base = S5PC100_GPG0(0), | ||
170 | .ngpio = S5PC100_GPIO_G0_NR, | ||
171 | .label = "GPG0", | ||
172 | }, | ||
173 | }, { | ||
174 | .chip = { | ||
175 | .base = S5PC100_GPG1(0), | ||
176 | .ngpio = S5PC100_GPIO_G1_NR, | ||
177 | .label = "GPG1", | ||
178 | }, | ||
179 | }, { | ||
180 | .chip = { | ||
181 | .base = S5PC100_GPG2(0), | ||
182 | .ngpio = S5PC100_GPIO_G2_NR, | ||
183 | .label = "GPG2", | ||
184 | }, | ||
185 | }, { | ||
186 | .chip = { | ||
187 | .base = S5PC100_GPG3(0), | ||
188 | .ngpio = S5PC100_GPIO_G3_NR, | ||
189 | .label = "GPG3", | ||
190 | }, | ||
191 | }, { | ||
192 | .chip = { | ||
193 | .base = S5PC100_GPI(0), | ||
194 | .ngpio = S5PC100_GPIO_I_NR, | ||
195 | .label = "GPI", | ||
196 | }, | ||
197 | }, { | ||
198 | .chip = { | ||
199 | .base = S5PC100_GPJ0(0), | ||
200 | .ngpio = S5PC100_GPIO_J0_NR, | ||
201 | .label = "GPJ0", | ||
202 | }, | ||
203 | }, { | ||
204 | .chip = { | ||
205 | .base = S5PC100_GPJ1(0), | ||
206 | .ngpio = S5PC100_GPIO_J1_NR, | ||
207 | .label = "GPJ1", | ||
208 | }, | ||
209 | }, { | ||
210 | .chip = { | ||
211 | .base = S5PC100_GPJ2(0), | ||
212 | .ngpio = S5PC100_GPIO_J2_NR, | ||
213 | .label = "GPJ2", | ||
214 | }, | ||
215 | }, { | ||
216 | .chip = { | ||
217 | .base = S5PC100_GPJ3(0), | ||
218 | .ngpio = S5PC100_GPIO_J3_NR, | ||
219 | .label = "GPJ3", | ||
220 | }, | ||
221 | }, { | ||
222 | .chip = { | ||
223 | .base = S5PC100_GPJ4(0), | ||
224 | .ngpio = S5PC100_GPIO_J4_NR, | ||
225 | .label = "GPJ4", | ||
226 | }, | ||
227 | }, { | ||
228 | .config = &gpio_cfg_noint, | ||
229 | .chip = { | ||
230 | .base = S5PC100_GPK0(0), | ||
231 | .ngpio = S5PC100_GPIO_K0_NR, | ||
232 | .label = "GPK0", | ||
233 | }, | ||
234 | }, { | ||
235 | .config = &gpio_cfg_noint, | ||
236 | .chip = { | ||
237 | .base = S5PC100_GPK1(0), | ||
238 | .ngpio = S5PC100_GPIO_K1_NR, | ||
239 | .label = "GPK1", | ||
240 | }, | ||
241 | }, { | ||
242 | .config = &gpio_cfg_noint, | ||
243 | .chip = { | ||
244 | .base = S5PC100_GPK2(0), | ||
245 | .ngpio = S5PC100_GPIO_K2_NR, | ||
246 | .label = "GPK2", | ||
247 | }, | ||
248 | }, { | ||
249 | .config = &gpio_cfg_noint, | ||
250 | .chip = { | ||
251 | .base = S5PC100_GPK3(0), | ||
252 | .ngpio = S5PC100_GPIO_K3_NR, | ||
253 | .label = "GPK3", | ||
254 | }, | ||
255 | }, { | ||
256 | .config = &gpio_cfg_noint, | ||
257 | .chip = { | ||
258 | .base = S5PC100_GPL0(0), | ||
259 | .ngpio = S5PC100_GPIO_L0_NR, | ||
260 | .label = "GPL0", | ||
261 | }, | ||
262 | }, { | ||
263 | .config = &gpio_cfg_noint, | ||
264 | .chip = { | ||
265 | .base = S5PC100_GPL1(0), | ||
266 | .ngpio = S5PC100_GPIO_L1_NR, | ||
267 | .label = "GPL1", | ||
268 | }, | ||
269 | }, { | ||
270 | .config = &gpio_cfg_noint, | ||
271 | .chip = { | ||
272 | .base = S5PC100_GPL2(0), | ||
273 | .ngpio = S5PC100_GPIO_L2_NR, | ||
274 | .label = "GPL2", | ||
275 | }, | ||
276 | }, { | ||
277 | .config = &gpio_cfg_noint, | ||
278 | .chip = { | ||
279 | .base = S5PC100_GPL3(0), | ||
280 | .ngpio = S5PC100_GPIO_L3_NR, | ||
281 | .label = "GPL3", | ||
282 | }, | ||
283 | }, { | ||
284 | .config = &gpio_cfg_noint, | ||
285 | .chip = { | ||
286 | .base = S5PC100_GPL4(0), | ||
287 | .ngpio = S5PC100_GPIO_L4_NR, | ||
288 | .label = "GPL4", | ||
289 | }, | ||
290 | }, { | ||
291 | .base = (S5P_VA_GPIO + 0xC00), | ||
292 | .config = &gpio_cfg_eint, | ||
293 | .irq_base = IRQ_EINT(0), | ||
294 | .chip = { | ||
295 | .base = S5PC100_GPH0(0), | ||
296 | .ngpio = S5PC100_GPIO_H0_NR, | ||
297 | .label = "GPH0", | ||
298 | .to_irq = samsung_gpiolib_to_irq, | ||
299 | }, | ||
300 | }, { | ||
301 | .base = (S5P_VA_GPIO + 0xC20), | ||
302 | .config = &gpio_cfg_eint, | ||
303 | .irq_base = IRQ_EINT(8), | ||
304 | .chip = { | ||
305 | .base = S5PC100_GPH1(0), | ||
306 | .ngpio = S5PC100_GPIO_H1_NR, | ||
307 | .label = "GPH1", | ||
308 | .to_irq = samsung_gpiolib_to_irq, | ||
309 | }, | ||
310 | }, { | ||
311 | .base = (S5P_VA_GPIO + 0xC40), | ||
312 | .config = &gpio_cfg_eint, | ||
313 | .irq_base = IRQ_EINT(16), | ||
314 | .chip = { | ||
315 | .base = S5PC100_GPH2(0), | ||
316 | .ngpio = S5PC100_GPIO_H2_NR, | ||
317 | .label = "GPH2", | ||
318 | .to_irq = samsung_gpiolib_to_irq, | ||
319 | }, | ||
320 | }, { | ||
321 | .base = (S5P_VA_GPIO + 0xC60), | ||
322 | .config = &gpio_cfg_eint, | ||
323 | .irq_base = IRQ_EINT(24), | ||
324 | .chip = { | ||
325 | .base = S5PC100_GPH3(0), | ||
326 | .ngpio = S5PC100_GPIO_H3_NR, | ||
327 | .label = "GPH3", | ||
328 | .to_irq = samsung_gpiolib_to_irq, | ||
329 | }, | ||
330 | }, | ||
331 | }; | ||
332 | |||
333 | static __init int s5pc100_gpiolib_init(void) | ||
334 | { | ||
335 | struct s3c_gpio_chip *chip = s5pc100_gpio_chips; | ||
336 | int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips); | ||
337 | int gpioint_group = 0; | ||
338 | int i; | ||
339 | |||
340 | for (i = 0; i < nr_chips; i++, chip++) { | ||
341 | if (chip->config == NULL) { | ||
342 | chip->config = &gpio_cfg; | ||
343 | chip->group = gpioint_group++; | ||
344 | } | ||
345 | if (chip->base == NULL) | ||
346 | chip->base = S5PC100_BANK_BASE(i); | ||
347 | } | ||
348 | |||
349 | samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips); | ||
350 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | core_initcall(s5pc100_gpiolib_init); | ||
diff --git a/drivers/gpio/gpio-s5pv210.c b/drivers/gpio/gpio-s5pv210.c deleted file mode 100644 index eb12f1602de9..000000000000 --- a/drivers/gpio/gpio-s5pv210.c +++ /dev/null | |||
@@ -1,287 +0,0 @@ | |||
1 | /* | ||
2 | * S5PV210 - GPIOlib support | ||
3 | * | ||
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||
5 | * http://www.samsung.com/ | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <plat/gpio-core.h> | ||
17 | #include <plat/gpio-cfg.h> | ||
18 | #include <plat/gpio-cfg-helpers.h> | ||
19 | #include <mach/map.h> | ||
20 | |||
21 | static struct s3c_gpio_cfg gpio_cfg = { | ||
22 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
23 | .set_pull = s3c_gpio_setpull_updown, | ||
24 | .get_pull = s3c_gpio_getpull_updown, | ||
25 | }; | ||
26 | |||
27 | static struct s3c_gpio_cfg gpio_cfg_noint = { | ||
28 | .set_config = s3c_gpio_setcfg_s3c64xx_4bit, | ||
29 | .set_pull = s3c_gpio_setpull_updown, | ||
30 | .get_pull = s3c_gpio_getpull_updown, | ||
31 | }; | ||
32 | |||
33 | /* GPIO bank's base address given the index of the bank in the | ||
34 | * list of all gpio banks. | ||
35 | */ | ||
36 | #define S5PV210_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20)) | ||
37 | |||
38 | /* | ||
39 | * Following are the gpio banks in v210. | ||
40 | * | ||
41 | * The 'config' member when left to NULL, is initialized to the default | ||
42 | * structure gpio_cfg in the init function below. | ||
43 | * | ||
44 | * The 'base' member is also initialized in the init function below. | ||
45 | * Note: The initialization of 'base' member of s3c_gpio_chip structure | ||
46 | * uses the above macro and depends on the banks being listed in order here. | ||
47 | */ | ||
48 | static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { | ||
49 | { | ||
50 | .chip = { | ||
51 | .base = S5PV210_GPA0(0), | ||
52 | .ngpio = S5PV210_GPIO_A0_NR, | ||
53 | .label = "GPA0", | ||
54 | }, | ||
55 | }, { | ||
56 | .chip = { | ||
57 | .base = S5PV210_GPA1(0), | ||
58 | .ngpio = S5PV210_GPIO_A1_NR, | ||
59 | .label = "GPA1", | ||
60 | }, | ||
61 | }, { | ||
62 | .chip = { | ||
63 | .base = S5PV210_GPB(0), | ||
64 | .ngpio = S5PV210_GPIO_B_NR, | ||
65 | .label = "GPB", | ||
66 | }, | ||
67 | }, { | ||
68 | .chip = { | ||
69 | .base = S5PV210_GPC0(0), | ||
70 | .ngpio = S5PV210_GPIO_C0_NR, | ||
71 | .label = "GPC0", | ||
72 | }, | ||
73 | }, { | ||
74 | .chip = { | ||
75 | .base = S5PV210_GPC1(0), | ||
76 | .ngpio = S5PV210_GPIO_C1_NR, | ||
77 | .label = "GPC1", | ||
78 | }, | ||
79 | }, { | ||
80 | .chip = { | ||
81 | .base = S5PV210_GPD0(0), | ||
82 | .ngpio = S5PV210_GPIO_D0_NR, | ||
83 | .label = "GPD0", | ||
84 | }, | ||
85 | }, { | ||
86 | .chip = { | ||
87 | .base = S5PV210_GPD1(0), | ||
88 | .ngpio = S5PV210_GPIO_D1_NR, | ||
89 | .label = "GPD1", | ||
90 | }, | ||
91 | }, { | ||
92 | .chip = { | ||
93 | .base = S5PV210_GPE0(0), | ||
94 | .ngpio = S5PV210_GPIO_E0_NR, | ||
95 | .label = "GPE0", | ||
96 | }, | ||
97 | }, { | ||
98 | .chip = { | ||
99 | .base = S5PV210_GPE1(0), | ||
100 | .ngpio = S5PV210_GPIO_E1_NR, | ||
101 | .label = "GPE1", | ||
102 | }, | ||
103 | }, { | ||
104 | .chip = { | ||
105 | .base = S5PV210_GPF0(0), | ||
106 | .ngpio = S5PV210_GPIO_F0_NR, | ||
107 | .label = "GPF0", | ||
108 | }, | ||
109 | }, { | ||
110 | .chip = { | ||
111 | .base = S5PV210_GPF1(0), | ||
112 | .ngpio = S5PV210_GPIO_F1_NR, | ||
113 | .label = "GPF1", | ||
114 | }, | ||
115 | }, { | ||
116 | .chip = { | ||
117 | .base = S5PV210_GPF2(0), | ||
118 | .ngpio = S5PV210_GPIO_F2_NR, | ||
119 | .label = "GPF2", | ||
120 | }, | ||
121 | }, { | ||
122 | .chip = { | ||
123 | .base = S5PV210_GPF3(0), | ||
124 | .ngpio = S5PV210_GPIO_F3_NR, | ||
125 | .label = "GPF3", | ||
126 | }, | ||
127 | }, { | ||
128 | .chip = { | ||
129 | .base = S5PV210_GPG0(0), | ||
130 | .ngpio = S5PV210_GPIO_G0_NR, | ||
131 | .label = "GPG0", | ||
132 | }, | ||
133 | }, { | ||
134 | .chip = { | ||
135 | .base = S5PV210_GPG1(0), | ||
136 | .ngpio = S5PV210_GPIO_G1_NR, | ||
137 | .label = "GPG1", | ||
138 | }, | ||
139 | }, { | ||
140 | .chip = { | ||
141 | .base = S5PV210_GPG2(0), | ||
142 | .ngpio = S5PV210_GPIO_G2_NR, | ||
143 | .label = "GPG2", | ||
144 | }, | ||
145 | }, { | ||
146 | .chip = { | ||
147 | .base = S5PV210_GPG3(0), | ||
148 | .ngpio = S5PV210_GPIO_G3_NR, | ||
149 | .label = "GPG3", | ||
150 | }, | ||
151 | }, { | ||
152 | .config = &gpio_cfg_noint, | ||
153 | .chip = { | ||
154 | .base = S5PV210_GPI(0), | ||
155 | .ngpio = S5PV210_GPIO_I_NR, | ||
156 | .label = "GPI", | ||
157 | }, | ||
158 | }, { | ||
159 | .chip = { | ||
160 | .base = S5PV210_GPJ0(0), | ||
161 | .ngpio = S5PV210_GPIO_J0_NR, | ||
162 | .label = "GPJ0", | ||
163 | }, | ||
164 | }, { | ||
165 | .chip = { | ||
166 | .base = S5PV210_GPJ1(0), | ||
167 | .ngpio = S5PV210_GPIO_J1_NR, | ||
168 | .label = "GPJ1", | ||
169 | }, | ||
170 | }, { | ||
171 | .chip = { | ||
172 | .base = S5PV210_GPJ2(0), | ||
173 | .ngpio = S5PV210_GPIO_J2_NR, | ||
174 | .label = "GPJ2", | ||
175 | }, | ||
176 | }, { | ||
177 | .chip = { | ||
178 | .base = S5PV210_GPJ3(0), | ||
179 | .ngpio = S5PV210_GPIO_J3_NR, | ||
180 | .label = "GPJ3", | ||
181 | }, | ||
182 | }, { | ||
183 | .chip = { | ||
184 | .base = S5PV210_GPJ4(0), | ||
185 | .ngpio = S5PV210_GPIO_J4_NR, | ||
186 | .label = "GPJ4", | ||
187 | }, | ||
188 | }, { | ||
189 | .config = &gpio_cfg_noint, | ||
190 | .chip = { | ||
191 | .base = S5PV210_MP01(0), | ||
192 | .ngpio = S5PV210_GPIO_MP01_NR, | ||
193 | .label = "MP01", | ||
194 | }, | ||
195 | }, { | ||
196 | .config = &gpio_cfg_noint, | ||
197 | .chip = { | ||
198 | .base = S5PV210_MP02(0), | ||
199 | .ngpio = S5PV210_GPIO_MP02_NR, | ||
200 | .label = "MP02", | ||
201 | }, | ||
202 | }, { | ||
203 | .config = &gpio_cfg_noint, | ||
204 | .chip = { | ||
205 | .base = S5PV210_MP03(0), | ||
206 | .ngpio = S5PV210_GPIO_MP03_NR, | ||
207 | .label = "MP03", | ||
208 | }, | ||
209 | }, { | ||
210 | .config = &gpio_cfg_noint, | ||
211 | .chip = { | ||
212 | .base = S5PV210_MP04(0), | ||
213 | .ngpio = S5PV210_GPIO_MP04_NR, | ||
214 | .label = "MP04", | ||
215 | }, | ||
216 | }, { | ||
217 | .config = &gpio_cfg_noint, | ||
218 | .chip = { | ||
219 | .base = S5PV210_MP05(0), | ||
220 | .ngpio = S5PV210_GPIO_MP05_NR, | ||
221 | .label = "MP05", | ||
222 | }, | ||
223 | }, { | ||
224 | .base = (S5P_VA_GPIO + 0xC00), | ||
225 | .config = &gpio_cfg_noint, | ||
226 | .irq_base = IRQ_EINT(0), | ||
227 | .chip = { | ||
228 | .base = S5PV210_GPH0(0), | ||
229 | .ngpio = S5PV210_GPIO_H0_NR, | ||
230 | .label = "GPH0", | ||
231 | .to_irq = samsung_gpiolib_to_irq, | ||
232 | }, | ||
233 | }, { | ||
234 | .base = (S5P_VA_GPIO + 0xC20), | ||
235 | .config = &gpio_cfg_noint, | ||
236 | .irq_base = IRQ_EINT(8), | ||
237 | .chip = { | ||
238 | .base = S5PV210_GPH1(0), | ||
239 | .ngpio = S5PV210_GPIO_H1_NR, | ||
240 | .label = "GPH1", | ||
241 | .to_irq = samsung_gpiolib_to_irq, | ||
242 | }, | ||
243 | }, { | ||
244 | .base = (S5P_VA_GPIO + 0xC40), | ||
245 | .config = &gpio_cfg_noint, | ||
246 | .irq_base = IRQ_EINT(16), | ||
247 | .chip = { | ||
248 | .base = S5PV210_GPH2(0), | ||
249 | .ngpio = S5PV210_GPIO_H2_NR, | ||
250 | .label = "GPH2", | ||
251 | .to_irq = samsung_gpiolib_to_irq, | ||
252 | }, | ||
253 | }, { | ||
254 | .base = (S5P_VA_GPIO + 0xC60), | ||
255 | .config = &gpio_cfg_noint, | ||
256 | .irq_base = IRQ_EINT(24), | ||
257 | .chip = { | ||
258 | .base = S5PV210_GPH3(0), | ||
259 | .ngpio = S5PV210_GPIO_H3_NR, | ||
260 | .label = "GPH3", | ||
261 | .to_irq = samsung_gpiolib_to_irq, | ||
262 | }, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | static __init int s5pv210_gpiolib_init(void) | ||
267 | { | ||
268 | struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; | ||
269 | int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); | ||
270 | int gpioint_group = 0; | ||
271 | int i = 0; | ||
272 | |||
273 | for (i = 0; i < nr_chips; i++, chip++) { | ||
274 | if (chip->config == NULL) { | ||
275 | chip->config = &gpio_cfg; | ||
276 | chip->group = gpioint_group++; | ||
277 | } | ||
278 | if (chip->base == NULL) | ||
279 | chip->base = S5PV210_BANK_BASE(i); | ||
280 | } | ||
281 | |||
282 | samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips); | ||
283 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | core_initcall(s5pv210_gpiolib_init); | ||
diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c new file mode 100644 index 000000000000..b6c1f6d80649 --- /dev/null +++ b/drivers/gpio/gpio-sa1100.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-sa1100/gpio.c | ||
3 | * | ||
4 | * Generic SA-1100 GPIO handling | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/gpio.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | |||
16 | static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
17 | { | ||
18 | return GPLR & GPIO_GPIO(offset); | ||
19 | } | ||
20 | |||
21 | static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
22 | { | ||
23 | if (value) | ||
24 | GPSR = GPIO_GPIO(offset); | ||
25 | else | ||
26 | GPCR = GPIO_GPIO(offset); | ||
27 | } | ||
28 | |||
29 | static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset) | ||
30 | { | ||
31 | unsigned long flags; | ||
32 | |||
33 | local_irq_save(flags); | ||
34 | GPDR &= ~GPIO_GPIO(offset); | ||
35 | local_irq_restore(flags); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value) | ||
40 | { | ||
41 | unsigned long flags; | ||
42 | |||
43 | local_irq_save(flags); | ||
44 | sa1100_gpio_set(chip, offset, value); | ||
45 | GPDR |= GPIO_GPIO(offset); | ||
46 | local_irq_restore(flags); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static struct gpio_chip sa1100_gpio_chip = { | ||
51 | .label = "gpio", | ||
52 | .direction_input = sa1100_direction_input, | ||
53 | .direction_output = sa1100_direction_output, | ||
54 | .set = sa1100_gpio_set, | ||
55 | .get = sa1100_gpio_get, | ||
56 | .base = 0, | ||
57 | .ngpio = GPIO_MAX + 1, | ||
58 | }; | ||
59 | |||
60 | void __init sa1100_init_gpio(void) | ||
61 | { | ||
62 | gpiochip_add(&sa1100_gpio_chip); | ||
63 | } | ||
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c new file mode 100644 index 000000000000..866251852719 --- /dev/null +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -0,0 +1,2712 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd. | ||
3 | * http://www.samsung.com/ | ||
4 | * | ||
5 | * Copyright 2008 Openmoko, Inc. | ||
6 | * Copyright 2008 Simtec Electronics | ||
7 | * Ben Dooks <ben@simtec.co.uk> | ||
8 | * http://armlinux.simtec.co.uk/ | ||
9 | * | ||
10 | * SAMSUNG - GPIOlib support | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/sysdev.h> | ||
26 | #include <linux/ioport.h> | ||
27 | |||
28 | #include <asm/irq.h> | ||
29 | |||
30 | #include <mach/hardware.h> | ||
31 | #include <mach/map.h> | ||
32 | #include <mach/regs-clock.h> | ||
33 | #include <mach/regs-gpio.h> | ||
34 | |||
35 | #include <plat/cpu.h> | ||
36 | #include <plat/gpio-core.h> | ||
37 | #include <plat/gpio-cfg.h> | ||
38 | #include <plat/gpio-cfg-helpers.h> | ||
39 | #include <plat/gpio-fns.h> | ||
40 | #include <plat/pm.h> | ||
41 | |||
42 | #ifndef DEBUG_GPIO | ||
43 | #define gpio_dbg(x...) do { } while (0) | ||
44 | #else | ||
45 | #define gpio_dbg(x...) printk(KERN_DEBUG x) | ||
46 | #endif | ||
47 | |||
48 | int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, | ||
49 | unsigned int off, samsung_gpio_pull_t pull) | ||
50 | { | ||
51 | void __iomem *reg = chip->base + 0x08; | ||
52 | int shift = off * 2; | ||
53 | u32 pup; | ||
54 | |||
55 | pup = __raw_readl(reg); | ||
56 | pup &= ~(3 << shift); | ||
57 | pup |= pull << shift; | ||
58 | __raw_writel(pup, reg); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip, | ||
64 | unsigned int off) | ||
65 | { | ||
66 | void __iomem *reg = chip->base + 0x08; | ||
67 | int shift = off * 2; | ||
68 | u32 pup = __raw_readl(reg); | ||
69 | |||
70 | pup >>= shift; | ||
71 | pup &= 0x3; | ||
72 | |||
73 | return (__force samsung_gpio_pull_t)pup; | ||
74 | } | ||
75 | |||
76 | int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip, | ||
77 | unsigned int off, samsung_gpio_pull_t pull) | ||
78 | { | ||
79 | switch (pull) { | ||
80 | case S3C_GPIO_PULL_NONE: | ||
81 | pull = 0x01; | ||
82 | break; | ||
83 | case S3C_GPIO_PULL_UP: | ||
84 | pull = 0x00; | ||
85 | break; | ||
86 | case S3C_GPIO_PULL_DOWN: | ||
87 | pull = 0x02; | ||
88 | break; | ||
89 | } | ||
90 | return samsung_gpio_setpull_updown(chip, off, pull); | ||
91 | } | ||
92 | |||
93 | samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip, | ||
94 | unsigned int off) | ||
95 | { | ||
96 | samsung_gpio_pull_t pull; | ||
97 | |||
98 | pull = samsung_gpio_getpull_updown(chip, off); | ||
99 | |||
100 | switch (pull) { | ||
101 | case 0x00: | ||
102 | pull = S3C_GPIO_PULL_UP; | ||
103 | break; | ||
104 | case 0x01: | ||
105 | case 0x03: | ||
106 | pull = S3C_GPIO_PULL_NONE; | ||
107 | break; | ||
108 | case 0x02: | ||
109 | pull = S3C_GPIO_PULL_DOWN; | ||
110 | break; | ||
111 | } | ||
112 | |||
113 | return pull; | ||
114 | } | ||
115 | |||
116 | static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip, | ||
117 | unsigned int off, samsung_gpio_pull_t pull, | ||
118 | samsung_gpio_pull_t updown) | ||
119 | { | ||
120 | void __iomem *reg = chip->base + 0x08; | ||
121 | u32 pup = __raw_readl(reg); | ||
122 | |||
123 | if (pull == updown) | ||
124 | pup &= ~(1 << off); | ||
125 | else if (pull == S3C_GPIO_PULL_NONE) | ||
126 | pup |= (1 << off); | ||
127 | else | ||
128 | return -EINVAL; | ||
129 | |||
130 | __raw_writel(pup, reg); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip, | ||
135 | unsigned int off, | ||
136 | samsung_gpio_pull_t updown) | ||
137 | { | ||
138 | void __iomem *reg = chip->base + 0x08; | ||
139 | u32 pup = __raw_readl(reg); | ||
140 | |||
141 | pup &= (1 << off); | ||
142 | return pup ? S3C_GPIO_PULL_NONE : updown; | ||
143 | } | ||
144 | |||
145 | samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip, | ||
146 | unsigned int off) | ||
147 | { | ||
148 | return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); | ||
149 | } | ||
150 | |||
151 | int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip, | ||
152 | unsigned int off, samsung_gpio_pull_t pull) | ||
153 | { | ||
154 | return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); | ||
155 | } | ||
156 | |||
157 | samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip, | ||
158 | unsigned int off) | ||
159 | { | ||
160 | return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); | ||
161 | } | ||
162 | |||
163 | int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip, | ||
164 | unsigned int off, samsung_gpio_pull_t pull) | ||
165 | { | ||
166 | return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); | ||
167 | } | ||
168 | |||
169 | static int exynos4_gpio_setpull(struct samsung_gpio_chip *chip, | ||
170 | unsigned int off, samsung_gpio_pull_t pull) | ||
171 | { | ||
172 | if (pull == S3C_GPIO_PULL_UP) | ||
173 | pull = 3; | ||
174 | |||
175 | return samsung_gpio_setpull_updown(chip, off, pull); | ||
176 | } | ||
177 | |||
178 | static samsung_gpio_pull_t exynos4_gpio_getpull(struct samsung_gpio_chip *chip, | ||
179 | unsigned int off) | ||
180 | { | ||
181 | samsung_gpio_pull_t pull; | ||
182 | |||
183 | pull = samsung_gpio_getpull_updown(chip, off); | ||
184 | |||
185 | if (pull == 3) | ||
186 | pull = S3C_GPIO_PULL_UP; | ||
187 | |||
188 | return pull; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration. | ||
193 | * @chip: The gpio chip that is being configured. | ||
194 | * @off: The offset for the GPIO being configured. | ||
195 | * @cfg: The configuration value to set. | ||
196 | * | ||
197 | * This helper deal with the GPIO cases where the control register | ||
198 | * has two bits of configuration per gpio, which have the following | ||
199 | * functions: | ||
200 | * 00 = input | ||
201 | * 01 = output | ||
202 | * 1x = special function | ||
203 | */ | ||
204 | |||
205 | static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip, | ||
206 | unsigned int off, unsigned int cfg) | ||
207 | { | ||
208 | void __iomem *reg = chip->base; | ||
209 | unsigned int shift = off * 2; | ||
210 | u32 con; | ||
211 | |||
212 | if (samsung_gpio_is_cfg_special(cfg)) { | ||
213 | cfg &= 0xf; | ||
214 | if (cfg > 3) | ||
215 | return -EINVAL; | ||
216 | |||
217 | cfg <<= shift; | ||
218 | } | ||
219 | |||
220 | con = __raw_readl(reg); | ||
221 | con &= ~(0x3 << shift); | ||
222 | con |= cfg; | ||
223 | __raw_writel(con, reg); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read. | ||
230 | * @chip: The gpio chip that is being configured. | ||
231 | * @off: The offset for the GPIO being configured. | ||
232 | * | ||
233 | * The reverse of samsung_gpio_setcfg_2bit(). Will return a value whicg | ||
234 | * could be directly passed back to samsung_gpio_setcfg_2bit(), from the | ||
235 | * S3C_GPIO_SPECIAL() macro. | ||
236 | */ | ||
237 | |||
238 | static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip, | ||
239 | unsigned int off) | ||
240 | { | ||
241 | u32 con; | ||
242 | |||
243 | con = __raw_readl(chip->base); | ||
244 | con >>= off * 2; | ||
245 | con &= 3; | ||
246 | |||
247 | /* this conversion works for IN and OUT as well as special mode */ | ||
248 | return S3C_GPIO_SPECIAL(con); | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config. | ||
253 | * @chip: The gpio chip that is being configured. | ||
254 | * @off: The offset for the GPIO being configured. | ||
255 | * @cfg: The configuration value to set. | ||
256 | * | ||
257 | * This helper deal with the GPIO cases where the control register has 4 bits | ||
258 | * of control per GPIO, generally in the form of: | ||
259 | * 0000 = Input | ||
260 | * 0001 = Output | ||
261 | * others = Special functions (dependent on bank) | ||
262 | * | ||
263 | * Note, since the code to deal with the case where there are two control | ||
264 | * registers instead of one, we do not have a separate set of functions for | ||
265 | * each case. | ||
266 | */ | ||
267 | |||
268 | static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip, | ||
269 | unsigned int off, unsigned int cfg) | ||
270 | { | ||
271 | void __iomem *reg = chip->base; | ||
272 | unsigned int shift = (off & 7) * 4; | ||
273 | u32 con; | ||
274 | |||
275 | if (off < 8 && chip->chip.ngpio > 8) | ||
276 | reg -= 4; | ||
277 | |||
278 | if (samsung_gpio_is_cfg_special(cfg)) { | ||
279 | cfg &= 0xf; | ||
280 | cfg <<= shift; | ||
281 | } | ||
282 | |||
283 | con = __raw_readl(reg); | ||
284 | con &= ~(0xf << shift); | ||
285 | con |= cfg; | ||
286 | __raw_writel(con, reg); | ||
287 | |||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read. | ||
293 | * @chip: The gpio chip that is being configured. | ||
294 | * @off: The offset for the GPIO being configured. | ||
295 | * | ||
296 | * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration | ||
297 | * register setting into a value the software can use, such as could be passed | ||
298 | * to samsung_gpio_setcfg_4bit(). | ||
299 | * | ||
300 | * @sa samsung_gpio_getcfg_2bit | ||
301 | */ | ||
302 | |||
303 | static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip, | ||
304 | unsigned int off) | ||
305 | { | ||
306 | void __iomem *reg = chip->base; | ||
307 | unsigned int shift = (off & 7) * 4; | ||
308 | u32 con; | ||
309 | |||
310 | if (off < 8 && chip->chip.ngpio > 8) | ||
311 | reg -= 4; | ||
312 | |||
313 | con = __raw_readl(reg); | ||
314 | con >>= shift; | ||
315 | con &= 0xf; | ||
316 | |||
317 | /* this conversion works for IN and OUT as well as special mode */ | ||
318 | return S3C_GPIO_SPECIAL(con); | ||
319 | } | ||
320 | |||
321 | #ifdef CONFIG_PLAT_S3C24XX | ||
322 | /* | ||
323 | * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A) | ||
324 | * @chip: The gpio chip that is being configured. | ||
325 | * @off: The offset for the GPIO being configured. | ||
326 | * @cfg: The configuration value to set. | ||
327 | * | ||
328 | * This helper deal with the GPIO cases where the control register | ||
329 | * has one bit of configuration for the gpio, where setting the bit | ||
330 | * means the pin is in special function mode and unset means output. | ||
331 | */ | ||
332 | |||
333 | static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip, | ||
334 | unsigned int off, unsigned int cfg) | ||
335 | { | ||
336 | void __iomem *reg = chip->base; | ||
337 | unsigned int shift = off; | ||
338 | u32 con; | ||
339 | |||
340 | if (samsung_gpio_is_cfg_special(cfg)) { | ||
341 | cfg &= 0xf; | ||
342 | |||
343 | /* Map output to 0, and SFN2 to 1 */ | ||
344 | cfg -= 1; | ||
345 | if (cfg > 1) | ||
346 | return -EINVAL; | ||
347 | |||
348 | cfg <<= shift; | ||
349 | } | ||
350 | |||
351 | con = __raw_readl(reg); | ||
352 | con &= ~(0x1 << shift); | ||
353 | con |= cfg; | ||
354 | __raw_writel(con, reg); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A) | ||
361 | * @chip: The gpio chip that is being configured. | ||
362 | * @off: The offset for the GPIO being configured. | ||
363 | * | ||
364 | * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable | ||
365 | * GPIO configuration value. | ||
366 | * | ||
367 | * @sa samsung_gpio_getcfg_2bit | ||
368 | * @sa samsung_gpio_getcfg_4bit | ||
369 | */ | ||
370 | |||
371 | static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip, | ||
372 | unsigned int off) | ||
373 | { | ||
374 | u32 con; | ||
375 | |||
376 | con = __raw_readl(chip->base); | ||
377 | con >>= off; | ||
378 | con &= 1; | ||
379 | con++; | ||
380 | |||
381 | return S3C_GPIO_SFN(con); | ||
382 | } | ||
383 | #endif | ||
384 | |||
385 | #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) | ||
386 | static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip, | ||
387 | unsigned int off, unsigned int cfg) | ||
388 | { | ||
389 | void __iomem *reg = chip->base; | ||
390 | unsigned int shift; | ||
391 | u32 con; | ||
392 | |||
393 | switch (off) { | ||
394 | case 0: | ||
395 | case 1: | ||
396 | case 2: | ||
397 | case 3: | ||
398 | case 4: | ||
399 | case 5: | ||
400 | shift = (off & 7) * 4; | ||
401 | reg -= 4; | ||
402 | break; | ||
403 | case 6: | ||
404 | shift = ((off + 1) & 7) * 4; | ||
405 | reg -= 4; | ||
406 | default: | ||
407 | shift = ((off + 1) & 7) * 4; | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | if (samsung_gpio_is_cfg_special(cfg)) { | ||
412 | cfg &= 0xf; | ||
413 | cfg <<= shift; | ||
414 | } | ||
415 | |||
416 | con = __raw_readl(reg); | ||
417 | con &= ~(0xf << shift); | ||
418 | con |= cfg; | ||
419 | __raw_writel(con, reg); | ||
420 | |||
421 | return 0; | ||
422 | } | ||
423 | #endif | ||
424 | |||
425 | static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg, | ||
426 | int nr_chips) | ||
427 | { | ||
428 | for (; nr_chips > 0; nr_chips--, chipcfg++) { | ||
429 | if (!chipcfg->set_config) | ||
430 | chipcfg->set_config = samsung_gpio_setcfg_4bit; | ||
431 | if (!chipcfg->get_config) | ||
432 | chipcfg->get_config = samsung_gpio_getcfg_4bit; | ||
433 | if (!chipcfg->set_pull) | ||
434 | chipcfg->set_pull = samsung_gpio_setpull_updown; | ||
435 | if (!chipcfg->get_pull) | ||
436 | chipcfg->get_pull = samsung_gpio_getpull_updown; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | struct samsung_gpio_cfg s3c24xx_gpiocfg_default = { | ||
441 | .set_config = samsung_gpio_setcfg_2bit, | ||
442 | .get_config = samsung_gpio_getcfg_2bit, | ||
443 | }; | ||
444 | |||
445 | #ifdef CONFIG_PLAT_S3C24XX | ||
446 | static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = { | ||
447 | .set_config = s3c24xx_gpio_setcfg_abank, | ||
448 | .get_config = s3c24xx_gpio_getcfg_abank, | ||
449 | }; | ||
450 | #endif | ||
451 | |||
452 | static struct samsung_gpio_cfg exynos4_gpio_cfg = { | ||
453 | .set_pull = exynos4_gpio_setpull, | ||
454 | .get_pull = exynos4_gpio_getpull, | ||
455 | .set_config = samsung_gpio_setcfg_4bit, | ||
456 | .get_config = samsung_gpio_getcfg_4bit, | ||
457 | }; | ||
458 | |||
459 | #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) | ||
460 | static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = { | ||
461 | .cfg_eint = 0x3, | ||
462 | .set_config = s5p64x0_gpio_setcfg_rbank, | ||
463 | .get_config = samsung_gpio_getcfg_4bit, | ||
464 | .set_pull = samsung_gpio_setpull_updown, | ||
465 | .get_pull = samsung_gpio_getpull_updown, | ||
466 | }; | ||
467 | #endif | ||
468 | |||
469 | static struct samsung_gpio_cfg samsung_gpio_cfgs[] = { | ||
470 | { | ||
471 | .cfg_eint = 0x0, | ||
472 | }, { | ||
473 | .cfg_eint = 0x3, | ||
474 | }, { | ||
475 | .cfg_eint = 0x7, | ||
476 | }, { | ||
477 | .cfg_eint = 0xF, | ||
478 | }, { | ||
479 | .cfg_eint = 0x0, | ||
480 | .set_config = samsung_gpio_setcfg_2bit, | ||
481 | .get_config = samsung_gpio_getcfg_2bit, | ||
482 | }, { | ||
483 | .cfg_eint = 0x2, | ||
484 | .set_config = samsung_gpio_setcfg_2bit, | ||
485 | .get_config = samsung_gpio_getcfg_2bit, | ||
486 | }, { | ||
487 | .cfg_eint = 0x3, | ||
488 | .set_config = samsung_gpio_setcfg_2bit, | ||
489 | .get_config = samsung_gpio_getcfg_2bit, | ||
490 | }, { | ||
491 | .set_config = samsung_gpio_setcfg_2bit, | ||
492 | .get_config = samsung_gpio_getcfg_2bit, | ||
493 | }, { | ||
494 | .set_pull = exynos4_gpio_setpull, | ||
495 | .get_pull = exynos4_gpio_getpull, | ||
496 | }, { | ||
497 | .cfg_eint = 0x3, | ||
498 | .set_pull = exynos4_gpio_setpull, | ||
499 | .get_pull = exynos4_gpio_getpull, | ||
500 | } | ||
501 | }; | ||
502 | |||
503 | /* | ||
504 | * Default routines for controlling GPIO, based on the original S3C24XX | ||
505 | * GPIO functions which deal with the case where each gpio bank of the | ||
506 | * chip is as following: | ||
507 | * | ||
508 | * base + 0x00: Control register, 2 bits per gpio | ||
509 | * gpio n: 2 bits starting at (2*n) | ||
510 | * 00 = input, 01 = output, others mean special-function | ||
511 | * base + 0x04: Data register, 1 bit per gpio | ||
512 | * bit n: data bit n | ||
513 | */ | ||
514 | |||
515 | static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset) | ||
516 | { | ||
517 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
518 | void __iomem *base = ourchip->base; | ||
519 | unsigned long flags; | ||
520 | unsigned long con; | ||
521 | |||
522 | samsung_gpio_lock(ourchip, flags); | ||
523 | |||
524 | con = __raw_readl(base + 0x00); | ||
525 | con &= ~(3 << (offset * 2)); | ||
526 | |||
527 | __raw_writel(con, base + 0x00); | ||
528 | |||
529 | samsung_gpio_unlock(ourchip, flags); | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static int samsung_gpiolib_2bit_output(struct gpio_chip *chip, | ||
534 | unsigned offset, int value) | ||
535 | { | ||
536 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
537 | void __iomem *base = ourchip->base; | ||
538 | unsigned long flags; | ||
539 | unsigned long dat; | ||
540 | unsigned long con; | ||
541 | |||
542 | samsung_gpio_lock(ourchip, flags); | ||
543 | |||
544 | dat = __raw_readl(base + 0x04); | ||
545 | dat &= ~(1 << offset); | ||
546 | if (value) | ||
547 | dat |= 1 << offset; | ||
548 | __raw_writel(dat, base + 0x04); | ||
549 | |||
550 | con = __raw_readl(base + 0x00); | ||
551 | con &= ~(3 << (offset * 2)); | ||
552 | con |= 1 << (offset * 2); | ||
553 | |||
554 | __raw_writel(con, base + 0x00); | ||
555 | __raw_writel(dat, base + 0x04); | ||
556 | |||
557 | samsung_gpio_unlock(ourchip, flags); | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * The samsung_gpiolib_4bit routines are to control the gpio banks where | ||
563 | * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the | ||
564 | * following example: | ||
565 | * | ||
566 | * base + 0x00: Control register, 4 bits per gpio | ||
567 | * gpio n: 4 bits starting at (4*n) | ||
568 | * 0000 = input, 0001 = output, others mean special-function | ||
569 | * base + 0x04: Data register, 1 bit per gpio | ||
570 | * bit n: data bit n | ||
571 | * | ||
572 | * Note, since the data register is one bit per gpio and is at base + 0x4 | ||
573 | * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the | ||
574 | * state of the output. | ||
575 | */ | ||
576 | |||
577 | static int samsung_gpiolib_4bit_input(struct gpio_chip *chip, | ||
578 | unsigned int offset) | ||
579 | { | ||
580 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
581 | void __iomem *base = ourchip->base; | ||
582 | unsigned long con; | ||
583 | |||
584 | con = __raw_readl(base + GPIOCON_OFF); | ||
585 | con &= ~(0xf << con_4bit_shift(offset)); | ||
586 | __raw_writel(con, base + GPIOCON_OFF); | ||
587 | |||
588 | gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static int samsung_gpiolib_4bit_output(struct gpio_chip *chip, | ||
594 | unsigned int offset, int value) | ||
595 | { | ||
596 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
597 | void __iomem *base = ourchip->base; | ||
598 | unsigned long con; | ||
599 | unsigned long dat; | ||
600 | |||
601 | con = __raw_readl(base + GPIOCON_OFF); | ||
602 | con &= ~(0xf << con_4bit_shift(offset)); | ||
603 | con |= 0x1 << con_4bit_shift(offset); | ||
604 | |||
605 | dat = __raw_readl(base + GPIODAT_OFF); | ||
606 | |||
607 | if (value) | ||
608 | dat |= 1 << offset; | ||
609 | else | ||
610 | dat &= ~(1 << offset); | ||
611 | |||
612 | __raw_writel(dat, base + GPIODAT_OFF); | ||
613 | __raw_writel(con, base + GPIOCON_OFF); | ||
614 | __raw_writel(dat, base + GPIODAT_OFF); | ||
615 | |||
616 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | /* | ||
622 | * The next set of routines are for the case where the GPIO configuration | ||
623 | * registers are 4 bits per GPIO but there is more than one register (the | ||
624 | * bank has more than 8 GPIOs. | ||
625 | * | ||
626 | * This case is the similar to the 4 bit case, but the registers are as | ||
627 | * follows: | ||
628 | * | ||
629 | * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs) | ||
630 | * gpio n: 4 bits starting at (4*n) | ||
631 | * 0000 = input, 0001 = output, others mean special-function | ||
632 | * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs) | ||
633 | * gpio n: 4 bits starting at (4*n) | ||
634 | * 0000 = input, 0001 = output, others mean special-function | ||
635 | * base + 0x08: Data register, 1 bit per gpio | ||
636 | * bit n: data bit n | ||
637 | * | ||
638 | * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set | ||
639 | * routines we store the 'base + 0x4' address so that these routines see | ||
640 | * the data register at ourchip->base + 0x04. | ||
641 | */ | ||
642 | |||
643 | static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip, | ||
644 | unsigned int offset) | ||
645 | { | ||
646 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
647 | void __iomem *base = ourchip->base; | ||
648 | void __iomem *regcon = base; | ||
649 | unsigned long con; | ||
650 | |||
651 | if (offset > 7) | ||
652 | offset -= 8; | ||
653 | else | ||
654 | regcon -= 4; | ||
655 | |||
656 | con = __raw_readl(regcon); | ||
657 | con &= ~(0xf << con_4bit_shift(offset)); | ||
658 | __raw_writel(con, regcon); | ||
659 | |||
660 | gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con); | ||
661 | |||
662 | return 0; | ||
663 | } | ||
664 | |||
665 | static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip, | ||
666 | unsigned int offset, int value) | ||
667 | { | ||
668 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
669 | void __iomem *base = ourchip->base; | ||
670 | void __iomem *regcon = base; | ||
671 | unsigned long con; | ||
672 | unsigned long dat; | ||
673 | unsigned con_offset = offset; | ||
674 | |||
675 | if (con_offset > 7) | ||
676 | con_offset -= 8; | ||
677 | else | ||
678 | regcon -= 4; | ||
679 | |||
680 | con = __raw_readl(regcon); | ||
681 | con &= ~(0xf << con_4bit_shift(con_offset)); | ||
682 | con |= 0x1 << con_4bit_shift(con_offset); | ||
683 | |||
684 | dat = __raw_readl(base + GPIODAT_OFF); | ||
685 | |||
686 | if (value) | ||
687 | dat |= 1 << offset; | ||
688 | else | ||
689 | dat &= ~(1 << offset); | ||
690 | |||
691 | __raw_writel(dat, base + GPIODAT_OFF); | ||
692 | __raw_writel(con, regcon); | ||
693 | __raw_writel(dat, base + GPIODAT_OFF); | ||
694 | |||
695 | gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat); | ||
696 | |||
697 | return 0; | ||
698 | } | ||
699 | |||
700 | #ifdef CONFIG_PLAT_S3C24XX | ||
701 | /* The next set of routines are for the case of s3c24xx bank a */ | ||
702 | |||
703 | static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset) | ||
704 | { | ||
705 | return -EINVAL; | ||
706 | } | ||
707 | |||
708 | static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip, | ||
709 | unsigned offset, int value) | ||
710 | { | ||
711 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
712 | void __iomem *base = ourchip->base; | ||
713 | unsigned long flags; | ||
714 | unsigned long dat; | ||
715 | unsigned long con; | ||
716 | |||
717 | local_irq_save(flags); | ||
718 | |||
719 | con = __raw_readl(base + 0x00); | ||
720 | dat = __raw_readl(base + 0x04); | ||
721 | |||
722 | dat &= ~(1 << offset); | ||
723 | if (value) | ||
724 | dat |= 1 << offset; | ||
725 | |||
726 | __raw_writel(dat, base + 0x04); | ||
727 | |||
728 | con &= ~(1 << offset); | ||
729 | |||
730 | __raw_writel(con, base + 0x00); | ||
731 | __raw_writel(dat, base + 0x04); | ||
732 | |||
733 | local_irq_restore(flags); | ||
734 | return 0; | ||
735 | } | ||
736 | #endif | ||
737 | |||
738 | /* The next set of routines are for the case of s5p64x0 bank r */ | ||
739 | |||
740 | static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip, | ||
741 | unsigned int offset) | ||
742 | { | ||
743 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
744 | void __iomem *base = ourchip->base; | ||
745 | void __iomem *regcon = base; | ||
746 | unsigned long con; | ||
747 | unsigned long flags; | ||
748 | |||
749 | switch (offset) { | ||
750 | case 6: | ||
751 | offset += 1; | ||
752 | case 0: | ||
753 | case 1: | ||
754 | case 2: | ||
755 | case 3: | ||
756 | case 4: | ||
757 | case 5: | ||
758 | regcon -= 4; | ||
759 | break; | ||
760 | default: | ||
761 | offset -= 7; | ||
762 | break; | ||
763 | } | ||
764 | |||
765 | samsung_gpio_lock(ourchip, flags); | ||
766 | |||
767 | con = __raw_readl(regcon); | ||
768 | con &= ~(0xf << con_4bit_shift(offset)); | ||
769 | __raw_writel(con, regcon); | ||
770 | |||
771 | samsung_gpio_unlock(ourchip, flags); | ||
772 | |||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip, | ||
777 | unsigned int offset, int value) | ||
778 | { | ||
779 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
780 | void __iomem *base = ourchip->base; | ||
781 | void __iomem *regcon = base; | ||
782 | unsigned long con; | ||
783 | unsigned long dat; | ||
784 | unsigned long flags; | ||
785 | unsigned con_offset = offset; | ||
786 | |||
787 | switch (con_offset) { | ||
788 | case 6: | ||
789 | con_offset += 1; | ||
790 | case 0: | ||
791 | case 1: | ||
792 | case 2: | ||
793 | case 3: | ||
794 | case 4: | ||
795 | case 5: | ||
796 | regcon -= 4; | ||
797 | break; | ||
798 | default: | ||
799 | con_offset -= 7; | ||
800 | break; | ||
801 | } | ||
802 | |||
803 | samsung_gpio_lock(ourchip, flags); | ||
804 | |||
805 | con = __raw_readl(regcon); | ||
806 | con &= ~(0xf << con_4bit_shift(con_offset)); | ||
807 | con |= 0x1 << con_4bit_shift(con_offset); | ||
808 | |||
809 | dat = __raw_readl(base + GPIODAT_OFF); | ||
810 | if (value) | ||
811 | dat |= 1 << offset; | ||
812 | else | ||
813 | dat &= ~(1 << offset); | ||
814 | |||
815 | __raw_writel(con, regcon); | ||
816 | __raw_writel(dat, base + GPIODAT_OFF); | ||
817 | |||
818 | samsung_gpio_unlock(ourchip, flags); | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static void samsung_gpiolib_set(struct gpio_chip *chip, | ||
824 | unsigned offset, int value) | ||
825 | { | ||
826 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
827 | void __iomem *base = ourchip->base; | ||
828 | unsigned long flags; | ||
829 | unsigned long dat; | ||
830 | |||
831 | samsung_gpio_lock(ourchip, flags); | ||
832 | |||
833 | dat = __raw_readl(base + 0x04); | ||
834 | dat &= ~(1 << offset); | ||
835 | if (value) | ||
836 | dat |= 1 << offset; | ||
837 | __raw_writel(dat, base + 0x04); | ||
838 | |||
839 | samsung_gpio_unlock(ourchip, flags); | ||
840 | } | ||
841 | |||
842 | static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset) | ||
843 | { | ||
844 | struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip); | ||
845 | unsigned long val; | ||
846 | |||
847 | val = __raw_readl(ourchip->base + 0x04); | ||
848 | val >>= offset; | ||
849 | val &= 1; | ||
850 | |||
851 | return val; | ||
852 | } | ||
853 | |||
854 | /* | ||
855 | * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios | ||
856 | * for use with the configuration calls, and other parts of the s3c gpiolib | ||
857 | * support code. | ||
858 | * | ||
859 | * Not all s3c support code will need this, as some configurations of cpu | ||
860 | * may only support one or two different configuration options and have an | ||
861 | * easy gpio to samsung_gpio_chip mapping function. If this is the case, then | ||
862 | * the machine support file should provide its own samsung_gpiolib_getchip() | ||
863 | * and any other necessary functions. | ||
864 | */ | ||
865 | |||
866 | #ifdef CONFIG_S3C_GPIO_TRACK | ||
867 | struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END]; | ||
868 | |||
869 | static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip) | ||
870 | { | ||
871 | unsigned int gpn; | ||
872 | int i; | ||
873 | |||
874 | gpn = chip->chip.base; | ||
875 | for (i = 0; i < chip->chip.ngpio; i++, gpn++) { | ||
876 | BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios)); | ||
877 | s3c_gpios[gpn] = chip; | ||
878 | } | ||
879 | } | ||
880 | #endif /* CONFIG_S3C_GPIO_TRACK */ | ||
881 | |||
882 | /* | ||
883 | * samsung_gpiolib_add() - add the Samsung gpio_chip. | ||
884 | * @chip: The chip to register | ||
885 | * | ||
886 | * This is a wrapper to gpiochip_add() that takes our specific gpio chip | ||
887 | * information and makes the necessary alterations for the platform and | ||
888 | * notes the information for use with the configuration systems and any | ||
889 | * other parts of the system. | ||
890 | */ | ||
891 | |||
892 | static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) | ||
893 | { | ||
894 | struct gpio_chip *gc = &chip->chip; | ||
895 | int ret; | ||
896 | |||
897 | BUG_ON(!chip->base); | ||
898 | BUG_ON(!gc->label); | ||
899 | BUG_ON(!gc->ngpio); | ||
900 | |||
901 | spin_lock_init(&chip->lock); | ||
902 | |||
903 | if (!gc->direction_input) | ||
904 | gc->direction_input = samsung_gpiolib_2bit_input; | ||
905 | if (!gc->direction_output) | ||
906 | gc->direction_output = samsung_gpiolib_2bit_output; | ||
907 | if (!gc->set) | ||
908 | gc->set = samsung_gpiolib_set; | ||
909 | if (!gc->get) | ||
910 | gc->get = samsung_gpiolib_get; | ||
911 | |||
912 | #ifdef CONFIG_PM | ||
913 | if (chip->pm != NULL) { | ||
914 | if (!chip->pm->save || !chip->pm->resume) | ||
915 | printk(KERN_ERR "gpio: %s has missing PM functions\n", | ||
916 | gc->label); | ||
917 | } else | ||
918 | printk(KERN_ERR "gpio: %s has no PM function\n", gc->label); | ||
919 | #endif | ||
920 | |||
921 | /* gpiochip_add() prints own failure message on error. */ | ||
922 | ret = gpiochip_add(gc); | ||
923 | if (ret >= 0) | ||
924 | s3c_gpiolib_track(chip); | ||
925 | } | ||
926 | |||
927 | static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, | ||
928 | int nr_chips, void __iomem *base) | ||
929 | { | ||
930 | int i; | ||
931 | struct gpio_chip *gc = &chip->chip; | ||
932 | |||
933 | for (i = 0 ; i < nr_chips; i++, chip++) { | ||
934 | /* skip banks not present on SoC */ | ||
935 | if (chip->chip.base >= S3C_GPIO_END) | ||
936 | continue; | ||
937 | |||
938 | if (!chip->config) | ||
939 | chip->config = &s3c24xx_gpiocfg_default; | ||
940 | if (!chip->pm) | ||
941 | chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); | ||
942 | if ((base != NULL) && (chip->base == NULL)) | ||
943 | chip->base = base + ((i) * 0x10); | ||
944 | |||
945 | if (!gc->direction_input) | ||
946 | gc->direction_input = samsung_gpiolib_2bit_input; | ||
947 | if (!gc->direction_output) | ||
948 | gc->direction_output = samsung_gpiolib_2bit_output; | ||
949 | |||
950 | samsung_gpiolib_add(chip); | ||
951 | } | ||
952 | } | ||
953 | |||
954 | static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip, | ||
955 | int nr_chips, void __iomem *base, | ||
956 | unsigned int offset) | ||
957 | { | ||
958 | int i; | ||
959 | |||
960 | for (i = 0 ; i < nr_chips; i++, chip++) { | ||
961 | chip->chip.direction_input = samsung_gpiolib_2bit_input; | ||
962 | chip->chip.direction_output = samsung_gpiolib_2bit_output; | ||
963 | |||
964 | if (!chip->config) | ||
965 | chip->config = &samsung_gpio_cfgs[7]; | ||
966 | if (!chip->pm) | ||
967 | chip->pm = __gpio_pm(&samsung_gpio_pm_2bit); | ||
968 | if ((base != NULL) && (chip->base == NULL)) | ||
969 | chip->base = base + ((i) * offset); | ||
970 | |||
971 | samsung_gpiolib_add(chip); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | /* | ||
976 | * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config. | ||
977 | * @chip: The gpio chip that is being configured. | ||
978 | * @nr_chips: The no of chips (gpio ports) for the GPIO being configured. | ||
979 | * | ||
980 | * This helper deal with the GPIO cases where the control register has 4 bits | ||
981 | * of control per GPIO, generally in the form of: | ||
982 | * 0000 = Input | ||
983 | * 0001 = Output | ||
984 | * others = Special functions (dependent on bank) | ||
985 | * | ||
986 | * Note, since the code to deal with the case where there are two control | ||
987 | * registers instead of one, we do not have a separate set of function | ||
988 | * (samsung_gpiolib_add_4bit2_chips)for each case. | ||
989 | */ | ||
990 | |||
991 | static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip, | ||
992 | int nr_chips, void __iomem *base) | ||
993 | { | ||
994 | int i; | ||
995 | |||
996 | for (i = 0 ; i < nr_chips; i++, chip++) { | ||
997 | chip->chip.direction_input = samsung_gpiolib_4bit_input; | ||
998 | chip->chip.direction_output = samsung_gpiolib_4bit_output; | ||
999 | |||
1000 | if (!chip->config) | ||
1001 | chip->config = &samsung_gpio_cfgs[2]; | ||
1002 | if (!chip->pm) | ||
1003 | chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); | ||
1004 | if ((base != NULL) && (chip->base == NULL)) | ||
1005 | chip->base = base + ((i) * 0x20); | ||
1006 | |||
1007 | samsung_gpiolib_add(chip); | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip, | ||
1012 | int nr_chips) | ||
1013 | { | ||
1014 | for (; nr_chips > 0; nr_chips--, chip++) { | ||
1015 | chip->chip.direction_input = samsung_gpiolib_4bit2_input; | ||
1016 | chip->chip.direction_output = samsung_gpiolib_4bit2_output; | ||
1017 | |||
1018 | if (!chip->config) | ||
1019 | chip->config = &samsung_gpio_cfgs[2]; | ||
1020 | if (!chip->pm) | ||
1021 | chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); | ||
1022 | |||
1023 | samsung_gpiolib_add(chip); | ||
1024 | } | ||
1025 | } | ||
1026 | |||
1027 | static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip, | ||
1028 | int nr_chips) | ||
1029 | { | ||
1030 | for (; nr_chips > 0; nr_chips--, chip++) { | ||
1031 | chip->chip.direction_input = s5p64x0_gpiolib_rbank_input; | ||
1032 | chip->chip.direction_output = s5p64x0_gpiolib_rbank_output; | ||
1033 | |||
1034 | if (!chip->pm) | ||
1035 | chip->pm = __gpio_pm(&samsung_gpio_pm_4bit); | ||
1036 | |||
1037 | samsung_gpiolib_add(chip); | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset) | ||
1042 | { | ||
1043 | struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip); | ||
1044 | |||
1045 | return samsung_chip->irq_base + offset; | ||
1046 | } | ||
1047 | |||
1048 | #ifdef CONFIG_PLAT_S3C24XX | ||
1049 | static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset) | ||
1050 | { | ||
1051 | if (offset < 4) | ||
1052 | return IRQ_EINT0 + offset; | ||
1053 | |||
1054 | if (offset < 8) | ||
1055 | return IRQ_EINT4 + offset - 4; | ||
1056 | |||
1057 | return -EINVAL; | ||
1058 | } | ||
1059 | #endif | ||
1060 | |||
1061 | #ifdef CONFIG_PLAT_S3C64XX | ||
1062 | static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin) | ||
1063 | { | ||
1064 | return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO; | ||
1065 | } | ||
1066 | |||
1067 | static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin) | ||
1068 | { | ||
1069 | return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO; | ||
1070 | } | ||
1071 | #endif | ||
1072 | |||
1073 | struct samsung_gpio_chip s3c24xx_gpios[] = { | ||
1074 | #ifdef CONFIG_PLAT_S3C24XX | ||
1075 | { | ||
1076 | .config = &s3c24xx_gpiocfg_banka, | ||
1077 | .chip = { | ||
1078 | .base = S3C2410_GPA(0), | ||
1079 | .owner = THIS_MODULE, | ||
1080 | .label = "GPIOA", | ||
1081 | .ngpio = 24, | ||
1082 | .direction_input = s3c24xx_gpiolib_banka_input, | ||
1083 | .direction_output = s3c24xx_gpiolib_banka_output, | ||
1084 | }, | ||
1085 | }, { | ||
1086 | .chip = { | ||
1087 | .base = S3C2410_GPB(0), | ||
1088 | .owner = THIS_MODULE, | ||
1089 | .label = "GPIOB", | ||
1090 | .ngpio = 16, | ||
1091 | }, | ||
1092 | }, { | ||
1093 | .chip = { | ||
1094 | .base = S3C2410_GPC(0), | ||
1095 | .owner = THIS_MODULE, | ||
1096 | .label = "GPIOC", | ||
1097 | .ngpio = 16, | ||
1098 | }, | ||
1099 | }, { | ||
1100 | .chip = { | ||
1101 | .base = S3C2410_GPD(0), | ||
1102 | .owner = THIS_MODULE, | ||
1103 | .label = "GPIOD", | ||
1104 | .ngpio = 16, | ||
1105 | }, | ||
1106 | }, { | ||
1107 | .chip = { | ||
1108 | .base = S3C2410_GPE(0), | ||
1109 | .label = "GPIOE", | ||
1110 | .owner = THIS_MODULE, | ||
1111 | .ngpio = 16, | ||
1112 | }, | ||
1113 | }, { | ||
1114 | .chip = { | ||
1115 | .base = S3C2410_GPF(0), | ||
1116 | .owner = THIS_MODULE, | ||
1117 | .label = "GPIOF", | ||
1118 | .ngpio = 8, | ||
1119 | .to_irq = s3c24xx_gpiolib_fbank_to_irq, | ||
1120 | }, | ||
1121 | }, { | ||
1122 | .irq_base = IRQ_EINT8, | ||
1123 | .chip = { | ||
1124 | .base = S3C2410_GPG(0), | ||
1125 | .owner = THIS_MODULE, | ||
1126 | .label = "GPIOG", | ||
1127 | .ngpio = 16, | ||
1128 | .to_irq = samsung_gpiolib_to_irq, | ||
1129 | }, | ||
1130 | }, { | ||
1131 | .chip = { | ||
1132 | .base = S3C2410_GPH(0), | ||
1133 | .owner = THIS_MODULE, | ||
1134 | .label = "GPIOH", | ||
1135 | .ngpio = 11, | ||
1136 | }, | ||
1137 | }, | ||
1138 | /* GPIOS for the S3C2443 and later devices. */ | ||
1139 | { | ||
1140 | .base = S3C2440_GPJCON, | ||
1141 | .chip = { | ||
1142 | .base = S3C2410_GPJ(0), | ||
1143 | .owner = THIS_MODULE, | ||
1144 | .label = "GPIOJ", | ||
1145 | .ngpio = 16, | ||
1146 | }, | ||
1147 | }, { | ||
1148 | .base = S3C2443_GPKCON, | ||
1149 | .chip = { | ||
1150 | .base = S3C2410_GPK(0), | ||
1151 | .owner = THIS_MODULE, | ||
1152 | .label = "GPIOK", | ||
1153 | .ngpio = 16, | ||
1154 | }, | ||
1155 | }, { | ||
1156 | .base = S3C2443_GPLCON, | ||
1157 | .chip = { | ||
1158 | .base = S3C2410_GPL(0), | ||
1159 | .owner = THIS_MODULE, | ||
1160 | .label = "GPIOL", | ||
1161 | .ngpio = 15, | ||
1162 | }, | ||
1163 | }, { | ||
1164 | .base = S3C2443_GPMCON, | ||
1165 | .chip = { | ||
1166 | .base = S3C2410_GPM(0), | ||
1167 | .owner = THIS_MODULE, | ||
1168 | .label = "GPIOM", | ||
1169 | .ngpio = 2, | ||
1170 | }, | ||
1171 | }, | ||
1172 | #endif | ||
1173 | }; | ||
1174 | |||
1175 | /* | ||
1176 | * GPIO bank summary: | ||
1177 | * | ||
1178 | * Bank GPIOs Style SlpCon ExtInt Group | ||
1179 | * A 8 4Bit Yes 1 | ||
1180 | * B 7 4Bit Yes 1 | ||
1181 | * C 8 4Bit Yes 2 | ||
1182 | * D 5 4Bit Yes 3 | ||
1183 | * E 5 4Bit Yes None | ||
1184 | * F 16 2Bit Yes 4 [1] | ||
1185 | * G 7 4Bit Yes 5 | ||
1186 | * H 10 4Bit[2] Yes 6 | ||
1187 | * I 16 2Bit Yes None | ||
1188 | * J 12 2Bit Yes None | ||
1189 | * K 16 4Bit[2] No None | ||
1190 | * L 15 4Bit[2] No None | ||
1191 | * M 6 4Bit No IRQ_EINT | ||
1192 | * N 16 2Bit No IRQ_EINT | ||
1193 | * O 16 2Bit Yes 7 | ||
1194 | * P 15 2Bit Yes 8 | ||
1195 | * Q 9 2Bit Yes 9 | ||
1196 | * | ||
1197 | * [1] BANKF pins 14,15 do not form part of the external interrupt sources | ||
1198 | * [2] BANK has two control registers, GPxCON0 and GPxCON1 | ||
1199 | */ | ||
1200 | |||
1201 | static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = { | ||
1202 | #ifdef CONFIG_PLAT_S3C64XX | ||
1203 | { | ||
1204 | .chip = { | ||
1205 | .base = S3C64XX_GPA(0), | ||
1206 | .ngpio = S3C64XX_GPIO_A_NR, | ||
1207 | .label = "GPA", | ||
1208 | }, | ||
1209 | }, { | ||
1210 | .chip = { | ||
1211 | .base = S3C64XX_GPB(0), | ||
1212 | .ngpio = S3C64XX_GPIO_B_NR, | ||
1213 | .label = "GPB", | ||
1214 | }, | ||
1215 | }, { | ||
1216 | .chip = { | ||
1217 | .base = S3C64XX_GPC(0), | ||
1218 | .ngpio = S3C64XX_GPIO_C_NR, | ||
1219 | .label = "GPC", | ||
1220 | }, | ||
1221 | }, { | ||
1222 | .chip = { | ||
1223 | .base = S3C64XX_GPD(0), | ||
1224 | .ngpio = S3C64XX_GPIO_D_NR, | ||
1225 | .label = "GPD", | ||
1226 | }, | ||
1227 | }, { | ||
1228 | .config = &samsung_gpio_cfgs[0], | ||
1229 | .chip = { | ||
1230 | .base = S3C64XX_GPE(0), | ||
1231 | .ngpio = S3C64XX_GPIO_E_NR, | ||
1232 | .label = "GPE", | ||
1233 | }, | ||
1234 | }, { | ||
1235 | .base = S3C64XX_GPG_BASE, | ||
1236 | .chip = { | ||
1237 | .base = S3C64XX_GPG(0), | ||
1238 | .ngpio = S3C64XX_GPIO_G_NR, | ||
1239 | .label = "GPG", | ||
1240 | }, | ||
1241 | }, { | ||
1242 | .base = S3C64XX_GPM_BASE, | ||
1243 | .config = &samsung_gpio_cfgs[1], | ||
1244 | .chip = { | ||
1245 | .base = S3C64XX_GPM(0), | ||
1246 | .ngpio = S3C64XX_GPIO_M_NR, | ||
1247 | .label = "GPM", | ||
1248 | .to_irq = s3c64xx_gpiolib_mbank_to_irq, | ||
1249 | }, | ||
1250 | }, | ||
1251 | #endif | ||
1252 | }; | ||
1253 | |||
1254 | static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = { | ||
1255 | #ifdef CONFIG_PLAT_S3C64XX | ||
1256 | { | ||
1257 | .base = S3C64XX_GPH_BASE + 0x4, | ||
1258 | .chip = { | ||
1259 | .base = S3C64XX_GPH(0), | ||
1260 | .ngpio = S3C64XX_GPIO_H_NR, | ||
1261 | .label = "GPH", | ||
1262 | }, | ||
1263 | }, { | ||
1264 | .base = S3C64XX_GPK_BASE + 0x4, | ||
1265 | .config = &samsung_gpio_cfgs[0], | ||
1266 | .chip = { | ||
1267 | .base = S3C64XX_GPK(0), | ||
1268 | .ngpio = S3C64XX_GPIO_K_NR, | ||
1269 | .label = "GPK", | ||
1270 | }, | ||
1271 | }, { | ||
1272 | .base = S3C64XX_GPL_BASE + 0x4, | ||
1273 | .config = &samsung_gpio_cfgs[1], | ||
1274 | .chip = { | ||
1275 | .base = S3C64XX_GPL(0), | ||
1276 | .ngpio = S3C64XX_GPIO_L_NR, | ||
1277 | .label = "GPL", | ||
1278 | .to_irq = s3c64xx_gpiolib_lbank_to_irq, | ||
1279 | }, | ||
1280 | }, | ||
1281 | #endif | ||
1282 | }; | ||
1283 | |||
1284 | static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { | ||
1285 | #ifdef CONFIG_PLAT_S3C64XX | ||
1286 | { | ||
1287 | .base = S3C64XX_GPF_BASE, | ||
1288 | .config = &samsung_gpio_cfgs[6], | ||
1289 | .chip = { | ||
1290 | .base = S3C64XX_GPF(0), | ||
1291 | .ngpio = S3C64XX_GPIO_F_NR, | ||
1292 | .label = "GPF", | ||
1293 | }, | ||
1294 | }, { | ||
1295 | .config = &samsung_gpio_cfgs[7], | ||
1296 | .chip = { | ||
1297 | .base = S3C64XX_GPI(0), | ||
1298 | .ngpio = S3C64XX_GPIO_I_NR, | ||
1299 | .label = "GPI", | ||
1300 | }, | ||
1301 | }, { | ||
1302 | .config = &samsung_gpio_cfgs[7], | ||
1303 | .chip = { | ||
1304 | .base = S3C64XX_GPJ(0), | ||
1305 | .ngpio = S3C64XX_GPIO_J_NR, | ||
1306 | .label = "GPJ", | ||
1307 | }, | ||
1308 | }, { | ||
1309 | .config = &samsung_gpio_cfgs[6], | ||
1310 | .chip = { | ||
1311 | .base = S3C64XX_GPO(0), | ||
1312 | .ngpio = S3C64XX_GPIO_O_NR, | ||
1313 | .label = "GPO", | ||
1314 | }, | ||
1315 | }, { | ||
1316 | .config = &samsung_gpio_cfgs[6], | ||
1317 | .chip = { | ||
1318 | .base = S3C64XX_GPP(0), | ||
1319 | .ngpio = S3C64XX_GPIO_P_NR, | ||
1320 | .label = "GPP", | ||
1321 | }, | ||
1322 | }, { | ||
1323 | .config = &samsung_gpio_cfgs[6], | ||
1324 | .chip = { | ||
1325 | .base = S3C64XX_GPQ(0), | ||
1326 | .ngpio = S3C64XX_GPIO_Q_NR, | ||
1327 | .label = "GPQ", | ||
1328 | }, | ||
1329 | }, { | ||
1330 | .base = S3C64XX_GPN_BASE, | ||
1331 | .irq_base = IRQ_EINT(0), | ||
1332 | .config = &samsung_gpio_cfgs[5], | ||
1333 | .chip = { | ||
1334 | .base = S3C64XX_GPN(0), | ||
1335 | .ngpio = S3C64XX_GPIO_N_NR, | ||
1336 | .label = "GPN", | ||
1337 | .to_irq = samsung_gpiolib_to_irq, | ||
1338 | }, | ||
1339 | }, | ||
1340 | #endif | ||
1341 | }; | ||
1342 | |||
1343 | /* | ||
1344 | * S5P6440 GPIO bank summary: | ||
1345 | * | ||
1346 | * Bank GPIOs Style SlpCon ExtInt Group | ||
1347 | * A 6 4Bit Yes 1 | ||
1348 | * B 7 4Bit Yes 1 | ||
1349 | * C 8 4Bit Yes 2 | ||
1350 | * F 2 2Bit Yes 4 [1] | ||
1351 | * G 7 4Bit Yes 5 | ||
1352 | * H 10 4Bit[2] Yes 6 | ||
1353 | * I 16 2Bit Yes None | ||
1354 | * J 12 2Bit Yes None | ||
1355 | * N 16 2Bit No IRQ_EINT | ||
1356 | * P 8 2Bit Yes 8 | ||
1357 | * R 15 4Bit[2] Yes 8 | ||
1358 | */ | ||
1359 | |||
1360 | static struct samsung_gpio_chip s5p6440_gpios_4bit[] = { | ||
1361 | #ifdef CONFIG_CPU_S5P6440 | ||
1362 | { | ||
1363 | .chip = { | ||
1364 | .base = S5P6440_GPA(0), | ||
1365 | .ngpio = S5P6440_GPIO_A_NR, | ||
1366 | .label = "GPA", | ||
1367 | }, | ||
1368 | }, { | ||
1369 | .chip = { | ||
1370 | .base = S5P6440_GPB(0), | ||
1371 | .ngpio = S5P6440_GPIO_B_NR, | ||
1372 | .label = "GPB", | ||
1373 | }, | ||
1374 | }, { | ||
1375 | .chip = { | ||
1376 | .base = S5P6440_GPC(0), | ||
1377 | .ngpio = S5P6440_GPIO_C_NR, | ||
1378 | .label = "GPC", | ||
1379 | }, | ||
1380 | }, { | ||
1381 | .base = S5P64X0_GPG_BASE, | ||
1382 | .chip = { | ||
1383 | .base = S5P6440_GPG(0), | ||
1384 | .ngpio = S5P6440_GPIO_G_NR, | ||
1385 | .label = "GPG", | ||
1386 | }, | ||
1387 | }, | ||
1388 | #endif | ||
1389 | }; | ||
1390 | |||
1391 | static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = { | ||
1392 | #ifdef CONFIG_CPU_S5P6440 | ||
1393 | { | ||
1394 | .base = S5P64X0_GPH_BASE + 0x4, | ||
1395 | .chip = { | ||
1396 | .base = S5P6440_GPH(0), | ||
1397 | .ngpio = S5P6440_GPIO_H_NR, | ||
1398 | .label = "GPH", | ||
1399 | }, | ||
1400 | }, | ||
1401 | #endif | ||
1402 | }; | ||
1403 | |||
1404 | static struct samsung_gpio_chip s5p6440_gpios_rbank[] = { | ||
1405 | #ifdef CONFIG_CPU_S5P6440 | ||
1406 | { | ||
1407 | .base = S5P64X0_GPR_BASE + 0x4, | ||
1408 | .config = &s5p64x0_gpio_cfg_rbank, | ||
1409 | .chip = { | ||
1410 | .base = S5P6440_GPR(0), | ||
1411 | .ngpio = S5P6440_GPIO_R_NR, | ||
1412 | .label = "GPR", | ||
1413 | }, | ||
1414 | }, | ||
1415 | #endif | ||
1416 | }; | ||
1417 | |||
1418 | static struct samsung_gpio_chip s5p6440_gpios_2bit[] = { | ||
1419 | #ifdef CONFIG_CPU_S5P6440 | ||
1420 | { | ||
1421 | .base = S5P64X0_GPF_BASE, | ||
1422 | .config = &samsung_gpio_cfgs[6], | ||
1423 | .chip = { | ||
1424 | .base = S5P6440_GPF(0), | ||
1425 | .ngpio = S5P6440_GPIO_F_NR, | ||
1426 | .label = "GPF", | ||
1427 | }, | ||
1428 | }, { | ||
1429 | .base = S5P64X0_GPI_BASE, | ||
1430 | .config = &samsung_gpio_cfgs[4], | ||
1431 | .chip = { | ||
1432 | .base = S5P6440_GPI(0), | ||
1433 | .ngpio = S5P6440_GPIO_I_NR, | ||
1434 | .label = "GPI", | ||
1435 | }, | ||
1436 | }, { | ||
1437 | .base = S5P64X0_GPJ_BASE, | ||
1438 | .config = &samsung_gpio_cfgs[4], | ||
1439 | .chip = { | ||
1440 | .base = S5P6440_GPJ(0), | ||
1441 | .ngpio = S5P6440_GPIO_J_NR, | ||
1442 | .label = "GPJ", | ||
1443 | }, | ||
1444 | }, { | ||
1445 | .base = S5P64X0_GPN_BASE, | ||
1446 | .config = &samsung_gpio_cfgs[5], | ||
1447 | .chip = { | ||
1448 | .base = S5P6440_GPN(0), | ||
1449 | .ngpio = S5P6440_GPIO_N_NR, | ||
1450 | .label = "GPN", | ||
1451 | }, | ||
1452 | }, { | ||
1453 | .base = S5P64X0_GPP_BASE, | ||
1454 | .config = &samsung_gpio_cfgs[6], | ||
1455 | .chip = { | ||
1456 | .base = S5P6440_GPP(0), | ||
1457 | .ngpio = S5P6440_GPIO_P_NR, | ||
1458 | .label = "GPP", | ||
1459 | }, | ||
1460 | }, | ||
1461 | #endif | ||
1462 | }; | ||
1463 | |||
1464 | /* | ||
1465 | * S5P6450 GPIO bank summary: | ||
1466 | * | ||
1467 | * Bank GPIOs Style SlpCon ExtInt Group | ||
1468 | * A 6 4Bit Yes 1 | ||
1469 | * B 7 4Bit Yes 1 | ||
1470 | * C 8 4Bit Yes 2 | ||
1471 | * D 8 4Bit Yes None | ||
1472 | * F 2 2Bit Yes None | ||
1473 | * G 14 4Bit[2] Yes 5 | ||
1474 | * H 10 4Bit[2] Yes 6 | ||
1475 | * I 16 2Bit Yes None | ||
1476 | * J 12 2Bit Yes None | ||
1477 | * K 5 4Bit Yes None | ||
1478 | * N 16 2Bit No IRQ_EINT | ||
1479 | * P 11 2Bit Yes 8 | ||
1480 | * Q 14 2Bit Yes None | ||
1481 | * R 15 4Bit[2] Yes None | ||
1482 | * S 8 2Bit Yes None | ||
1483 | * | ||
1484 | * [1] BANKF pins 14,15 do not form part of the external interrupt sources | ||
1485 | * [2] BANK has two control registers, GPxCON0 and GPxCON1 | ||
1486 | */ | ||
1487 | |||
1488 | static struct samsung_gpio_chip s5p6450_gpios_4bit[] = { | ||
1489 | #ifdef CONFIG_CPU_S5P6450 | ||
1490 | { | ||
1491 | .chip = { | ||
1492 | .base = S5P6450_GPA(0), | ||
1493 | .ngpio = S5P6450_GPIO_A_NR, | ||
1494 | .label = "GPA", | ||
1495 | }, | ||
1496 | }, { | ||
1497 | .chip = { | ||
1498 | .base = S5P6450_GPB(0), | ||
1499 | .ngpio = S5P6450_GPIO_B_NR, | ||
1500 | .label = "GPB", | ||
1501 | }, | ||
1502 | }, { | ||
1503 | .chip = { | ||
1504 | .base = S5P6450_GPC(0), | ||
1505 | .ngpio = S5P6450_GPIO_C_NR, | ||
1506 | .label = "GPC", | ||
1507 | }, | ||
1508 | }, { | ||
1509 | .chip = { | ||
1510 | .base = S5P6450_GPD(0), | ||
1511 | .ngpio = S5P6450_GPIO_D_NR, | ||
1512 | .label = "GPD", | ||
1513 | }, | ||
1514 | }, { | ||
1515 | .base = S5P6450_GPK_BASE, | ||
1516 | .chip = { | ||
1517 | .base = S5P6450_GPK(0), | ||
1518 | .ngpio = S5P6450_GPIO_K_NR, | ||
1519 | .label = "GPK", | ||
1520 | }, | ||
1521 | }, | ||
1522 | #endif | ||
1523 | }; | ||
1524 | |||
1525 | static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = { | ||
1526 | #ifdef CONFIG_CPU_S5P6450 | ||
1527 | { | ||
1528 | .base = S5P64X0_GPG_BASE + 0x4, | ||
1529 | .chip = { | ||
1530 | .base = S5P6450_GPG(0), | ||
1531 | .ngpio = S5P6450_GPIO_G_NR, | ||
1532 | .label = "GPG", | ||
1533 | }, | ||
1534 | }, { | ||
1535 | .base = S5P64X0_GPH_BASE + 0x4, | ||
1536 | .chip = { | ||
1537 | .base = S5P6450_GPH(0), | ||
1538 | .ngpio = S5P6450_GPIO_H_NR, | ||
1539 | .label = "GPH", | ||
1540 | }, | ||
1541 | }, | ||
1542 | #endif | ||
1543 | }; | ||
1544 | |||
1545 | static struct samsung_gpio_chip s5p6450_gpios_rbank[] = { | ||
1546 | #ifdef CONFIG_CPU_S5P6450 | ||
1547 | { | ||
1548 | .base = S5P64X0_GPR_BASE + 0x4, | ||
1549 | .config = &s5p64x0_gpio_cfg_rbank, | ||
1550 | .chip = { | ||
1551 | .base = S5P6450_GPR(0), | ||
1552 | .ngpio = S5P6450_GPIO_R_NR, | ||
1553 | .label = "GPR", | ||
1554 | }, | ||
1555 | }, | ||
1556 | #endif | ||
1557 | }; | ||
1558 | |||
1559 | static struct samsung_gpio_chip s5p6450_gpios_2bit[] = { | ||
1560 | #ifdef CONFIG_CPU_S5P6450 | ||
1561 | { | ||
1562 | .base = S5P64X0_GPF_BASE, | ||
1563 | .config = &samsung_gpio_cfgs[6], | ||
1564 | .chip = { | ||
1565 | .base = S5P6450_GPF(0), | ||
1566 | .ngpio = S5P6450_GPIO_F_NR, | ||
1567 | .label = "GPF", | ||
1568 | }, | ||
1569 | }, { | ||
1570 | .base = S5P64X0_GPI_BASE, | ||
1571 | .config = &samsung_gpio_cfgs[4], | ||
1572 | .chip = { | ||
1573 | .base = S5P6450_GPI(0), | ||
1574 | .ngpio = S5P6450_GPIO_I_NR, | ||
1575 | .label = "GPI", | ||
1576 | }, | ||
1577 | }, { | ||
1578 | .base = S5P64X0_GPJ_BASE, | ||
1579 | .config = &samsung_gpio_cfgs[4], | ||
1580 | .chip = { | ||
1581 | .base = S5P6450_GPJ(0), | ||
1582 | .ngpio = S5P6450_GPIO_J_NR, | ||
1583 | .label = "GPJ", | ||
1584 | }, | ||
1585 | }, { | ||
1586 | .base = S5P64X0_GPN_BASE, | ||
1587 | .config = &samsung_gpio_cfgs[5], | ||
1588 | .chip = { | ||
1589 | .base = S5P6450_GPN(0), | ||
1590 | .ngpio = S5P6450_GPIO_N_NR, | ||
1591 | .label = "GPN", | ||
1592 | }, | ||
1593 | }, { | ||
1594 | .base = S5P64X0_GPP_BASE, | ||
1595 | .config = &samsung_gpio_cfgs[6], | ||
1596 | .chip = { | ||
1597 | .base = S5P6450_GPP(0), | ||
1598 | .ngpio = S5P6450_GPIO_P_NR, | ||
1599 | .label = "GPP", | ||
1600 | }, | ||
1601 | }, { | ||
1602 | .base = S5P6450_GPQ_BASE, | ||
1603 | .config = &samsung_gpio_cfgs[5], | ||
1604 | .chip = { | ||
1605 | .base = S5P6450_GPQ(0), | ||
1606 | .ngpio = S5P6450_GPIO_Q_NR, | ||
1607 | .label = "GPQ", | ||
1608 | }, | ||
1609 | }, { | ||
1610 | .base = S5P6450_GPS_BASE, | ||
1611 | .config = &samsung_gpio_cfgs[6], | ||
1612 | .chip = { | ||
1613 | .base = S5P6450_GPS(0), | ||
1614 | .ngpio = S5P6450_GPIO_S_NR, | ||
1615 | .label = "GPS", | ||
1616 | }, | ||
1617 | }, | ||
1618 | #endif | ||
1619 | }; | ||
1620 | |||
1621 | /* | ||
1622 | * S5PC100 GPIO bank summary: | ||
1623 | * | ||
1624 | * Bank GPIOs Style INT Type | ||
1625 | * A0 8 4Bit GPIO_INT0 | ||
1626 | * A1 5 4Bit GPIO_INT1 | ||
1627 | * B 8 4Bit GPIO_INT2 | ||
1628 | * C 5 4Bit GPIO_INT3 | ||
1629 | * D 7 4Bit GPIO_INT4 | ||
1630 | * E0 8 4Bit GPIO_INT5 | ||
1631 | * E1 6 4Bit GPIO_INT6 | ||
1632 | * F0 8 4Bit GPIO_INT7 | ||
1633 | * F1 8 4Bit GPIO_INT8 | ||
1634 | * F2 8 4Bit GPIO_INT9 | ||
1635 | * F3 4 4Bit GPIO_INT10 | ||
1636 | * G0 8 4Bit GPIO_INT11 | ||
1637 | * G1 3 4Bit GPIO_INT12 | ||
1638 | * G2 7 4Bit GPIO_INT13 | ||
1639 | * G3 7 4Bit GPIO_INT14 | ||
1640 | * H0 8 4Bit WKUP_INT | ||
1641 | * H1 8 4Bit WKUP_INT | ||
1642 | * H2 8 4Bit WKUP_INT | ||
1643 | * H3 8 4Bit WKUP_INT | ||
1644 | * I 8 4Bit GPIO_INT15 | ||
1645 | * J0 8 4Bit GPIO_INT16 | ||
1646 | * J1 5 4Bit GPIO_INT17 | ||
1647 | * J2 8 4Bit GPIO_INT18 | ||
1648 | * J3 8 4Bit GPIO_INT19 | ||
1649 | * J4 4 4Bit GPIO_INT20 | ||
1650 | * K0 8 4Bit None | ||
1651 | * K1 6 4Bit None | ||
1652 | * K2 8 4Bit None | ||
1653 | * K3 8 4Bit None | ||
1654 | * L0 8 4Bit None | ||
1655 | * L1 8 4Bit None | ||
1656 | * L2 8 4Bit None | ||
1657 | * L3 8 4Bit None | ||
1658 | */ | ||
1659 | |||
1660 | static struct samsung_gpio_chip s5pc100_gpios_4bit[] = { | ||
1661 | #ifdef CONFIG_CPU_S5PC100 | ||
1662 | { | ||
1663 | .chip = { | ||
1664 | .base = S5PC100_GPA0(0), | ||
1665 | .ngpio = S5PC100_GPIO_A0_NR, | ||
1666 | .label = "GPA0", | ||
1667 | }, | ||
1668 | }, { | ||
1669 | .chip = { | ||
1670 | .base = S5PC100_GPA1(0), | ||
1671 | .ngpio = S5PC100_GPIO_A1_NR, | ||
1672 | .label = "GPA1", | ||
1673 | }, | ||
1674 | }, { | ||
1675 | .chip = { | ||
1676 | .base = S5PC100_GPB(0), | ||
1677 | .ngpio = S5PC100_GPIO_B_NR, | ||
1678 | .label = "GPB", | ||
1679 | }, | ||
1680 | }, { | ||
1681 | .chip = { | ||
1682 | .base = S5PC100_GPC(0), | ||
1683 | .ngpio = S5PC100_GPIO_C_NR, | ||
1684 | .label = "GPC", | ||
1685 | }, | ||
1686 | }, { | ||
1687 | .chip = { | ||
1688 | .base = S5PC100_GPD(0), | ||
1689 | .ngpio = S5PC100_GPIO_D_NR, | ||
1690 | .label = "GPD", | ||
1691 | }, | ||
1692 | }, { | ||
1693 | .chip = { | ||
1694 | .base = S5PC100_GPE0(0), | ||
1695 | .ngpio = S5PC100_GPIO_E0_NR, | ||
1696 | .label = "GPE0", | ||
1697 | }, | ||
1698 | }, { | ||
1699 | .chip = { | ||
1700 | .base = S5PC100_GPE1(0), | ||
1701 | .ngpio = S5PC100_GPIO_E1_NR, | ||
1702 | .label = "GPE1", | ||
1703 | }, | ||
1704 | }, { | ||
1705 | .chip = { | ||
1706 | .base = S5PC100_GPF0(0), | ||
1707 | .ngpio = S5PC100_GPIO_F0_NR, | ||
1708 | .label = "GPF0", | ||
1709 | }, | ||
1710 | }, { | ||
1711 | .chip = { | ||
1712 | .base = S5PC100_GPF1(0), | ||
1713 | .ngpio = S5PC100_GPIO_F1_NR, | ||
1714 | .label = "GPF1", | ||
1715 | }, | ||
1716 | }, { | ||
1717 | .chip = { | ||
1718 | .base = S5PC100_GPF2(0), | ||
1719 | .ngpio = S5PC100_GPIO_F2_NR, | ||
1720 | .label = "GPF2", | ||
1721 | }, | ||
1722 | }, { | ||
1723 | .chip = { | ||
1724 | .base = S5PC100_GPF3(0), | ||
1725 | .ngpio = S5PC100_GPIO_F3_NR, | ||
1726 | .label = "GPF3", | ||
1727 | }, | ||
1728 | }, { | ||
1729 | .chip = { | ||
1730 | .base = S5PC100_GPG0(0), | ||
1731 | .ngpio = S5PC100_GPIO_G0_NR, | ||
1732 | .label = "GPG0", | ||
1733 | }, | ||
1734 | }, { | ||
1735 | .chip = { | ||
1736 | .base = S5PC100_GPG1(0), | ||
1737 | .ngpio = S5PC100_GPIO_G1_NR, | ||
1738 | .label = "GPG1", | ||
1739 | }, | ||
1740 | }, { | ||
1741 | .chip = { | ||
1742 | .base = S5PC100_GPG2(0), | ||
1743 | .ngpio = S5PC100_GPIO_G2_NR, | ||
1744 | .label = "GPG2", | ||
1745 | }, | ||
1746 | }, { | ||
1747 | .chip = { | ||
1748 | .base = S5PC100_GPG3(0), | ||
1749 | .ngpio = S5PC100_GPIO_G3_NR, | ||
1750 | .label = "GPG3", | ||
1751 | }, | ||
1752 | }, { | ||
1753 | .chip = { | ||
1754 | .base = S5PC100_GPI(0), | ||
1755 | .ngpio = S5PC100_GPIO_I_NR, | ||
1756 | .label = "GPI", | ||
1757 | }, | ||
1758 | }, { | ||
1759 | .chip = { | ||
1760 | .base = S5PC100_GPJ0(0), | ||
1761 | .ngpio = S5PC100_GPIO_J0_NR, | ||
1762 | .label = "GPJ0", | ||
1763 | }, | ||
1764 | }, { | ||
1765 | .chip = { | ||
1766 | .base = S5PC100_GPJ1(0), | ||
1767 | .ngpio = S5PC100_GPIO_J1_NR, | ||
1768 | .label = "GPJ1", | ||
1769 | }, | ||
1770 | }, { | ||
1771 | .chip = { | ||
1772 | .base = S5PC100_GPJ2(0), | ||
1773 | .ngpio = S5PC100_GPIO_J2_NR, | ||
1774 | .label = "GPJ2", | ||
1775 | }, | ||
1776 | }, { | ||
1777 | .chip = { | ||
1778 | .base = S5PC100_GPJ3(0), | ||
1779 | .ngpio = S5PC100_GPIO_J3_NR, | ||
1780 | .label = "GPJ3", | ||
1781 | }, | ||
1782 | }, { | ||
1783 | .chip = { | ||
1784 | .base = S5PC100_GPJ4(0), | ||
1785 | .ngpio = S5PC100_GPIO_J4_NR, | ||
1786 | .label = "GPJ4", | ||
1787 | }, | ||
1788 | }, { | ||
1789 | .chip = { | ||
1790 | .base = S5PC100_GPK0(0), | ||
1791 | .ngpio = S5PC100_GPIO_K0_NR, | ||
1792 | .label = "GPK0", | ||
1793 | }, | ||
1794 | }, { | ||
1795 | .chip = { | ||
1796 | .base = S5PC100_GPK1(0), | ||
1797 | .ngpio = S5PC100_GPIO_K1_NR, | ||
1798 | .label = "GPK1", | ||
1799 | }, | ||
1800 | }, { | ||
1801 | .chip = { | ||
1802 | .base = S5PC100_GPK2(0), | ||
1803 | .ngpio = S5PC100_GPIO_K2_NR, | ||
1804 | .label = "GPK2", | ||
1805 | }, | ||
1806 | }, { | ||
1807 | .chip = { | ||
1808 | .base = S5PC100_GPK3(0), | ||
1809 | .ngpio = S5PC100_GPIO_K3_NR, | ||
1810 | .label = "GPK3", | ||
1811 | }, | ||
1812 | }, { | ||
1813 | .chip = { | ||
1814 | .base = S5PC100_GPL0(0), | ||
1815 | .ngpio = S5PC100_GPIO_L0_NR, | ||
1816 | .label = "GPL0", | ||
1817 | }, | ||
1818 | }, { | ||
1819 | .chip = { | ||
1820 | .base = S5PC100_GPL1(0), | ||
1821 | .ngpio = S5PC100_GPIO_L1_NR, | ||
1822 | .label = "GPL1", | ||
1823 | }, | ||
1824 | }, { | ||
1825 | .chip = { | ||
1826 | .base = S5PC100_GPL2(0), | ||
1827 | .ngpio = S5PC100_GPIO_L2_NR, | ||
1828 | .label = "GPL2", | ||
1829 | }, | ||
1830 | }, { | ||
1831 | .chip = { | ||
1832 | .base = S5PC100_GPL3(0), | ||
1833 | .ngpio = S5PC100_GPIO_L3_NR, | ||
1834 | .label = "GPL3", | ||
1835 | }, | ||
1836 | }, { | ||
1837 | .chip = { | ||
1838 | .base = S5PC100_GPL4(0), | ||
1839 | .ngpio = S5PC100_GPIO_L4_NR, | ||
1840 | .label = "GPL4", | ||
1841 | }, | ||
1842 | }, { | ||
1843 | .base = (S5P_VA_GPIO + 0xC00), | ||
1844 | .irq_base = IRQ_EINT(0), | ||
1845 | .chip = { | ||
1846 | .base = S5PC100_GPH0(0), | ||
1847 | .ngpio = S5PC100_GPIO_H0_NR, | ||
1848 | .label = "GPH0", | ||
1849 | .to_irq = samsung_gpiolib_to_irq, | ||
1850 | }, | ||
1851 | }, { | ||
1852 | .base = (S5P_VA_GPIO + 0xC20), | ||
1853 | .irq_base = IRQ_EINT(8), | ||
1854 | .chip = { | ||
1855 | .base = S5PC100_GPH1(0), | ||
1856 | .ngpio = S5PC100_GPIO_H1_NR, | ||
1857 | .label = "GPH1", | ||
1858 | .to_irq = samsung_gpiolib_to_irq, | ||
1859 | }, | ||
1860 | }, { | ||
1861 | .base = (S5P_VA_GPIO + 0xC40), | ||
1862 | .irq_base = IRQ_EINT(16), | ||
1863 | .chip = { | ||
1864 | .base = S5PC100_GPH2(0), | ||
1865 | .ngpio = S5PC100_GPIO_H2_NR, | ||
1866 | .label = "GPH2", | ||
1867 | .to_irq = samsung_gpiolib_to_irq, | ||
1868 | }, | ||
1869 | }, { | ||
1870 | .base = (S5P_VA_GPIO + 0xC60), | ||
1871 | .irq_base = IRQ_EINT(24), | ||
1872 | .chip = { | ||
1873 | .base = S5PC100_GPH3(0), | ||
1874 | .ngpio = S5PC100_GPIO_H3_NR, | ||
1875 | .label = "GPH3", | ||
1876 | .to_irq = samsung_gpiolib_to_irq, | ||
1877 | }, | ||
1878 | }, | ||
1879 | #endif | ||
1880 | }; | ||
1881 | |||
1882 | /* | ||
1883 | * Followings are the gpio banks in S5PV210/S5PC110 | ||
1884 | * | ||
1885 | * The 'config' member when left to NULL, is initialized to the default | ||
1886 | * structure samsung_gpio_cfgs[3] in the init function below. | ||
1887 | * | ||
1888 | * The 'base' member is also initialized in the init function below. | ||
1889 | * Note: The initialization of 'base' member of samsung_gpio_chip structure | ||
1890 | * uses the above macro and depends on the banks being listed in order here. | ||
1891 | */ | ||
1892 | |||
1893 | static struct samsung_gpio_chip s5pv210_gpios_4bit[] = { | ||
1894 | #ifdef CONFIG_CPU_S5PV210 | ||
1895 | { | ||
1896 | .chip = { | ||
1897 | .base = S5PV210_GPA0(0), | ||
1898 | .ngpio = S5PV210_GPIO_A0_NR, | ||
1899 | .label = "GPA0", | ||
1900 | }, | ||
1901 | }, { | ||
1902 | .chip = { | ||
1903 | .base = S5PV210_GPA1(0), | ||
1904 | .ngpio = S5PV210_GPIO_A1_NR, | ||
1905 | .label = "GPA1", | ||
1906 | }, | ||
1907 | }, { | ||
1908 | .chip = { | ||
1909 | .base = S5PV210_GPB(0), | ||
1910 | .ngpio = S5PV210_GPIO_B_NR, | ||
1911 | .label = "GPB", | ||
1912 | }, | ||
1913 | }, { | ||
1914 | .chip = { | ||
1915 | .base = S5PV210_GPC0(0), | ||
1916 | .ngpio = S5PV210_GPIO_C0_NR, | ||
1917 | .label = "GPC0", | ||
1918 | }, | ||
1919 | }, { | ||
1920 | .chip = { | ||
1921 | .base = S5PV210_GPC1(0), | ||
1922 | .ngpio = S5PV210_GPIO_C1_NR, | ||
1923 | .label = "GPC1", | ||
1924 | }, | ||
1925 | }, { | ||
1926 | .chip = { | ||
1927 | .base = S5PV210_GPD0(0), | ||
1928 | .ngpio = S5PV210_GPIO_D0_NR, | ||
1929 | .label = "GPD0", | ||
1930 | }, | ||
1931 | }, { | ||
1932 | .chip = { | ||
1933 | .base = S5PV210_GPD1(0), | ||
1934 | .ngpio = S5PV210_GPIO_D1_NR, | ||
1935 | .label = "GPD1", | ||
1936 | }, | ||
1937 | }, { | ||
1938 | .chip = { | ||
1939 | .base = S5PV210_GPE0(0), | ||
1940 | .ngpio = S5PV210_GPIO_E0_NR, | ||
1941 | .label = "GPE0", | ||
1942 | }, | ||
1943 | }, { | ||
1944 | .chip = { | ||
1945 | .base = S5PV210_GPE1(0), | ||
1946 | .ngpio = S5PV210_GPIO_E1_NR, | ||
1947 | .label = "GPE1", | ||
1948 | }, | ||
1949 | }, { | ||
1950 | .chip = { | ||
1951 | .base = S5PV210_GPF0(0), | ||
1952 | .ngpio = S5PV210_GPIO_F0_NR, | ||
1953 | .label = "GPF0", | ||
1954 | }, | ||
1955 | }, { | ||
1956 | .chip = { | ||
1957 | .base = S5PV210_GPF1(0), | ||
1958 | .ngpio = S5PV210_GPIO_F1_NR, | ||
1959 | .label = "GPF1", | ||
1960 | }, | ||
1961 | }, { | ||
1962 | .chip = { | ||
1963 | .base = S5PV210_GPF2(0), | ||
1964 | .ngpio = S5PV210_GPIO_F2_NR, | ||
1965 | .label = "GPF2", | ||
1966 | }, | ||
1967 | }, { | ||
1968 | .chip = { | ||
1969 | .base = S5PV210_GPF3(0), | ||
1970 | .ngpio = S5PV210_GPIO_F3_NR, | ||
1971 | .label = "GPF3", | ||
1972 | }, | ||
1973 | }, { | ||
1974 | .chip = { | ||
1975 | .base = S5PV210_GPG0(0), | ||
1976 | .ngpio = S5PV210_GPIO_G0_NR, | ||
1977 | .label = "GPG0", | ||
1978 | }, | ||
1979 | }, { | ||
1980 | .chip = { | ||
1981 | .base = S5PV210_GPG1(0), | ||
1982 | .ngpio = S5PV210_GPIO_G1_NR, | ||
1983 | .label = "GPG1", | ||
1984 | }, | ||
1985 | }, { | ||
1986 | .chip = { | ||
1987 | .base = S5PV210_GPG2(0), | ||
1988 | .ngpio = S5PV210_GPIO_G2_NR, | ||
1989 | .label = "GPG2", | ||
1990 | }, | ||
1991 | }, { | ||
1992 | .chip = { | ||
1993 | .base = S5PV210_GPG3(0), | ||
1994 | .ngpio = S5PV210_GPIO_G3_NR, | ||
1995 | .label = "GPG3", | ||
1996 | }, | ||
1997 | }, { | ||
1998 | .chip = { | ||
1999 | .base = S5PV210_GPI(0), | ||
2000 | .ngpio = S5PV210_GPIO_I_NR, | ||
2001 | .label = "GPI", | ||
2002 | }, | ||
2003 | }, { | ||
2004 | .chip = { | ||
2005 | .base = S5PV210_GPJ0(0), | ||
2006 | .ngpio = S5PV210_GPIO_J0_NR, | ||
2007 | .label = "GPJ0", | ||
2008 | }, | ||
2009 | }, { | ||
2010 | .chip = { | ||
2011 | .base = S5PV210_GPJ1(0), | ||
2012 | .ngpio = S5PV210_GPIO_J1_NR, | ||
2013 | .label = "GPJ1", | ||
2014 | }, | ||
2015 | }, { | ||
2016 | .chip = { | ||
2017 | .base = S5PV210_GPJ2(0), | ||
2018 | .ngpio = S5PV210_GPIO_J2_NR, | ||
2019 | .label = "GPJ2", | ||
2020 | }, | ||
2021 | }, { | ||
2022 | .chip = { | ||
2023 | .base = S5PV210_GPJ3(0), | ||
2024 | .ngpio = S5PV210_GPIO_J3_NR, | ||
2025 | .label = "GPJ3", | ||
2026 | }, | ||
2027 | }, { | ||
2028 | .chip = { | ||
2029 | .base = S5PV210_GPJ4(0), | ||
2030 | .ngpio = S5PV210_GPIO_J4_NR, | ||
2031 | .label = "GPJ4", | ||
2032 | }, | ||
2033 | }, { | ||
2034 | .chip = { | ||
2035 | .base = S5PV210_MP01(0), | ||
2036 | .ngpio = S5PV210_GPIO_MP01_NR, | ||
2037 | .label = "MP01", | ||
2038 | }, | ||
2039 | }, { | ||
2040 | .chip = { | ||
2041 | .base = S5PV210_MP02(0), | ||
2042 | .ngpio = S5PV210_GPIO_MP02_NR, | ||
2043 | .label = "MP02", | ||
2044 | }, | ||
2045 | }, { | ||
2046 | .chip = { | ||
2047 | .base = S5PV210_MP03(0), | ||
2048 | .ngpio = S5PV210_GPIO_MP03_NR, | ||
2049 | .label = "MP03", | ||
2050 | }, | ||
2051 | }, { | ||
2052 | .chip = { | ||
2053 | .base = S5PV210_MP04(0), | ||
2054 | .ngpio = S5PV210_GPIO_MP04_NR, | ||
2055 | .label = "MP04", | ||
2056 | }, | ||
2057 | }, { | ||
2058 | .chip = { | ||
2059 | .base = S5PV210_MP05(0), | ||
2060 | .ngpio = S5PV210_GPIO_MP05_NR, | ||
2061 | .label = "MP05", | ||
2062 | }, | ||
2063 | }, { | ||
2064 | .base = (S5P_VA_GPIO + 0xC00), | ||
2065 | .irq_base = IRQ_EINT(0), | ||
2066 | .chip = { | ||
2067 | .base = S5PV210_GPH0(0), | ||
2068 | .ngpio = S5PV210_GPIO_H0_NR, | ||
2069 | .label = "GPH0", | ||
2070 | .to_irq = samsung_gpiolib_to_irq, | ||
2071 | }, | ||
2072 | }, { | ||
2073 | .base = (S5P_VA_GPIO + 0xC20), | ||
2074 | .irq_base = IRQ_EINT(8), | ||
2075 | .chip = { | ||
2076 | .base = S5PV210_GPH1(0), | ||
2077 | .ngpio = S5PV210_GPIO_H1_NR, | ||
2078 | .label = "GPH1", | ||
2079 | .to_irq = samsung_gpiolib_to_irq, | ||
2080 | }, | ||
2081 | }, { | ||
2082 | .base = (S5P_VA_GPIO + 0xC40), | ||
2083 | .irq_base = IRQ_EINT(16), | ||
2084 | .chip = { | ||
2085 | .base = S5PV210_GPH2(0), | ||
2086 | .ngpio = S5PV210_GPIO_H2_NR, | ||
2087 | .label = "GPH2", | ||
2088 | .to_irq = samsung_gpiolib_to_irq, | ||
2089 | }, | ||
2090 | }, { | ||
2091 | .base = (S5P_VA_GPIO + 0xC60), | ||
2092 | .irq_base = IRQ_EINT(24), | ||
2093 | .chip = { | ||
2094 | .base = S5PV210_GPH3(0), | ||
2095 | .ngpio = S5PV210_GPIO_H3_NR, | ||
2096 | .label = "GPH3", | ||
2097 | .to_irq = samsung_gpiolib_to_irq, | ||
2098 | }, | ||
2099 | }, | ||
2100 | #endif | ||
2101 | }; | ||
2102 | |||
2103 | /* | ||
2104 | * Followings are the gpio banks in EXYNOS4210 | ||
2105 | * | ||
2106 | * The 'config' member when left to NULL, is initialized to the default | ||
2107 | * structure samsung_gpio_cfgs[3] in the init function below. | ||
2108 | * | ||
2109 | * The 'base' member is also initialized in the init function below. | ||
2110 | * Note: The initialization of 'base' member of samsung_gpio_chip structure | ||
2111 | * uses the above macro and depends on the banks being listed in order here. | ||
2112 | */ | ||
2113 | |||
2114 | static struct samsung_gpio_chip exynos4_gpios_1[] = { | ||
2115 | #ifdef CONFIG_ARCH_EXYNOS4 | ||
2116 | { | ||
2117 | .chip = { | ||
2118 | .base = EXYNOS4_GPA0(0), | ||
2119 | .ngpio = EXYNOS4_GPIO_A0_NR, | ||
2120 | .label = "GPA0", | ||
2121 | }, | ||
2122 | }, { | ||
2123 | .chip = { | ||
2124 | .base = EXYNOS4_GPA1(0), | ||
2125 | .ngpio = EXYNOS4_GPIO_A1_NR, | ||
2126 | .label = "GPA1", | ||
2127 | }, | ||
2128 | }, { | ||
2129 | .chip = { | ||
2130 | .base = EXYNOS4_GPB(0), | ||
2131 | .ngpio = EXYNOS4_GPIO_B_NR, | ||
2132 | .label = "GPB", | ||
2133 | }, | ||
2134 | }, { | ||
2135 | .chip = { | ||
2136 | .base = EXYNOS4_GPC0(0), | ||
2137 | .ngpio = EXYNOS4_GPIO_C0_NR, | ||
2138 | .label = "GPC0", | ||
2139 | }, | ||
2140 | }, { | ||
2141 | .chip = { | ||
2142 | .base = EXYNOS4_GPC1(0), | ||
2143 | .ngpio = EXYNOS4_GPIO_C1_NR, | ||
2144 | .label = "GPC1", | ||
2145 | }, | ||
2146 | }, { | ||
2147 | .chip = { | ||
2148 | .base = EXYNOS4_GPD0(0), | ||
2149 | .ngpio = EXYNOS4_GPIO_D0_NR, | ||
2150 | .label = "GPD0", | ||
2151 | }, | ||
2152 | }, { | ||
2153 | .chip = { | ||
2154 | .base = EXYNOS4_GPD1(0), | ||
2155 | .ngpio = EXYNOS4_GPIO_D1_NR, | ||
2156 | .label = "GPD1", | ||
2157 | }, | ||
2158 | }, { | ||
2159 | .chip = { | ||
2160 | .base = EXYNOS4_GPE0(0), | ||
2161 | .ngpio = EXYNOS4_GPIO_E0_NR, | ||
2162 | .label = "GPE0", | ||
2163 | }, | ||
2164 | }, { | ||
2165 | .chip = { | ||
2166 | .base = EXYNOS4_GPE1(0), | ||
2167 | .ngpio = EXYNOS4_GPIO_E1_NR, | ||
2168 | .label = "GPE1", | ||
2169 | }, | ||
2170 | }, { | ||
2171 | .chip = { | ||
2172 | .base = EXYNOS4_GPE2(0), | ||
2173 | .ngpio = EXYNOS4_GPIO_E2_NR, | ||
2174 | .label = "GPE2", | ||
2175 | }, | ||
2176 | }, { | ||
2177 | .chip = { | ||
2178 | .base = EXYNOS4_GPE3(0), | ||
2179 | .ngpio = EXYNOS4_GPIO_E3_NR, | ||
2180 | .label = "GPE3", | ||
2181 | }, | ||
2182 | }, { | ||
2183 | .chip = { | ||
2184 | .base = EXYNOS4_GPE4(0), | ||
2185 | .ngpio = EXYNOS4_GPIO_E4_NR, | ||
2186 | .label = "GPE4", | ||
2187 | }, | ||
2188 | }, { | ||
2189 | .chip = { | ||
2190 | .base = EXYNOS4_GPF0(0), | ||
2191 | .ngpio = EXYNOS4_GPIO_F0_NR, | ||
2192 | .label = "GPF0", | ||
2193 | }, | ||
2194 | }, { | ||
2195 | .chip = { | ||
2196 | .base = EXYNOS4_GPF1(0), | ||
2197 | .ngpio = EXYNOS4_GPIO_F1_NR, | ||
2198 | .label = "GPF1", | ||
2199 | }, | ||
2200 | }, { | ||
2201 | .chip = { | ||
2202 | .base = EXYNOS4_GPF2(0), | ||
2203 | .ngpio = EXYNOS4_GPIO_F2_NR, | ||
2204 | .label = "GPF2", | ||
2205 | }, | ||
2206 | }, { | ||
2207 | .chip = { | ||
2208 | .base = EXYNOS4_GPF3(0), | ||
2209 | .ngpio = EXYNOS4_GPIO_F3_NR, | ||
2210 | .label = "GPF3", | ||
2211 | }, | ||
2212 | }, | ||
2213 | #endif | ||
2214 | }; | ||
2215 | |||
2216 | static struct samsung_gpio_chip exynos4_gpios_2[] = { | ||
2217 | #ifdef CONFIG_ARCH_EXYNOS4 | ||
2218 | { | ||
2219 | .chip = { | ||
2220 | .base = EXYNOS4_GPJ0(0), | ||
2221 | .ngpio = EXYNOS4_GPIO_J0_NR, | ||
2222 | .label = "GPJ0", | ||
2223 | }, | ||
2224 | }, { | ||
2225 | .chip = { | ||
2226 | .base = EXYNOS4_GPJ1(0), | ||
2227 | .ngpio = EXYNOS4_GPIO_J1_NR, | ||
2228 | .label = "GPJ1", | ||
2229 | }, | ||
2230 | }, { | ||
2231 | .chip = { | ||
2232 | .base = EXYNOS4_GPK0(0), | ||
2233 | .ngpio = EXYNOS4_GPIO_K0_NR, | ||
2234 | .label = "GPK0", | ||
2235 | }, | ||
2236 | }, { | ||
2237 | .chip = { | ||
2238 | .base = EXYNOS4_GPK1(0), | ||
2239 | .ngpio = EXYNOS4_GPIO_K1_NR, | ||
2240 | .label = "GPK1", | ||
2241 | }, | ||
2242 | }, { | ||
2243 | .chip = { | ||
2244 | .base = EXYNOS4_GPK2(0), | ||
2245 | .ngpio = EXYNOS4_GPIO_K2_NR, | ||
2246 | .label = "GPK2", | ||
2247 | }, | ||
2248 | }, { | ||
2249 | .chip = { | ||
2250 | .base = EXYNOS4_GPK3(0), | ||
2251 | .ngpio = EXYNOS4_GPIO_K3_NR, | ||
2252 | .label = "GPK3", | ||
2253 | }, | ||
2254 | }, { | ||
2255 | .chip = { | ||
2256 | .base = EXYNOS4_GPL0(0), | ||
2257 | .ngpio = EXYNOS4_GPIO_L0_NR, | ||
2258 | .label = "GPL0", | ||
2259 | }, | ||
2260 | }, { | ||
2261 | .chip = { | ||
2262 | .base = EXYNOS4_GPL1(0), | ||
2263 | .ngpio = EXYNOS4_GPIO_L1_NR, | ||
2264 | .label = "GPL1", | ||
2265 | }, | ||
2266 | }, { | ||
2267 | .chip = { | ||
2268 | .base = EXYNOS4_GPL2(0), | ||
2269 | .ngpio = EXYNOS4_GPIO_L2_NR, | ||
2270 | .label = "GPL2", | ||
2271 | }, | ||
2272 | }, { | ||
2273 | .config = &samsung_gpio_cfgs[8], | ||
2274 | .chip = { | ||
2275 | .base = EXYNOS4_GPY0(0), | ||
2276 | .ngpio = EXYNOS4_GPIO_Y0_NR, | ||
2277 | .label = "GPY0", | ||
2278 | }, | ||
2279 | }, { | ||
2280 | .config = &samsung_gpio_cfgs[8], | ||
2281 | .chip = { | ||
2282 | .base = EXYNOS4_GPY1(0), | ||
2283 | .ngpio = EXYNOS4_GPIO_Y1_NR, | ||
2284 | .label = "GPY1", | ||
2285 | }, | ||
2286 | }, { | ||
2287 | .config = &samsung_gpio_cfgs[8], | ||
2288 | .chip = { | ||
2289 | .base = EXYNOS4_GPY2(0), | ||
2290 | .ngpio = EXYNOS4_GPIO_Y2_NR, | ||
2291 | .label = "GPY2", | ||
2292 | }, | ||
2293 | }, { | ||
2294 | .config = &samsung_gpio_cfgs[8], | ||
2295 | .chip = { | ||
2296 | .base = EXYNOS4_GPY3(0), | ||
2297 | .ngpio = EXYNOS4_GPIO_Y3_NR, | ||
2298 | .label = "GPY3", | ||
2299 | }, | ||
2300 | }, { | ||
2301 | .config = &samsung_gpio_cfgs[8], | ||
2302 | .chip = { | ||
2303 | .base = EXYNOS4_GPY4(0), | ||
2304 | .ngpio = EXYNOS4_GPIO_Y4_NR, | ||
2305 | .label = "GPY4", | ||
2306 | }, | ||
2307 | }, { | ||
2308 | .config = &samsung_gpio_cfgs[8], | ||
2309 | .chip = { | ||
2310 | .base = EXYNOS4_GPY5(0), | ||
2311 | .ngpio = EXYNOS4_GPIO_Y5_NR, | ||
2312 | .label = "GPY5", | ||
2313 | }, | ||
2314 | }, { | ||
2315 | .config = &samsung_gpio_cfgs[8], | ||
2316 | .chip = { | ||
2317 | .base = EXYNOS4_GPY6(0), | ||
2318 | .ngpio = EXYNOS4_GPIO_Y6_NR, | ||
2319 | .label = "GPY6", | ||
2320 | }, | ||
2321 | }, { | ||
2322 | .base = (S5P_VA_GPIO2 + 0xC00), | ||
2323 | .config = &samsung_gpio_cfgs[9], | ||
2324 | .irq_base = IRQ_EINT(0), | ||
2325 | .chip = { | ||
2326 | .base = EXYNOS4_GPX0(0), | ||
2327 | .ngpio = EXYNOS4_GPIO_X0_NR, | ||
2328 | .label = "GPX0", | ||
2329 | .to_irq = samsung_gpiolib_to_irq, | ||
2330 | }, | ||
2331 | }, { | ||
2332 | .base = (S5P_VA_GPIO2 + 0xC20), | ||
2333 | .config = &samsung_gpio_cfgs[9], | ||
2334 | .irq_base = IRQ_EINT(8), | ||
2335 | .chip = { | ||
2336 | .base = EXYNOS4_GPX1(0), | ||
2337 | .ngpio = EXYNOS4_GPIO_X1_NR, | ||
2338 | .label = "GPX1", | ||
2339 | .to_irq = samsung_gpiolib_to_irq, | ||
2340 | }, | ||
2341 | }, { | ||
2342 | .base = (S5P_VA_GPIO2 + 0xC40), | ||
2343 | .config = &samsung_gpio_cfgs[9], | ||
2344 | .irq_base = IRQ_EINT(16), | ||
2345 | .chip = { | ||
2346 | .base = EXYNOS4_GPX2(0), | ||
2347 | .ngpio = EXYNOS4_GPIO_X2_NR, | ||
2348 | .label = "GPX2", | ||
2349 | .to_irq = samsung_gpiolib_to_irq, | ||
2350 | }, | ||
2351 | }, { | ||
2352 | .base = (S5P_VA_GPIO2 + 0xC60), | ||
2353 | .config = &samsung_gpio_cfgs[9], | ||
2354 | .irq_base = IRQ_EINT(24), | ||
2355 | .chip = { | ||
2356 | .base = EXYNOS4_GPX3(0), | ||
2357 | .ngpio = EXYNOS4_GPIO_X3_NR, | ||
2358 | .label = "GPX3", | ||
2359 | .to_irq = samsung_gpiolib_to_irq, | ||
2360 | }, | ||
2361 | }, | ||
2362 | #endif | ||
2363 | }; | ||
2364 | |||
2365 | static struct samsung_gpio_chip exynos4_gpios_3[] = { | ||
2366 | #ifdef CONFIG_ARCH_EXYNOS4 | ||
2367 | { | ||
2368 | .chip = { | ||
2369 | .base = EXYNOS4_GPZ(0), | ||
2370 | .ngpio = EXYNOS4_GPIO_Z_NR, | ||
2371 | .label = "GPZ", | ||
2372 | }, | ||
2373 | }, | ||
2374 | #endif | ||
2375 | }; | ||
2376 | |||
2377 | /* TODO: cleanup soc_is_* */ | ||
2378 | static __init int samsung_gpiolib_init(void) | ||
2379 | { | ||
2380 | struct samsung_gpio_chip *chip; | ||
2381 | int i, nr_chips; | ||
2382 | int group = 0; | ||
2383 | |||
2384 | samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); | ||
2385 | |||
2386 | if (soc_is_s3c24xx()) { | ||
2387 | s3c24xx_gpiolib_add_chips(s3c24xx_gpios, | ||
2388 | ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO); | ||
2389 | } else if (soc_is_s3c64xx()) { | ||
2390 | samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit, | ||
2391 | ARRAY_SIZE(s3c64xx_gpios_2bit), | ||
2392 | S3C64XX_VA_GPIO + 0xE0, 0x20); | ||
2393 | samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit, | ||
2394 | ARRAY_SIZE(s3c64xx_gpios_4bit), | ||
2395 | S3C64XX_VA_GPIO); | ||
2396 | samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2, | ||
2397 | ARRAY_SIZE(s3c64xx_gpios_4bit2)); | ||
2398 | } else if (soc_is_s5p6440()) { | ||
2399 | samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit, | ||
2400 | ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0); | ||
2401 | samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit, | ||
2402 | ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO); | ||
2403 | samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2, | ||
2404 | ARRAY_SIZE(s5p6440_gpios_4bit2)); | ||
2405 | s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank, | ||
2406 | ARRAY_SIZE(s5p6440_gpios_rbank)); | ||
2407 | } else if (soc_is_s5p6450()) { | ||
2408 | samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit, | ||
2409 | ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0); | ||
2410 | samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit, | ||
2411 | ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO); | ||
2412 | samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2, | ||
2413 | ARRAY_SIZE(s5p6450_gpios_4bit2)); | ||
2414 | s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank, | ||
2415 | ARRAY_SIZE(s5p6450_gpios_rbank)); | ||
2416 | } else if (soc_is_s5pc100()) { | ||
2417 | group = 0; | ||
2418 | chip = s5pc100_gpios_4bit; | ||
2419 | nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit); | ||
2420 | |||
2421 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2422 | if (!chip->config) { | ||
2423 | chip->config = &samsung_gpio_cfgs[3]; | ||
2424 | chip->group = group++; | ||
2425 | } | ||
2426 | } | ||
2427 | samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO); | ||
2428 | #if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT) | ||
2429 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); | ||
2430 | #endif | ||
2431 | } else if (soc_is_s5pv210()) { | ||
2432 | group = 0; | ||
2433 | chip = s5pv210_gpios_4bit; | ||
2434 | nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit); | ||
2435 | |||
2436 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2437 | if (!chip->config) { | ||
2438 | chip->config = &samsung_gpio_cfgs[3]; | ||
2439 | chip->group = group++; | ||
2440 | } | ||
2441 | } | ||
2442 | samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO); | ||
2443 | #if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT) | ||
2444 | s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR); | ||
2445 | #endif | ||
2446 | } else if (soc_is_exynos4210()) { | ||
2447 | group = 0; | ||
2448 | |||
2449 | /* gpio part1 */ | ||
2450 | chip = exynos4_gpios_1; | ||
2451 | nr_chips = ARRAY_SIZE(exynos4_gpios_1); | ||
2452 | |||
2453 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2454 | if (!chip->config) { | ||
2455 | chip->config = &exynos4_gpio_cfg; | ||
2456 | chip->group = group++; | ||
2457 | } | ||
2458 | } | ||
2459 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1); | ||
2460 | |||
2461 | /* gpio part2 */ | ||
2462 | chip = exynos4_gpios_2; | ||
2463 | nr_chips = ARRAY_SIZE(exynos4_gpios_2); | ||
2464 | |||
2465 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2466 | if (!chip->config) { | ||
2467 | chip->config = &exynos4_gpio_cfg; | ||
2468 | chip->group = group++; | ||
2469 | } | ||
2470 | } | ||
2471 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2); | ||
2472 | |||
2473 | /* gpio part3 */ | ||
2474 | chip = exynos4_gpios_3; | ||
2475 | nr_chips = ARRAY_SIZE(exynos4_gpios_3); | ||
2476 | |||
2477 | for (i = 0; i < nr_chips; i++, chip++) { | ||
2478 | if (!chip->config) { | ||
2479 | chip->config = &exynos4_gpio_cfg; | ||
2480 | chip->group = group++; | ||
2481 | } | ||
2482 | } | ||
2483 | samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3); | ||
2484 | |||
2485 | #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT) | ||
2486 | s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS); | ||
2487 | s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS); | ||
2488 | #endif | ||
2489 | } else { | ||
2490 | WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n"); | ||
2491 | return -ENODEV; | ||
2492 | } | ||
2493 | |||
2494 | return 0; | ||
2495 | } | ||
2496 | core_initcall(samsung_gpiolib_init); | ||
2497 | |||
2498 | int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) | ||
2499 | { | ||
2500 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2501 | unsigned long flags; | ||
2502 | int offset; | ||
2503 | int ret; | ||
2504 | |||
2505 | if (!chip) | ||
2506 | return -EINVAL; | ||
2507 | |||
2508 | offset = pin - chip->chip.base; | ||
2509 | |||
2510 | samsung_gpio_lock(chip, flags); | ||
2511 | ret = samsung_gpio_do_setcfg(chip, offset, config); | ||
2512 | samsung_gpio_unlock(chip, flags); | ||
2513 | |||
2514 | return ret; | ||
2515 | } | ||
2516 | EXPORT_SYMBOL(s3c_gpio_cfgpin); | ||
2517 | |||
2518 | int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr, | ||
2519 | unsigned int cfg) | ||
2520 | { | ||
2521 | int ret; | ||
2522 | |||
2523 | for (; nr > 0; nr--, start++) { | ||
2524 | ret = s3c_gpio_cfgpin(start, cfg); | ||
2525 | if (ret != 0) | ||
2526 | return ret; | ||
2527 | } | ||
2528 | |||
2529 | return 0; | ||
2530 | } | ||
2531 | EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range); | ||
2532 | |||
2533 | int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr, | ||
2534 | unsigned int cfg, samsung_gpio_pull_t pull) | ||
2535 | { | ||
2536 | int ret; | ||
2537 | |||
2538 | for (; nr > 0; nr--, start++) { | ||
2539 | s3c_gpio_setpull(start, pull); | ||
2540 | ret = s3c_gpio_cfgpin(start, cfg); | ||
2541 | if (ret != 0) | ||
2542 | return ret; | ||
2543 | } | ||
2544 | |||
2545 | return 0; | ||
2546 | } | ||
2547 | EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range); | ||
2548 | |||
2549 | unsigned s3c_gpio_getcfg(unsigned int pin) | ||
2550 | { | ||
2551 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2552 | unsigned long flags; | ||
2553 | unsigned ret = 0; | ||
2554 | int offset; | ||
2555 | |||
2556 | if (chip) { | ||
2557 | offset = pin - chip->chip.base; | ||
2558 | |||
2559 | samsung_gpio_lock(chip, flags); | ||
2560 | ret = samsung_gpio_do_getcfg(chip, offset); | ||
2561 | samsung_gpio_unlock(chip, flags); | ||
2562 | } | ||
2563 | |||
2564 | return ret; | ||
2565 | } | ||
2566 | EXPORT_SYMBOL(s3c_gpio_getcfg); | ||
2567 | |||
2568 | int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull) | ||
2569 | { | ||
2570 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2571 | unsigned long flags; | ||
2572 | int offset, ret; | ||
2573 | |||
2574 | if (!chip) | ||
2575 | return -EINVAL; | ||
2576 | |||
2577 | offset = pin - chip->chip.base; | ||
2578 | |||
2579 | samsung_gpio_lock(chip, flags); | ||
2580 | ret = samsung_gpio_do_setpull(chip, offset, pull); | ||
2581 | samsung_gpio_unlock(chip, flags); | ||
2582 | |||
2583 | return ret; | ||
2584 | } | ||
2585 | EXPORT_SYMBOL(s3c_gpio_setpull); | ||
2586 | |||
2587 | samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin) | ||
2588 | { | ||
2589 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2590 | unsigned long flags; | ||
2591 | int offset; | ||
2592 | u32 pup = 0; | ||
2593 | |||
2594 | if (chip) { | ||
2595 | offset = pin - chip->chip.base; | ||
2596 | |||
2597 | samsung_gpio_lock(chip, flags); | ||
2598 | pup = samsung_gpio_do_getpull(chip, offset); | ||
2599 | samsung_gpio_unlock(chip, flags); | ||
2600 | } | ||
2601 | |||
2602 | return (__force samsung_gpio_pull_t)pup; | ||
2603 | } | ||
2604 | EXPORT_SYMBOL(s3c_gpio_getpull); | ||
2605 | |||
2606 | /* gpiolib wrappers until these are totally eliminated */ | ||
2607 | |||
2608 | void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) | ||
2609 | { | ||
2610 | int ret; | ||
2611 | |||
2612 | WARN_ON(to); /* should be none of these left */ | ||
2613 | |||
2614 | if (!to) { | ||
2615 | /* if pull is enabled, try first with up, and if that | ||
2616 | * fails, try using down */ | ||
2617 | |||
2618 | ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); | ||
2619 | if (ret) | ||
2620 | s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN); | ||
2621 | } else { | ||
2622 | s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); | ||
2623 | } | ||
2624 | } | ||
2625 | EXPORT_SYMBOL(s3c2410_gpio_pullup); | ||
2626 | |||
2627 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) | ||
2628 | { | ||
2629 | /* do this via gpiolib until all users removed */ | ||
2630 | |||
2631 | gpio_request(pin, "temporary"); | ||
2632 | gpio_set_value(pin, to); | ||
2633 | gpio_free(pin); | ||
2634 | } | ||
2635 | EXPORT_SYMBOL(s3c2410_gpio_setpin); | ||
2636 | |||
2637 | unsigned int s3c2410_gpio_getpin(unsigned int pin) | ||
2638 | { | ||
2639 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2640 | unsigned long offs = pin - chip->chip.base; | ||
2641 | |||
2642 | return __raw_readl(chip->base + 0x04) & (1 << offs); | ||
2643 | } | ||
2644 | EXPORT_SYMBOL(s3c2410_gpio_getpin); | ||
2645 | |||
2646 | #ifdef CONFIG_S5P_GPIO_DRVSTR | ||
2647 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | ||
2648 | { | ||
2649 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2650 | unsigned int off; | ||
2651 | void __iomem *reg; | ||
2652 | int shift; | ||
2653 | u32 drvstr; | ||
2654 | |||
2655 | if (!chip) | ||
2656 | return -EINVAL; | ||
2657 | |||
2658 | off = pin - chip->chip.base; | ||
2659 | shift = off * 2; | ||
2660 | reg = chip->base + 0x0C; | ||
2661 | |||
2662 | drvstr = __raw_readl(reg); | ||
2663 | drvstr = drvstr >> shift; | ||
2664 | drvstr &= 0x3; | ||
2665 | |||
2666 | return (__force s5p_gpio_drvstr_t)drvstr; | ||
2667 | } | ||
2668 | EXPORT_SYMBOL(s5p_gpio_get_drvstr); | ||
2669 | |||
2670 | int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) | ||
2671 | { | ||
2672 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
2673 | unsigned int off; | ||
2674 | void __iomem *reg; | ||
2675 | int shift; | ||
2676 | u32 tmp; | ||
2677 | |||
2678 | if (!chip) | ||
2679 | return -EINVAL; | ||
2680 | |||
2681 | off = pin - chip->chip.base; | ||
2682 | shift = off * 2; | ||
2683 | reg = chip->base + 0x0C; | ||
2684 | |||
2685 | tmp = __raw_readl(reg); | ||
2686 | tmp &= ~(0x3 << shift); | ||
2687 | tmp |= drvstr << shift; | ||
2688 | |||
2689 | __raw_writel(tmp, reg); | ||
2690 | |||
2691 | return 0; | ||
2692 | } | ||
2693 | EXPORT_SYMBOL(s5p_gpio_set_drvstr); | ||
2694 | #endif /* CONFIG_S5P_GPIO_DRVSTR */ | ||
2695 | |||
2696 | #ifdef CONFIG_PLAT_S3C24XX | ||
2697 | unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) | ||
2698 | { | ||
2699 | unsigned long flags; | ||
2700 | unsigned long misccr; | ||
2701 | |||
2702 | local_irq_save(flags); | ||
2703 | misccr = __raw_readl(S3C24XX_MISCCR); | ||
2704 | misccr &= ~clear; | ||
2705 | misccr ^= change; | ||
2706 | __raw_writel(misccr, S3C24XX_MISCCR); | ||
2707 | local_irq_restore(flags); | ||
2708 | |||
2709 | return misccr; | ||
2710 | } | ||
2711 | EXPORT_SYMBOL(s3c2410_modify_misccr); | ||
2712 | #endif | ||
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 747eb40e8afe..61044c889f7f 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
@@ -20,13 +20,15 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | |||
24 | #include <linux/io.h> | 23 | #include <linux/io.h> |
25 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
26 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/module.h> | ||
27 | 28 | ||
28 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
29 | 30 | ||
31 | #include <mach/gpio-tegra.h> | ||
30 | #include <mach/iomap.h> | 32 | #include <mach/iomap.h> |
31 | #include <mach/suspend.h> | 33 | #include <mach/suspend.h> |
32 | 34 | ||
@@ -34,9 +36,7 @@ | |||
34 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) | 36 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) |
35 | #define GPIO_BIT(x) ((x) & 0x7) | 37 | #define GPIO_BIT(x) ((x) & 0x7) |
36 | 38 | ||
37 | #define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \ | 39 | #define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4) |
38 | GPIO_BANK(x) * 0x80 + \ | ||
39 | GPIO_PORT(x) * 4) | ||
40 | 40 | ||
41 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) | 41 | #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) |
42 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) | 42 | #define GPIO_OE(x) (GPIO_REG(x) + 0x10) |
@@ -75,15 +75,18 @@ struct tegra_gpio_bank { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | 77 | ||
78 | static struct tegra_gpio_bank tegra_gpio_banks[] = { | 78 | static void __iomem *regs; |
79 | {.bank = 0, .irq = INT_GPIO1}, | 79 | static struct tegra_gpio_bank tegra_gpio_banks[7]; |
80 | {.bank = 1, .irq = INT_GPIO2}, | 80 | |
81 | {.bank = 2, .irq = INT_GPIO3}, | 81 | static inline void tegra_gpio_writel(u32 val, u32 reg) |
82 | {.bank = 3, .irq = INT_GPIO4}, | 82 | { |
83 | {.bank = 4, .irq = INT_GPIO5}, | 83 | __raw_writel(val, regs + reg); |
84 | {.bank = 5, .irq = INT_GPIO6}, | 84 | } |
85 | {.bank = 6, .irq = INT_GPIO7}, | 85 | |
86 | }; | 86 | static inline u32 tegra_gpio_readl(u32 reg) |
87 | { | ||
88 | return __raw_readl(regs + reg); | ||
89 | } | ||
87 | 90 | ||
88 | static int tegra_gpio_compose(int bank, int port, int bit) | 91 | static int tegra_gpio_compose(int bank, int port, int bit) |
89 | { | 92 | { |
@@ -97,7 +100,7 @@ static void tegra_gpio_mask_write(u32 reg, int gpio, int value) | |||
97 | val = 0x100 << GPIO_BIT(gpio); | 100 | val = 0x100 << GPIO_BIT(gpio); |
98 | if (value) | 101 | if (value) |
99 | val |= 1 << GPIO_BIT(gpio); | 102 | val |= 1 << GPIO_BIT(gpio); |
100 | __raw_writel(val, reg); | 103 | tegra_gpio_writel(val, reg); |
101 | } | 104 | } |
102 | 105 | ||
103 | void tegra_gpio_enable(int gpio) | 106 | void tegra_gpio_enable(int gpio) |
@@ -117,7 +120,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
117 | 120 | ||
118 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) | 121 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) |
119 | { | 122 | { |
120 | return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; | 123 | return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; |
121 | } | 124 | } |
122 | 125 | ||
123 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 126 | static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
@@ -134,7 +137,10 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
134 | return 0; | 137 | return 0; |
135 | } | 138 | } |
136 | 139 | ||
137 | 140 | static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |
141 | { | ||
142 | return TEGRA_GPIO_TO_IRQ(offset); | ||
143 | } | ||
138 | 144 | ||
139 | static struct gpio_chip tegra_gpio_chip = { | 145 | static struct gpio_chip tegra_gpio_chip = { |
140 | .label = "tegra-gpio", | 146 | .label = "tegra-gpio", |
@@ -142,6 +148,7 @@ static struct gpio_chip tegra_gpio_chip = { | |||
142 | .get = tegra_gpio_get, | 148 | .get = tegra_gpio_get, |
143 | .direction_output = tegra_gpio_direction_output, | 149 | .direction_output = tegra_gpio_direction_output, |
144 | .set = tegra_gpio_set, | 150 | .set = tegra_gpio_set, |
151 | .to_irq = tegra_gpio_to_irq, | ||
145 | .base = 0, | 152 | .base = 0, |
146 | .ngpio = TEGRA_NR_GPIOS, | 153 | .ngpio = TEGRA_NR_GPIOS, |
147 | }; | 154 | }; |
@@ -150,7 +157,7 @@ static void tegra_gpio_irq_ack(struct irq_data *d) | |||
150 | { | 157 | { |
151 | int gpio = d->irq - INT_GPIO_BASE; | 158 | int gpio = d->irq - INT_GPIO_BASE; |
152 | 159 | ||
153 | __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); | 160 | tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio)); |
154 | } | 161 | } |
155 | 162 | ||
156 | static void tegra_gpio_irq_mask(struct irq_data *d) | 163 | static void tegra_gpio_irq_mask(struct irq_data *d) |
@@ -203,10 +210,10 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
203 | 210 | ||
204 | spin_lock_irqsave(&bank->lvl_lock[port], flags); | 211 | spin_lock_irqsave(&bank->lvl_lock[port], flags); |
205 | 212 | ||
206 | val = __raw_readl(GPIO_INT_LVL(gpio)); | 213 | val = tegra_gpio_readl(GPIO_INT_LVL(gpio)); |
207 | val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); | 214 | val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio)); |
208 | val |= lvl_type << GPIO_BIT(gpio); | 215 | val |= lvl_type << GPIO_BIT(gpio); |
209 | __raw_writel(val, GPIO_INT_LVL(gpio)); | 216 | tegra_gpio_writel(val, GPIO_INT_LVL(gpio)); |
210 | 217 | ||
211 | spin_unlock_irqrestore(&bank->lvl_lock[port], flags); | 218 | spin_unlock_irqrestore(&bank->lvl_lock[port], flags); |
212 | 219 | ||
@@ -232,12 +239,12 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
232 | 239 | ||
233 | for (port = 0; port < 4; port++) { | 240 | for (port = 0; port < 4; port++) { |
234 | int gpio = tegra_gpio_compose(bank->bank, port, 0); | 241 | int gpio = tegra_gpio_compose(bank->bank, port, 0); |
235 | unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) & | 242 | unsigned long sta = tegra_gpio_readl(GPIO_INT_STA(gpio)) & |
236 | __raw_readl(GPIO_INT_ENB(gpio)); | 243 | tegra_gpio_readl(GPIO_INT_ENB(gpio)); |
237 | u32 lvl = __raw_readl(GPIO_INT_LVL(gpio)); | 244 | u32 lvl = tegra_gpio_readl(GPIO_INT_LVL(gpio)); |
238 | 245 | ||
239 | for_each_set_bit(pin, &sta, 8) { | 246 | for_each_set_bit(pin, &sta, 8) { |
240 | __raw_writel(1 << pin, GPIO_INT_CLR(gpio)); | 247 | tegra_gpio_writel(1 << pin, GPIO_INT_CLR(gpio)); |
241 | 248 | ||
242 | /* if gpio is edge triggered, clear condition | 249 | /* if gpio is edge triggered, clear condition |
243 | * before executing the hander so that we don't | 250 | * before executing the hander so that we don't |
@@ -271,11 +278,11 @@ void tegra_gpio_resume(void) | |||
271 | 278 | ||
272 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { | 279 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { |
273 | unsigned int gpio = (b<<5) | (p<<3); | 280 | unsigned int gpio = (b<<5) | (p<<3); |
274 | __raw_writel(bank->cnf[p], GPIO_CNF(gpio)); | 281 | tegra_gpio_writel(bank->cnf[p], GPIO_CNF(gpio)); |
275 | __raw_writel(bank->out[p], GPIO_OUT(gpio)); | 282 | tegra_gpio_writel(bank->out[p], GPIO_OUT(gpio)); |
276 | __raw_writel(bank->oe[p], GPIO_OE(gpio)); | 283 | tegra_gpio_writel(bank->oe[p], GPIO_OE(gpio)); |
277 | __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); | 284 | tegra_gpio_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio)); |
278 | __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); | 285 | tegra_gpio_writel(bank->int_enb[p], GPIO_INT_ENB(gpio)); |
279 | } | 286 | } |
280 | } | 287 | } |
281 | 288 | ||
@@ -294,11 +301,11 @@ void tegra_gpio_suspend(void) | |||
294 | 301 | ||
295 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { | 302 | for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { |
296 | unsigned int gpio = (b<<5) | (p<<3); | 303 | unsigned int gpio = (b<<5) | (p<<3); |
297 | bank->cnf[p] = __raw_readl(GPIO_CNF(gpio)); | 304 | bank->cnf[p] = tegra_gpio_readl(GPIO_CNF(gpio)); |
298 | bank->out[p] = __raw_readl(GPIO_OUT(gpio)); | 305 | bank->out[p] = tegra_gpio_readl(GPIO_OUT(gpio)); |
299 | bank->oe[p] = __raw_readl(GPIO_OE(gpio)); | 306 | bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio)); |
300 | bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio)); | 307 | bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio)); |
301 | bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio)); | 308 | bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio)); |
302 | } | 309 | } |
303 | } | 310 | } |
304 | local_irq_restore(flags); | 311 | local_irq_restore(flags); |
@@ -328,38 +335,69 @@ static struct irq_chip tegra_gpio_irq_chip = { | |||
328 | */ | 335 | */ |
329 | static struct lock_class_key gpio_lock_class; | 336 | static struct lock_class_key gpio_lock_class; |
330 | 337 | ||
331 | static int __init tegra_gpio_init(void) | 338 | static int __devinit tegra_gpio_probe(struct platform_device *pdev) |
332 | { | 339 | { |
340 | struct resource *res; | ||
333 | struct tegra_gpio_bank *bank; | 341 | struct tegra_gpio_bank *bank; |
342 | int gpio; | ||
334 | int i; | 343 | int i; |
335 | int j; | 344 | int j; |
336 | 345 | ||
346 | for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { | ||
347 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); | ||
348 | if (!res) { | ||
349 | dev_err(&pdev->dev, "Missing IRQ resource\n"); | ||
350 | return -ENODEV; | ||
351 | } | ||
352 | |||
353 | bank = &tegra_gpio_banks[i]; | ||
354 | bank->bank = i; | ||
355 | bank->irq = res->start; | ||
356 | } | ||
357 | |||
358 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
359 | if (!res) { | ||
360 | dev_err(&pdev->dev, "Missing MEM resource\n"); | ||
361 | return -ENODEV; | ||
362 | } | ||
363 | |||
364 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
365 | resource_size(res), | ||
366 | dev_name(&pdev->dev))) { | ||
367 | dev_err(&pdev->dev, "Couldn't request MEM resource\n"); | ||
368 | return -ENODEV; | ||
369 | } | ||
370 | |||
371 | regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
372 | if (!regs) { | ||
373 | dev_err(&pdev->dev, "Couldn't ioremap regs\n"); | ||
374 | return -ENODEV; | ||
375 | } | ||
376 | |||
337 | for (i = 0; i < 7; i++) { | 377 | for (i = 0; i < 7; i++) { |
338 | for (j = 0; j < 4; j++) { | 378 | for (j = 0; j < 4; j++) { |
339 | int gpio = tegra_gpio_compose(i, j, 0); | 379 | int gpio = tegra_gpio_compose(i, j, 0); |
340 | __raw_writel(0x00, GPIO_INT_ENB(gpio)); | 380 | tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); |
341 | } | 381 | } |
342 | } | 382 | } |
343 | 383 | ||
344 | #ifdef CONFIG_OF_GPIO | 384 | #ifdef CONFIG_OF_GPIO |
345 | /* | 385 | tegra_gpio_chip.of_node = pdev->dev.of_node; |
346 | * This isn't ideal, but it gets things hooked up until this | 386 | #endif |
347 | * driver is converted into a platform_device | ||
348 | */ | ||
349 | tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL, | ||
350 | "nvidia,tegra20-gpio"); | ||
351 | #endif /* CONFIG_OF_GPIO */ | ||
352 | 387 | ||
353 | gpiochip_add(&tegra_gpio_chip); | 388 | gpiochip_add(&tegra_gpio_chip); |
354 | 389 | ||
355 | for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) { | 390 | for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) { |
356 | bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))]; | 391 | int irq = TEGRA_GPIO_TO_IRQ(gpio); |
392 | /* No validity check; all Tegra GPIOs are valid IRQs */ | ||
357 | 393 | ||
358 | irq_set_lockdep_class(i, &gpio_lock_class); | 394 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; |
359 | irq_set_chip_data(i, bank); | 395 | |
360 | irq_set_chip_and_handler(i, &tegra_gpio_irq_chip, | 396 | irq_set_lockdep_class(irq, &gpio_lock_class); |
397 | irq_set_chip_data(irq, bank); | ||
398 | irq_set_chip_and_handler(irq, &tegra_gpio_irq_chip, | ||
361 | handle_simple_irq); | 399 | handle_simple_irq); |
362 | set_irq_flags(i, IRQF_VALID); | 400 | set_irq_flags(irq, IRQF_VALID); |
363 | } | 401 | } |
364 | 402 | ||
365 | for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { | 403 | for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { |
@@ -375,6 +413,24 @@ static int __init tegra_gpio_init(void) | |||
375 | return 0; | 413 | return 0; |
376 | } | 414 | } |
377 | 415 | ||
416 | static struct of_device_id tegra_gpio_of_match[] __devinitdata = { | ||
417 | { .compatible = "nvidia,tegra20-gpio", }, | ||
418 | { }, | ||
419 | }; | ||
420 | |||
421 | static struct platform_driver tegra_gpio_driver = { | ||
422 | .driver = { | ||
423 | .name = "tegra-gpio", | ||
424 | .owner = THIS_MODULE, | ||
425 | .of_match_table = tegra_gpio_of_match, | ||
426 | }, | ||
427 | .probe = tegra_gpio_probe, | ||
428 | }; | ||
429 | |||
430 | static int __init tegra_gpio_init(void) | ||
431 | { | ||
432 | return platform_driver_register(&tegra_gpio_driver); | ||
433 | } | ||
378 | postcore_initcall(tegra_gpio_init); | 434 | postcore_initcall(tegra_gpio_init); |
379 | 435 | ||
380 | void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) | 436 | void __init tegra_gpio_config(struct tegra_gpio_table *table, int num) |
@@ -407,13 +463,13 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
407 | seq_printf(s, | 463 | seq_printf(s, |
408 | "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", | 464 | "%d:%d %02x %02x %02x %02x %02x %02x %06x\n", |
409 | i, j, | 465 | i, j, |
410 | __raw_readl(GPIO_CNF(gpio)), | 466 | tegra_gpio_readl(GPIO_CNF(gpio)), |
411 | __raw_readl(GPIO_OE(gpio)), | 467 | tegra_gpio_readl(GPIO_OE(gpio)), |
412 | __raw_readl(GPIO_OUT(gpio)), | 468 | tegra_gpio_readl(GPIO_OUT(gpio)), |
413 | __raw_readl(GPIO_IN(gpio)), | 469 | tegra_gpio_readl(GPIO_IN(gpio)), |
414 | __raw_readl(GPIO_INT_STA(gpio)), | 470 | tegra_gpio_readl(GPIO_INT_STA(gpio)), |
415 | __raw_readl(GPIO_INT_ENB(gpio)), | 471 | tegra_gpio_readl(GPIO_INT_ENB(gpio)), |
416 | __raw_readl(GPIO_INT_LVL(gpio))); | 472 | tegra_gpio_readl(GPIO_INT_LVL(gpio))); |
417 | } | 473 | } |
418 | } | 474 | } |
419 | return 0; | 475 | return 0; |
diff --git a/drivers/gpio/gpio-tnetv107x.c b/drivers/gpio/gpio-tnetv107x.c new file mode 100644 index 000000000000..3fa3e2867e19 --- /dev/null +++ b/drivers/gpio/gpio-tnetv107x.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * Texas Instruments TNETV107X GPIO Controller | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation version 2. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether express or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <mach/common.h> | ||
20 | #include <mach/tnetv107x.h> | ||
21 | |||
22 | struct tnetv107x_gpio_regs { | ||
23 | u32 idver; | ||
24 | u32 data_in[3]; | ||
25 | u32 data_out[3]; | ||
26 | u32 direction[3]; | ||
27 | u32 enable[3]; | ||
28 | }; | ||
29 | |||
30 | #define gpio_reg_index(gpio) ((gpio) >> 5) | ||
31 | #define gpio_reg_bit(gpio) BIT((gpio) & 0x1f) | ||
32 | |||
33 | #define gpio_reg_rmw(reg, mask, val) \ | ||
34 | __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg)) | ||
35 | |||
36 | #define gpio_reg_set_bit(reg, gpio) \ | ||
37 | gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio)) | ||
38 | |||
39 | #define gpio_reg_clear_bit(reg, gpio) \ | ||
40 | gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0) | ||
41 | |||
42 | #define gpio_reg_get_bit(reg, gpio) \ | ||
43 | (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio)) | ||
44 | |||
45 | #define chip2controller(chip) \ | ||
46 | container_of(chip, struct davinci_gpio_controller, chip) | ||
47 | |||
48 | #define TNETV107X_GPIO_CTLRS DIV_ROUND_UP(TNETV107X_N_GPIO, 32) | ||
49 | |||
50 | static struct davinci_gpio_controller chips[TNETV107X_GPIO_CTLRS]; | ||
51 | |||
52 | static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
53 | { | ||
54 | struct davinci_gpio_controller *ctlr = chip2controller(chip); | ||
55 | struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; | ||
56 | unsigned gpio = chip->base + offset; | ||
57 | unsigned long flags; | ||
58 | |||
59 | spin_lock_irqsave(&ctlr->lock, flags); | ||
60 | |||
61 | gpio_reg_set_bit(regs->enable, gpio); | ||
62 | |||
63 | spin_unlock_irqrestore(&ctlr->lock, flags); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
69 | { | ||
70 | struct davinci_gpio_controller *ctlr = chip2controller(chip); | ||
71 | struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; | ||
72 | unsigned gpio = chip->base + offset; | ||
73 | unsigned long flags; | ||
74 | |||
75 | spin_lock_irqsave(&ctlr->lock, flags); | ||
76 | |||
77 | gpio_reg_clear_bit(regs->enable, gpio); | ||
78 | |||
79 | spin_unlock_irqrestore(&ctlr->lock, flags); | ||
80 | } | ||
81 | |||
82 | static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset) | ||
83 | { | ||
84 | struct davinci_gpio_controller *ctlr = chip2controller(chip); | ||
85 | struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; | ||
86 | unsigned gpio = chip->base + offset; | ||
87 | unsigned long flags; | ||
88 | |||
89 | spin_lock_irqsave(&ctlr->lock, flags); | ||
90 | |||
91 | gpio_reg_set_bit(regs->direction, gpio); | ||
92 | |||
93 | spin_unlock_irqrestore(&ctlr->lock, flags); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int tnetv107x_gpio_dir_out(struct gpio_chip *chip, | ||
99 | unsigned offset, int value) | ||
100 | { | ||
101 | struct davinci_gpio_controller *ctlr = chip2controller(chip); | ||
102 | struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; | ||
103 | unsigned gpio = chip->base + offset; | ||
104 | unsigned long flags; | ||
105 | |||
106 | spin_lock_irqsave(&ctlr->lock, flags); | ||
107 | |||
108 | if (value) | ||
109 | gpio_reg_set_bit(regs->data_out, gpio); | ||
110 | else | ||
111 | gpio_reg_clear_bit(regs->data_out, gpio); | ||
112 | |||
113 | gpio_reg_clear_bit(regs->direction, gpio); | ||
114 | |||
115 | spin_unlock_irqrestore(&ctlr->lock, flags); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
121 | { | ||
122 | struct davinci_gpio_controller *ctlr = chip2controller(chip); | ||
123 | struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; | ||
124 | unsigned gpio = chip->base + offset; | ||
125 | int ret; | ||
126 | |||
127 | ret = gpio_reg_get_bit(regs->data_in, gpio); | ||
128 | |||
129 | return ret ? 1 : 0; | ||
130 | } | ||
131 | |||
132 | static void tnetv107x_gpio_set(struct gpio_chip *chip, | ||
133 | unsigned offset, int value) | ||
134 | { | ||
135 | struct davinci_gpio_controller *ctlr = chip2controller(chip); | ||
136 | struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs; | ||
137 | unsigned gpio = chip->base + offset; | ||
138 | unsigned long flags; | ||
139 | |||
140 | spin_lock_irqsave(&ctlr->lock, flags); | ||
141 | |||
142 | if (value) | ||
143 | gpio_reg_set_bit(regs->data_out, gpio); | ||
144 | else | ||
145 | gpio_reg_clear_bit(regs->data_out, gpio); | ||
146 | |||
147 | spin_unlock_irqrestore(&ctlr->lock, flags); | ||
148 | } | ||
149 | |||
150 | static int __init tnetv107x_gpio_setup(void) | ||
151 | { | ||
152 | int i, base; | ||
153 | unsigned ngpio; | ||
154 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
155 | struct tnetv107x_gpio_regs *regs; | ||
156 | struct davinci_gpio_controller *ctlr; | ||
157 | |||
158 | if (soc_info->gpio_type != GPIO_TYPE_TNETV107X) | ||
159 | return 0; | ||
160 | |||
161 | ngpio = soc_info->gpio_num; | ||
162 | if (ngpio == 0) { | ||
163 | pr_err("GPIO setup: how many GPIOs?\n"); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | if (WARN_ON(TNETV107X_N_GPIO < ngpio)) | ||
168 | ngpio = TNETV107X_N_GPIO; | ||
169 | |||
170 | regs = ioremap(soc_info->gpio_base, SZ_4K); | ||
171 | if (WARN_ON(!regs)) | ||
172 | return -EINVAL; | ||
173 | |||
174 | for (i = 0, base = 0; base < ngpio; i++, base += 32) { | ||
175 | ctlr = &chips[i]; | ||
176 | |||
177 | ctlr->chip.label = "tnetv107x"; | ||
178 | ctlr->chip.can_sleep = 0; | ||
179 | ctlr->chip.base = base; | ||
180 | ctlr->chip.ngpio = ngpio - base; | ||
181 | if (ctlr->chip.ngpio > 32) | ||
182 | ctlr->chip.ngpio = 32; | ||
183 | |||
184 | ctlr->chip.request = tnetv107x_gpio_request; | ||
185 | ctlr->chip.free = tnetv107x_gpio_free; | ||
186 | ctlr->chip.direction_input = tnetv107x_gpio_dir_in; | ||
187 | ctlr->chip.get = tnetv107x_gpio_get; | ||
188 | ctlr->chip.direction_output = tnetv107x_gpio_dir_out; | ||
189 | ctlr->chip.set = tnetv107x_gpio_set; | ||
190 | |||
191 | spin_lock_init(&ctlr->lock); | ||
192 | |||
193 | ctlr->regs = regs; | ||
194 | ctlr->set_data = ®s->data_out[i]; | ||
195 | ctlr->clr_data = ®s->data_out[i]; | ||
196 | ctlr->in_data = ®s->data_in[i]; | ||
197 | |||
198 | gpiochip_add(&ctlr->chip); | ||
199 | } | ||
200 | |||
201 | soc_info->gpio_ctlrs = chips; | ||
202 | soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32); | ||
203 | return 0; | ||
204 | } | ||
205 | pure_initcall(tnetv107x_gpio_setup); | ||
diff --git a/drivers/gpio/gpio-u300.c b/drivers/gpio/gpio-u300.c index 53e8255cb0ba..4035778852b0 100644 --- a/drivers/gpio/gpio-u300.c +++ b/drivers/gpio/gpio-u300.c | |||
@@ -1,18 +1,17 @@ | |||
1 | /* | 1 | /* |
2 | * U300 GPIO module. | 2 | * U300 GPIO module. |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2009 ST-Ericsson AB | 4 | * Copyright (C) 2007-2011 ST-Ericsson AB |
5 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
6 | * This can driver either of the two basic GPIO cores | 6 | * This can driver either of the two basic GPIO cores |
7 | * available in the U300 platforms: | 7 | * available in the U300 platforms: |
8 | * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) | 8 | * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) |
9 | * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) | 9 | * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) |
10 | * Notice that you also have inline macros in <asm-arch/gpio.h> | 10 | * Author: Linus Walleij <linus.walleij@linaro.org> |
11 | * Author: Linus Walleij <linus.walleij@stericsson.com> | ||
12 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | 11 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> |
13 | * | ||
14 | */ | 12 | */ |
15 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/irq.h> | ||
16 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
17 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
18 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
@@ -21,677 +20,898 @@ | |||
21 | #include <linux/err.h> | 20 | #include <linux/err.h> |
22 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
23 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/list.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <mach/gpio-u300.h> | ||
24 | 26 | ||
25 | /* Reference to GPIO block clock */ | 27 | /* |
26 | static struct clk *clk; | 28 | * Bias modes for U300 GPIOs |
29 | * | ||
30 | * GPIO_U300_CONFIG_BIAS_UNKNOWN: this bias mode is not known to us | ||
31 | * GPIO_U300_CONFIG_BIAS_FLOAT: no specific bias, the GPIO will float or state | ||
32 | * is not controlled by software | ||
33 | * GPIO_U300_CONFIG_BIAS_PULL_UP: the GPIO will be pulled up (usually with high | ||
34 | * impedance to VDD) | ||
35 | */ | ||
36 | #define GPIO_U300_CONFIG_BIAS_UNKNOWN 0x1000 | ||
37 | #define GPIO_U300_CONFIG_BIAS_FLOAT 0x1001 | ||
38 | #define GPIO_U300_CONFIG_BIAS_PULL_UP 0x1002 | ||
27 | 39 | ||
28 | /* Memory resource */ | 40 | /* |
29 | static struct resource *memres; | 41 | * Drive modes for U300 GPIOs (output) |
30 | static void __iomem *virtbase; | 42 | * |
31 | static struct device *gpiodev; | 43 | * GPIO_U300_CONFIG_DRIVE_PUSH_PULL: the GPIO will be driven actively high and |
44 | * low, this is the most typical case and is typically achieved with two | ||
45 | * active transistors on the output | ||
46 | * GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: the GPIO will be driven with open drain | ||
47 | * (open collector) which means it is usually wired with other output | ||
48 | * ports which are then pulled up with an external resistor | ||
49 | * GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: the GPIO will be driven with open drain | ||
50 | * (open emitter) which is the same as open drain mutatis mutandis but | ||
51 | * pulled to ground | ||
52 | */ | ||
53 | #define GPIO_U300_CONFIG_DRIVE_PUSH_PULL 0x2000 | ||
54 | #define GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN 0x2001 | ||
55 | #define GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE 0x2002 | ||
56 | |||
57 | /* | ||
58 | * Register definitions for COH 901 335 variant | ||
59 | */ | ||
60 | #define U300_335_PORT_STRIDE (0x1C) | ||
61 | /* Port X Pin Data Register 32bit, this is both input and output (R/W) */ | ||
62 | #define U300_335_PXPDIR (0x00) | ||
63 | #define U300_335_PXPDOR (0x00) | ||
64 | /* Port X Pin Config Register 32bit (R/W) */ | ||
65 | #define U300_335_PXPCR (0x04) | ||
66 | /* This register layout is the same in both blocks */ | ||
67 | #define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) | ||
68 | #define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) | ||
69 | #define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) | ||
70 | #define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) | ||
71 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) | ||
72 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) | ||
73 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) | ||
74 | /* Port X Interrupt Event Register 32bit (R/W) */ | ||
75 | #define U300_335_PXIEV (0x08) | ||
76 | /* Port X Interrupt Enable Register 32bit (R/W) */ | ||
77 | #define U300_335_PXIEN (0x0C) | ||
78 | /* Port X Interrupt Force Register 32bit (R/W) */ | ||
79 | #define U300_335_PXIFR (0x10) | ||
80 | /* Port X Interrupt Config Register 32bit (R/W) */ | ||
81 | #define U300_335_PXICR (0x14) | ||
82 | /* This register layout is the same in both blocks */ | ||
83 | #define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) | ||
84 | #define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) | ||
85 | #define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) | ||
86 | #define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) | ||
87 | /* Port X Pull-up Enable Register 32bit (R/W) */ | ||
88 | #define U300_335_PXPER (0x18) | ||
89 | /* This register layout is the same in both blocks */ | ||
90 | #define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) | ||
91 | #define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) | ||
92 | /* Control Register 32bit (R/W) */ | ||
93 | #define U300_335_CR (0x54) | ||
94 | #define U300_335_CR_BLOCK_CLOCK_ENABLE (0x00000001UL) | ||
95 | |||
96 | /* | ||
97 | * Register definitions for COH 901 571 / 3 variant | ||
98 | */ | ||
99 | #define U300_571_PORT_STRIDE (0x30) | ||
100 | /* | ||
101 | * Control Register 32bit (R/W) | ||
102 | * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores | ||
103 | * gives the number of GPIO pins. | ||
104 | * bit 8-2 (mask 0x000001FC) contains the core version ID. | ||
105 | */ | ||
106 | #define U300_571_CR (0x00) | ||
107 | #define U300_571_CR_SYNC_SEL_ENABLE (0x00000002UL) | ||
108 | #define U300_571_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) | ||
109 | /* | ||
110 | * These registers have the same layout and function as the corresponding | ||
111 | * COH 901 335 registers, just at different offset. | ||
112 | */ | ||
113 | #define U300_571_PXPDIR (0x04) | ||
114 | #define U300_571_PXPDOR (0x08) | ||
115 | #define U300_571_PXPCR (0x0C) | ||
116 | #define U300_571_PXPER (0x10) | ||
117 | #define U300_571_PXIEV (0x14) | ||
118 | #define U300_571_PXIEN (0x18) | ||
119 | #define U300_571_PXIFR (0x1C) | ||
120 | #define U300_571_PXICR (0x20) | ||
121 | |||
122 | /* 8 bits per port, no version has more than 7 ports */ | ||
123 | #define U300_GPIO_PINS_PER_PORT 8 | ||
124 | #define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * 7) | ||
125 | |||
126 | struct u300_gpio { | ||
127 | struct gpio_chip chip; | ||
128 | struct list_head port_list; | ||
129 | struct clk *clk; | ||
130 | struct resource *memres; | ||
131 | void __iomem *base; | ||
132 | struct device *dev; | ||
133 | int irq_base; | ||
134 | u32 stride; | ||
135 | /* Register offsets */ | ||
136 | u32 pcr; | ||
137 | u32 dor; | ||
138 | u32 dir; | ||
139 | u32 per; | ||
140 | u32 icr; | ||
141 | u32 ien; | ||
142 | u32 iev; | ||
143 | }; | ||
32 | 144 | ||
33 | struct u300_gpio_port { | 145 | struct u300_gpio_port { |
34 | const char *name; | 146 | struct list_head node; |
147 | struct u300_gpio *gpio; | ||
148 | char name[8]; | ||
35 | int irq; | 149 | int irq; |
36 | int number; | 150 | int number; |
151 | u8 toggle_edge_mode; | ||
37 | }; | 152 | }; |
38 | 153 | ||
154 | /* | ||
155 | * Macro to expand to read a specific register found in the "gpio" | ||
156 | * struct. It requires the struct u300_gpio *gpio variable to exist in | ||
157 | * its context. It calculates the port offset from the given pin | ||
158 | * offset, muliplies by the port stride and adds the register offset | ||
159 | * so it provides a pointer to the desired register. | ||
160 | */ | ||
161 | #define U300_PIN_REG(pin, reg) \ | ||
162 | (gpio->base + (pin >> 3) * gpio->stride + gpio->reg) | ||
39 | 163 | ||
40 | static struct u300_gpio_port gpio_ports[] = { | 164 | /* |
41 | { | 165 | * Provides a bitmask for a specific gpio pin inside an 8-bit GPIO |
42 | .name = "gpio0", | 166 | * register. |
43 | .number = 0, | 167 | */ |
44 | }, | 168 | #define U300_PIN_BIT(pin) \ |
45 | { | 169 | (1 << (pin & 0x07)) |
46 | .name = "gpio1", | ||
47 | .number = 1, | ||
48 | }, | ||
49 | { | ||
50 | .name = "gpio2", | ||
51 | .number = 2, | ||
52 | }, | ||
53 | #ifdef U300_COH901571_3 | ||
54 | { | ||
55 | .name = "gpio3", | ||
56 | .number = 3, | ||
57 | }, | ||
58 | { | ||
59 | .name = "gpio4", | ||
60 | .number = 4, | ||
61 | }, | ||
62 | #ifdef CONFIG_MACH_U300_BS335 | ||
63 | { | ||
64 | .name = "gpio5", | ||
65 | .number = 5, | ||
66 | }, | ||
67 | { | ||
68 | .name = "gpio6", | ||
69 | .number = 6, | ||
70 | }, | ||
71 | #endif | ||
72 | #endif | ||
73 | 170 | ||
171 | struct u300_gpio_confdata { | ||
172 | u16 bias_mode; | ||
173 | bool output; | ||
174 | int outval; | ||
74 | }; | 175 | }; |
75 | 176 | ||
177 | /* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */ | ||
178 | #define BS335_GPIO_NUM_PORTS 7 | ||
179 | /* BS365 has five ports of 8 bits each = GPIO pins 0..39 */ | ||
180 | #define BS365_GPIO_NUM_PORTS 5 | ||
76 | 181 | ||
77 | #ifdef U300_COH901571_3 | 182 | #define U300_FLOATING_INPUT { \ |
183 | .bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \ | ||
184 | .output = false, \ | ||
185 | } | ||
78 | 186 | ||
79 | /* Default input value */ | 187 | #define U300_PULL_UP_INPUT { \ |
80 | #define DEFAULT_OUTPUT_LOW 0 | 188 | .bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \ |
81 | #define DEFAULT_OUTPUT_HIGH 1 | 189 | .output = false, \ |
190 | } | ||
82 | 191 | ||
83 | /* GPIO Pull-Up status */ | 192 | #define U300_OUTPUT_LOW { \ |
84 | #define DISABLE_PULL_UP 0 | 193 | .output = true, \ |
85 | #define ENABLE_PULL_UP 1 | 194 | .outval = 0, \ |
195 | } | ||
86 | 196 | ||
87 | #define GPIO_NOT_USED 0 | 197 | #define U300_OUTPUT_HIGH { \ |
88 | #define GPIO_IN 1 | 198 | .output = true, \ |
89 | #define GPIO_OUT 2 | 199 | .outval = 1, \ |
200 | } | ||
90 | 201 | ||
91 | struct u300_gpio_configuration_data { | ||
92 | unsigned char pin_usage; | ||
93 | unsigned char default_output_value; | ||
94 | unsigned char pull_up; | ||
95 | }; | ||
96 | 202 | ||
97 | /* Initial configuration */ | 203 | /* Initial configuration */ |
98 | const struct u300_gpio_configuration_data | 204 | static const struct __initdata u300_gpio_confdata |
99 | u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { | 205 | bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { |
100 | #ifdef CONFIG_MACH_U300_BS335 | ||
101 | /* Port 0, pins 0-7 */ | 206 | /* Port 0, pins 0-7 */ |
102 | { | 207 | { |
103 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 208 | U300_FLOATING_INPUT, |
104 | {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, | 209 | U300_OUTPUT_HIGH, |
105 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 210 | U300_FLOATING_INPUT, |
106 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 211 | U300_OUTPUT_LOW, |
107 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 212 | U300_OUTPUT_LOW, |
108 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 213 | U300_OUTPUT_LOW, |
109 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 214 | U300_OUTPUT_LOW, |
110 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 215 | U300_OUTPUT_LOW, |
111 | }, | 216 | }, |
112 | /* Port 1, pins 0-7 */ | 217 | /* Port 1, pins 0-7 */ |
113 | { | 218 | { |
114 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 219 | U300_OUTPUT_LOW, |
115 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 220 | U300_OUTPUT_LOW, |
116 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 221 | U300_OUTPUT_LOW, |
117 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 222 | U300_PULL_UP_INPUT, |
118 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 223 | U300_FLOATING_INPUT, |
119 | {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, | 224 | U300_OUTPUT_HIGH, |
120 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 225 | U300_OUTPUT_LOW, |
121 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 226 | U300_OUTPUT_LOW, |
122 | }, | 227 | }, |
123 | /* Port 2, pins 0-7 */ | 228 | /* Port 2, pins 0-7 */ |
124 | { | 229 | { |
125 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 230 | U300_FLOATING_INPUT, |
126 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 231 | U300_FLOATING_INPUT, |
127 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 232 | U300_FLOATING_INPUT, |
128 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 233 | U300_FLOATING_INPUT, |
129 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 234 | U300_OUTPUT_LOW, |
130 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 235 | U300_PULL_UP_INPUT, |
131 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 236 | U300_OUTPUT_LOW, |
132 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | 237 | U300_PULL_UP_INPUT, |
133 | }, | 238 | }, |
134 | /* Port 3, pins 0-7 */ | 239 | /* Port 3, pins 0-7 */ |
135 | { | 240 | { |
136 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 241 | U300_PULL_UP_INPUT, |
137 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 242 | U300_OUTPUT_LOW, |
138 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 243 | U300_FLOATING_INPUT, |
139 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 244 | U300_FLOATING_INPUT, |
140 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 245 | U300_FLOATING_INPUT, |
141 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 246 | U300_FLOATING_INPUT, |
142 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 247 | U300_FLOATING_INPUT, |
143 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 248 | U300_FLOATING_INPUT, |
144 | }, | 249 | }, |
145 | /* Port 4, pins 0-7 */ | 250 | /* Port 4, pins 0-7 */ |
146 | { | 251 | { |
147 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 252 | U300_FLOATING_INPUT, |
148 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 253 | U300_FLOATING_INPUT, |
149 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 254 | U300_FLOATING_INPUT, |
150 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 255 | U300_FLOATING_INPUT, |
151 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 256 | U300_FLOATING_INPUT, |
152 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 257 | U300_FLOATING_INPUT, |
153 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 258 | U300_FLOATING_INPUT, |
154 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 259 | U300_FLOATING_INPUT, |
155 | }, | 260 | }, |
156 | /* Port 5, pins 0-7 */ | 261 | /* Port 5, pins 0-7 */ |
157 | { | 262 | { |
158 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 263 | U300_FLOATING_INPUT, |
159 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 264 | U300_FLOATING_INPUT, |
160 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 265 | U300_FLOATING_INPUT, |
161 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 266 | U300_FLOATING_INPUT, |
162 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 267 | U300_FLOATING_INPUT, |
163 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 268 | U300_FLOATING_INPUT, |
164 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 269 | U300_FLOATING_INPUT, |
165 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 270 | U300_FLOATING_INPUT, |
166 | }, | 271 | }, |
167 | /* Port 6, pind 0-7 */ | 272 | /* Port 6, pind 0-7 */ |
168 | { | 273 | { |
169 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 274 | U300_FLOATING_INPUT, |
170 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 275 | U300_FLOATING_INPUT, |
171 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 276 | U300_FLOATING_INPUT, |
172 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 277 | U300_FLOATING_INPUT, |
173 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 278 | U300_FLOATING_INPUT, |
174 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 279 | U300_FLOATING_INPUT, |
175 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 280 | U300_FLOATING_INPUT, |
176 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 281 | U300_FLOATING_INPUT, |
177 | } | 282 | } |
178 | #endif | 283 | }; |
179 | 284 | ||
180 | #ifdef CONFIG_MACH_U300_BS365 | 285 | static const struct __initdata u300_gpio_confdata |
286 | bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { | ||
181 | /* Port 0, pins 0-7 */ | 287 | /* Port 0, pins 0-7 */ |
182 | { | 288 | { |
183 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 289 | U300_FLOATING_INPUT, |
184 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 290 | U300_OUTPUT_LOW, |
185 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 291 | U300_FLOATING_INPUT, |
186 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 292 | U300_OUTPUT_LOW, |
187 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 293 | U300_OUTPUT_LOW, |
188 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 294 | U300_OUTPUT_LOW, |
189 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 295 | U300_PULL_UP_INPUT, |
190 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 296 | U300_FLOATING_INPUT, |
191 | }, | 297 | }, |
192 | /* Port 1, pins 0-7 */ | 298 | /* Port 1, pins 0-7 */ |
193 | { | 299 | { |
194 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 300 | U300_OUTPUT_LOW, |
195 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 301 | U300_FLOATING_INPUT, |
196 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 302 | U300_OUTPUT_LOW, |
197 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 303 | U300_FLOATING_INPUT, |
198 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 304 | U300_FLOATING_INPUT, |
199 | {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, | 305 | U300_OUTPUT_HIGH, |
200 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 306 | U300_OUTPUT_LOW, |
201 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | 307 | U300_OUTPUT_LOW, |
202 | }, | 308 | }, |
203 | /* Port 2, pins 0-7 */ | 309 | /* Port 2, pins 0-7 */ |
204 | { | 310 | { |
205 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 311 | U300_FLOATING_INPUT, |
206 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 312 | U300_PULL_UP_INPUT, |
207 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 313 | U300_OUTPUT_LOW, |
208 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | 314 | U300_OUTPUT_LOW, |
209 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 315 | U300_PULL_UP_INPUT, |
210 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 316 | U300_PULL_UP_INPUT, |
211 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 317 | U300_PULL_UP_INPUT, |
212 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | 318 | U300_PULL_UP_INPUT, |
213 | }, | 319 | }, |
214 | /* Port 3, pins 0-7 */ | 320 | /* Port 3, pins 0-7 */ |
215 | { | 321 | { |
216 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 322 | U300_PULL_UP_INPUT, |
217 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 323 | U300_PULL_UP_INPUT, |
218 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 324 | U300_PULL_UP_INPUT, |
219 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 325 | U300_PULL_UP_INPUT, |
220 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 326 | U300_PULL_UP_INPUT, |
221 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 327 | U300_PULL_UP_INPUT, |
222 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 328 | U300_PULL_UP_INPUT, |
223 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | 329 | U300_PULL_UP_INPUT, |
224 | }, | 330 | }, |
225 | /* Port 4, pins 0-7 */ | 331 | /* Port 4, pins 0-7 */ |
226 | { | 332 | { |
227 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 333 | U300_PULL_UP_INPUT, |
228 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 334 | U300_PULL_UP_INPUT, |
229 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 335 | U300_PULL_UP_INPUT, |
230 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 336 | U300_PULL_UP_INPUT, |
231 | /* These 4 pins doesn't exist on DB3210 */ | 337 | /* These 4 pins doesn't exist on DB3210 */ |
232 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 338 | U300_OUTPUT_LOW, |
233 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 339 | U300_OUTPUT_LOW, |
234 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | 340 | U300_OUTPUT_LOW, |
235 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | 341 | U300_OUTPUT_LOW, |
236 | } | 342 | } |
237 | #endif | ||
238 | }; | 343 | }; |
239 | #endif | ||
240 | 344 | ||
241 | 345 | /** | |
242 | /* No users == we can power down GPIO */ | 346 | * to_u300_gpio() - get the pointer to u300_gpio |
243 | static int gpio_users; | 347 | * @chip: the gpio chip member of the structure u300_gpio |
244 | |||
245 | struct gpio_struct { | ||
246 | int (*callback)(void *); | ||
247 | void *data; | ||
248 | int users; | ||
249 | }; | ||
250 | |||
251 | static struct gpio_struct gpio_pin[U300_GPIO_MAX]; | ||
252 | |||
253 | /* | ||
254 | * Let drivers register callback in order to get notified when there is | ||
255 | * an interrupt on the gpio pin | ||
256 | */ | 348 | */ |
257 | int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data) | 349 | static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip) |
258 | { | 350 | { |
259 | if (gpio_pin[gpio].callback) | 351 | return container_of(chip, struct u300_gpio, chip); |
260 | dev_warn(gpiodev, "%s: WARNING: callback already " | ||
261 | "registered for gpio pin#%d\n", __func__, gpio); | ||
262 | gpio_pin[gpio].callback = func; | ||
263 | gpio_pin[gpio].data = data; | ||
264 | |||
265 | return 0; | ||
266 | } | 352 | } |
267 | EXPORT_SYMBOL(gpio_register_callback); | ||
268 | 353 | ||
269 | int gpio_unregister_callback(unsigned gpio) | 354 | static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) |
270 | { | 355 | { |
271 | if (!gpio_pin[gpio].callback) | 356 | struct u300_gpio *gpio = to_u300_gpio(chip); |
272 | dev_warn(gpiodev, "%s: WARNING: callback already " | ||
273 | "unregistered for gpio pin#%d\n", __func__, gpio); | ||
274 | gpio_pin[gpio].callback = NULL; | ||
275 | gpio_pin[gpio].data = NULL; | ||
276 | 357 | ||
277 | return 0; | 358 | return readl(U300_PIN_REG(offset, dir)) & U300_PIN_BIT(offset); |
278 | } | 359 | } |
279 | EXPORT_SYMBOL(gpio_unregister_callback); | ||
280 | 360 | ||
281 | /* Non-zero means valid */ | 361 | static void u300_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
282 | int gpio_is_valid(int number) | ||
283 | { | 362 | { |
284 | if (number >= 0 && | 363 | struct u300_gpio *gpio = to_u300_gpio(chip); |
285 | number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT)) | 364 | unsigned long flags; |
286 | return 1; | 365 | u32 val; |
287 | return 0; | ||
288 | } | ||
289 | EXPORT_SYMBOL(gpio_is_valid); | ||
290 | 366 | ||
291 | int gpio_request(unsigned gpio, const char *label) | 367 | local_irq_save(flags); |
292 | { | ||
293 | if (gpio_pin[gpio].users) | ||
294 | return -EINVAL; | ||
295 | else | ||
296 | gpio_pin[gpio].users++; | ||
297 | 368 | ||
298 | gpio_users++; | 369 | val = readl(U300_PIN_REG(offset, dor)); |
370 | if (value) | ||
371 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); | ||
372 | else | ||
373 | writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); | ||
299 | 374 | ||
300 | return 0; | 375 | local_irq_restore(flags); |
301 | } | 376 | } |
302 | EXPORT_SYMBOL(gpio_request); | ||
303 | 377 | ||
304 | void gpio_free(unsigned gpio) | 378 | static int u300_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
305 | { | 379 | { |
306 | gpio_users--; | 380 | struct u300_gpio *gpio = to_u300_gpio(chip); |
307 | gpio_pin[gpio].users--; | 381 | unsigned long flags; |
308 | if (unlikely(gpio_pin[gpio].users < 0)) { | 382 | u32 val; |
309 | dev_warn(gpiodev, "warning: gpio#%d release mismatch\n", | ||
310 | gpio); | ||
311 | gpio_pin[gpio].users = 0; | ||
312 | } | ||
313 | |||
314 | return; | ||
315 | } | ||
316 | EXPORT_SYMBOL(gpio_free); | ||
317 | 383 | ||
318 | /* This returns zero or nonzero */ | 384 | local_irq_save(flags); |
319 | int gpio_get_value(unsigned gpio) | 385 | val = readl(U300_PIN_REG(offset, pcr)); |
320 | { | 386 | /* Mask out this pin, note 2 bits per setting */ |
321 | return readl(virtbase + U300_GPIO_PXPDIR + | 387 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); |
322 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07)); | 388 | writel(val, U300_PIN_REG(offset, pcr)); |
389 | local_irq_restore(flags); | ||
390 | return 0; | ||
323 | } | 391 | } |
324 | EXPORT_SYMBOL(gpio_get_value); | ||
325 | 392 | ||
326 | /* | 393 | static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, |
327 | * We hope that the compiler will optimize away the unused branch | 394 | int value) |
328 | * in case "value" is a constant | ||
329 | */ | ||
330 | void gpio_set_value(unsigned gpio, int value) | ||
331 | { | 395 | { |
332 | u32 val; | 396 | struct u300_gpio *gpio = to_u300_gpio(chip); |
333 | unsigned long flags; | 397 | unsigned long flags; |
398 | u32 oldmode; | ||
399 | u32 val; | ||
334 | 400 | ||
335 | local_irq_save(flags); | 401 | local_irq_save(flags); |
336 | if (value) { | 402 | val = readl(U300_PIN_REG(offset, pcr)); |
337 | /* set */ | 403 | /* |
338 | val = readl(virtbase + U300_GPIO_PXPDOR + | 404 | * Drive mode must be set by the special mode set function, set |
339 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) | 405 | * push/pull mode by default if no mode has been selected. |
340 | & (1 << (gpio & 0x07)); | 406 | */ |
341 | writel(val | (1 << (gpio & 0x07)), virtbase + | 407 | oldmode = val & (U300_GPIO_PXPCR_PIN_MODE_MASK << |
342 | U300_GPIO_PXPDOR + | 408 | ((offset & 0x07) << 1)); |
343 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | 409 | /* mode = 0 means input, else some mode is already set */ |
344 | } else { | 410 | if (oldmode == 0) { |
345 | /* clear */ | 411 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << |
346 | val = readl(virtbase + U300_GPIO_PXPDOR + | 412 | ((offset & 0x07) << 1)); |
347 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) | 413 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL |
348 | & (1 << (gpio & 0x07)); | 414 | << ((offset & 0x07) << 1)); |
349 | writel(val & ~(1 << (gpio & 0x07)), virtbase + | 415 | writel(val, U300_PIN_REG(offset, pcr)); |
350 | U300_GPIO_PXPDOR + | ||
351 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
352 | } | 416 | } |
417 | u300_gpio_set(chip, offset, value); | ||
353 | local_irq_restore(flags); | 418 | local_irq_restore(flags); |
419 | return 0; | ||
354 | } | 420 | } |
355 | EXPORT_SYMBOL(gpio_set_value); | ||
356 | 421 | ||
357 | int gpio_direction_input(unsigned gpio) | 422 | static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
358 | { | 423 | { |
424 | struct u300_gpio *gpio = to_u300_gpio(chip); | ||
425 | int retirq = gpio->irq_base + offset; | ||
426 | |||
427 | dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, | ||
428 | retirq); | ||
429 | return retirq; | ||
430 | } | ||
431 | |||
432 | static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, | ||
433 | u16 param, unsigned long *data) | ||
434 | { | ||
435 | struct u300_gpio *gpio = to_u300_gpio(chip); | ||
359 | unsigned long flags; | 436 | unsigned long flags; |
360 | u32 val; | 437 | u32 val; |
361 | 438 | ||
362 | if (gpio > U300_GPIO_MAX) | ||
363 | return -EINVAL; | ||
364 | |||
365 | local_irq_save(flags); | 439 | local_irq_save(flags); |
366 | val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | 440 | switch (param) { |
367 | U300_GPIO_PORTX_SPACING); | 441 | case GPIO_U300_CONFIG_BIAS_UNKNOWN: |
368 | /* Mask out this pin*/ | 442 | case GPIO_U300_CONFIG_BIAS_FLOAT: |
369 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1)); | 443 | val = readl(U300_PIN_REG(offset, per)); |
370 | /* This is not needed since it sets the bits to zero.*/ | 444 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); |
371 | /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */ | 445 | break; |
372 | writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | 446 | case GPIO_U300_CONFIG_BIAS_PULL_UP: |
373 | U300_GPIO_PORTX_SPACING); | 447 | val = readl(U300_PIN_REG(offset, per)); |
448 | writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); | ||
449 | break; | ||
450 | case GPIO_U300_CONFIG_DRIVE_PUSH_PULL: | ||
451 | val = readl(U300_PIN_REG(offset, pcr)); | ||
452 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK | ||
453 | << ((offset & 0x07) << 1)); | ||
454 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL | ||
455 | << ((offset & 0x07) << 1)); | ||
456 | writel(val, U300_PIN_REG(offset, pcr)); | ||
457 | break; | ||
458 | case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: | ||
459 | val = readl(U300_PIN_REG(offset, pcr)); | ||
460 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK | ||
461 | << ((offset & 0x07) << 1)); | ||
462 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN | ||
463 | << ((offset & 0x07) << 1)); | ||
464 | writel(val, U300_PIN_REG(offset, pcr)); | ||
465 | break; | ||
466 | case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: | ||
467 | val = readl(U300_PIN_REG(offset, pcr)); | ||
468 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK | ||
469 | << ((offset & 0x07) << 1)); | ||
470 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE | ||
471 | << ((offset & 0x07) << 1)); | ||
472 | writel(val, U300_PIN_REG(offset, pcr)); | ||
473 | break; | ||
474 | default: | ||
475 | local_irq_restore(flags); | ||
476 | dev_err(gpio->dev, "illegal configuration requested\n"); | ||
477 | return -EINVAL; | ||
478 | } | ||
374 | local_irq_restore(flags); | 479 | local_irq_restore(flags); |
375 | return 0; | 480 | return 0; |
376 | } | 481 | } |
377 | EXPORT_SYMBOL(gpio_direction_input); | ||
378 | 482 | ||
379 | int gpio_direction_output(unsigned gpio, int value) | 483 | static struct gpio_chip u300_gpio_chip = { |
484 | .label = "u300-gpio-chip", | ||
485 | .owner = THIS_MODULE, | ||
486 | .get = u300_gpio_get, | ||
487 | .set = u300_gpio_set, | ||
488 | .direction_input = u300_gpio_direction_input, | ||
489 | .direction_output = u300_gpio_direction_output, | ||
490 | .to_irq = u300_gpio_to_irq, | ||
491 | }; | ||
492 | |||
493 | static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset) | ||
380 | { | 494 | { |
381 | unsigned long flags; | ||
382 | u32 val; | 495 | u32 val; |
383 | 496 | ||
384 | if (gpio > U300_GPIO_MAX) | 497 | val = readl(U300_PIN_REG(offset, icr)); |
385 | return -EINVAL; | 498 | /* Set mode depending on state */ |
386 | 499 | if (u300_gpio_get(&gpio->chip, offset)) { | |
387 | local_irq_save(flags); | 500 | /* High now, let's trigger on falling edge next then */ |
388 | val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | 501 | writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); |
389 | U300_GPIO_PORTX_SPACING); | 502 | dev_dbg(gpio->dev, "next IRQ on falling edge on pin %d\n", |
390 | /* Mask out this pin */ | 503 | offset); |
391 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1)); | 504 | } else { |
392 | /* | 505 | /* Low now, let's trigger on rising edge next then */ |
393 | * FIXME: configure for push/pull, open drain or open source per pin | 506 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); |
394 | * in setup. The current driver will only support push/pull. | 507 | dev_dbg(gpio->dev, "next IRQ on rising edge on pin %d\n", |
395 | */ | 508 | offset); |
396 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL | 509 | } |
397 | << ((gpio & 0x07) << 1)); | ||
398 | writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | ||
399 | U300_GPIO_PORTX_SPACING); | ||
400 | gpio_set_value(gpio, value); | ||
401 | local_irq_restore(flags); | ||
402 | return 0; | ||
403 | } | 510 | } |
404 | EXPORT_SYMBOL(gpio_direction_output); | ||
405 | 511 | ||
406 | /* | 512 | static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) |
407 | * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0). | ||
408 | */ | ||
409 | void enable_irq_on_gpio_pin(unsigned gpio, int edge) | ||
410 | { | 513 | { |
514 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | ||
515 | struct u300_gpio *gpio = port->gpio; | ||
516 | int offset = d->irq - gpio->irq_base; | ||
411 | u32 val; | 517 | u32 val; |
412 | unsigned long flags; | ||
413 | local_irq_save(flags); | ||
414 | 518 | ||
415 | val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | 519 | if ((trigger & IRQF_TRIGGER_RISING) && |
416 | U300_GPIO_PORTX_SPACING); | 520 | (trigger & IRQF_TRIGGER_FALLING)) { |
417 | val |= (1 << (gpio & 0x07)); | 521 | /* |
418 | writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | 522 | * The GPIO block can only trigger on falling OR rising edges, |
419 | U300_GPIO_PORTX_SPACING); | 523 | * not both. So we need to toggle the mode whenever the pin |
420 | val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) * | 524 | * goes from one state to the other with a special state flag |
421 | U300_GPIO_PORTX_SPACING); | 525 | */ |
422 | if (edge) | 526 | dev_dbg(gpio->dev, |
423 | val |= (1 << (gpio & 0x07)); | 527 | "trigger on both rising and falling edge on pin %d\n", |
424 | else | 528 | offset); |
425 | val &= ~(1 << (gpio & 0x07)); | 529 | port->toggle_edge_mode |= U300_PIN_BIT(offset); |
426 | writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) * | 530 | u300_toggle_trigger(gpio, offset); |
427 | U300_GPIO_PORTX_SPACING); | 531 | } else if (trigger & IRQF_TRIGGER_RISING) { |
428 | local_irq_restore(flags); | 532 | dev_dbg(gpio->dev, "trigger on rising edge on pin %d\n", |
533 | offset); | ||
534 | val = readl(U300_PIN_REG(offset, icr)); | ||
535 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); | ||
536 | port->toggle_edge_mode &= ~U300_PIN_BIT(offset); | ||
537 | } else if (trigger & IRQF_TRIGGER_FALLING) { | ||
538 | dev_dbg(gpio->dev, "trigger on falling edge on pin %d\n", | ||
539 | offset); | ||
540 | val = readl(U300_PIN_REG(offset, icr)); | ||
541 | writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); | ||
542 | port->toggle_edge_mode &= ~U300_PIN_BIT(offset); | ||
543 | } | ||
544 | |||
545 | return 0; | ||
429 | } | 546 | } |
430 | EXPORT_SYMBOL(enable_irq_on_gpio_pin); | ||
431 | 547 | ||
432 | void disable_irq_on_gpio_pin(unsigned gpio) | 548 | static void u300_gpio_irq_enable(struct irq_data *d) |
433 | { | 549 | { |
550 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | ||
551 | struct u300_gpio *gpio = port->gpio; | ||
552 | int offset = d->irq - gpio->irq_base; | ||
434 | u32 val; | 553 | u32 val; |
435 | unsigned long flags; | 554 | unsigned long flags; |
436 | 555 | ||
437 | local_irq_save(flags); | 556 | local_irq_save(flags); |
438 | val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | 557 | val = readl(U300_PIN_REG(offset, ien)); |
439 | U300_GPIO_PORTX_SPACING); | 558 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); |
440 | val &= ~(1 << (gpio & 0x07)); | ||
441 | writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | ||
442 | U300_GPIO_PORTX_SPACING); | ||
443 | local_irq_restore(flags); | 559 | local_irq_restore(flags); |
444 | } | 560 | } |
445 | EXPORT_SYMBOL(disable_irq_on_gpio_pin); | ||
446 | 561 | ||
447 | /* Enable (value == 0) or disable (value == 1) internal pullup */ | 562 | static void u300_gpio_irq_disable(struct irq_data *d) |
448 | void gpio_pullup(unsigned gpio, int value) | ||
449 | { | 563 | { |
564 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | ||
565 | struct u300_gpio *gpio = port->gpio; | ||
566 | int offset = d->irq - gpio->irq_base; | ||
450 | u32 val; | 567 | u32 val; |
451 | unsigned long flags; | 568 | unsigned long flags; |
452 | 569 | ||
453 | local_irq_save(flags); | 570 | local_irq_save(flags); |
454 | if (value) { | 571 | val = readl(U300_PIN_REG(offset, ien)); |
455 | val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) * | 572 | writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); |
456 | U300_GPIO_PORTX_SPACING); | ||
457 | writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER + | ||
458 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
459 | } else { | ||
460 | val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) * | ||
461 | U300_GPIO_PORTX_SPACING); | ||
462 | writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER + | ||
463 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
464 | } | ||
465 | local_irq_restore(flags); | 573 | local_irq_restore(flags); |
466 | } | 574 | } |
467 | EXPORT_SYMBOL(gpio_pullup); | ||
468 | 575 | ||
469 | static irqreturn_t gpio_irq_handler(int irq, void *dev_id) | 576 | static struct irq_chip u300_gpio_irqchip = { |
577 | .name = "u300-gpio-irqchip", | ||
578 | .irq_enable = u300_gpio_irq_enable, | ||
579 | .irq_disable = u300_gpio_irq_disable, | ||
580 | .irq_set_type = u300_gpio_irq_type, | ||
581 | |||
582 | }; | ||
583 | |||
584 | static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
470 | { | 585 | { |
471 | struct u300_gpio_port *port = dev_id; | 586 | struct u300_gpio_port *port = irq_get_handler_data(irq); |
472 | u32 val; | 587 | struct u300_gpio *gpio = port->gpio; |
473 | int pin; | 588 | int pinoffset = port->number << 3; /* get the right stride */ |
589 | unsigned long val; | ||
474 | 590 | ||
591 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
475 | /* Read event register */ | 592 | /* Read event register */ |
476 | val = readl(virtbase + U300_GPIO_PXIEV + port->number * | 593 | val = readl(U300_PIN_REG(pinoffset, iev)); |
477 | U300_GPIO_PORTX_SPACING); | ||
478 | /* Mask with enable register */ | ||
479 | val &= readl(virtbase + U300_GPIO_PXIEV + port->number * | ||
480 | U300_GPIO_PORTX_SPACING); | ||
481 | /* Mask relevant bits */ | 594 | /* Mask relevant bits */ |
482 | val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK; | 595 | val &= 0xFFU; /* 8 bits per port */ |
483 | /* ACK IRQ (clear event) */ | 596 | /* ACK IRQ (clear event) */ |
484 | writel(val, virtbase + U300_GPIO_PXIEV + port->number * | 597 | writel(val, U300_PIN_REG(pinoffset, iev)); |
485 | U300_GPIO_PORTX_SPACING); | 598 | |
486 | /* Print message */ | 599 | /* Call IRQ handler */ |
487 | while (val != 0) { | 600 | if (val != 0) { |
488 | unsigned gpio; | 601 | int irqoffset; |
489 | 602 | ||
490 | pin = __ffs(val); | 603 | for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { |
491 | /* mask off this pin */ | 604 | int pin_irq = gpio->irq_base + (port->number << 3) |
492 | val &= ~(1 << pin); | 605 | + irqoffset; |
493 | gpio = (port->number << 3) + pin; | 606 | int offset = pinoffset + irqoffset; |
494 | 607 | ||
495 | if (gpio_pin[gpio].callback) | 608 | dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", |
496 | (void)gpio_pin[gpio].callback(gpio_pin[gpio].data); | 609 | pin_irq, offset); |
497 | else | 610 | generic_handle_irq(pin_irq); |
498 | dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n", | 611 | /* |
499 | gpio); | 612 | * Triggering IRQ on both rising and falling edge |
613 | * needs mockery | ||
614 | */ | ||
615 | if (port->toggle_edge_mode & U300_PIN_BIT(offset)) | ||
616 | u300_toggle_trigger(gpio, offset); | ||
617 | } | ||
500 | } | 618 | } |
501 | return IRQ_HANDLED; | 619 | |
620 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | ||
502 | } | 621 | } |
503 | 622 | ||
504 | static void gpio_set_initial_values(void) | 623 | static void __init u300_gpio_init_pin(struct u300_gpio *gpio, |
624 | int offset, | ||
625 | const struct u300_gpio_confdata *conf) | ||
505 | { | 626 | { |
506 | #ifdef U300_COH901571_3 | 627 | /* Set mode: input or output */ |
507 | int i, j; | 628 | if (conf->output) { |
508 | unsigned long flags; | 629 | u300_gpio_direction_output(&gpio->chip, offset, conf->outval); |
509 | u32 val; | ||
510 | 630 | ||
511 | /* Write default values to all pins */ | 631 | /* Deactivate bias mode for output */ |
512 | for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { | 632 | u300_gpio_config(&gpio->chip, offset, |
513 | val = 0; | 633 | GPIO_U300_CONFIG_BIAS_FLOAT, |
514 | for (j = 0; j < 8; j++) | 634 | NULL); |
515 | val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j; | 635 | |
516 | local_irq_save(flags); | 636 | /* Set drive mode for output */ |
517 | writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING); | 637 | u300_gpio_config(&gpio->chip, offset, |
518 | local_irq_restore(flags); | 638 | GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL); |
639 | |||
640 | dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", | ||
641 | offset, conf->outval); | ||
642 | } else { | ||
643 | u300_gpio_direction_input(&gpio->chip, offset); | ||
644 | |||
645 | /* Always set output low on input pins */ | ||
646 | u300_gpio_set(&gpio->chip, offset, 0); | ||
647 | |||
648 | /* Set bias mode for input */ | ||
649 | u300_gpio_config(&gpio->chip, offset, conf->bias_mode, NULL); | ||
650 | |||
651 | dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", | ||
652 | offset, conf->bias_mode); | ||
519 | } | 653 | } |
654 | } | ||
520 | 655 | ||
521 | /* | 656 | static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio, |
522 | * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED' | 657 | struct u300_gpio_platform *plat) |
523 | * to output and 'GPIO_IN' to input for each port. And initialize | 658 | { |
524 | * default value on outputs. | 659 | int i, j; |
525 | */ | 660 | |
526 | for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { | 661 | /* Write default config and values to all pins */ |
527 | for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) { | 662 | for (i = 0; i < plat->ports; i++) { |
528 | local_irq_save(flags); | 663 | for (j = 0; j < 8; j++) { |
529 | val = readl(virtbase + U300_GPIO_PXPCR + | 664 | const struct u300_gpio_confdata *conf; |
530 | i * U300_GPIO_PORTX_SPACING); | 665 | int offset = (i*8) + j; |
531 | /* Mask out this pin */ | 666 | |
532 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1)); | 667 | if (plat->variant == U300_GPIO_COH901571_3_BS335) |
533 | 668 | conf = &bs335_gpio_config[i][j]; | |
534 | if (u300_gpio_config[i][j].pin_usage != GPIO_IN) | 669 | else if (plat->variant == U300_GPIO_COH901571_3_BS365) |
535 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1)); | 670 | conf = &bs365_gpio_config[i][j]; |
536 | writel(val, virtbase + U300_GPIO_PXPCR + | 671 | else |
537 | i * U300_GPIO_PORTX_SPACING); | 672 | break; |
538 | local_irq_restore(flags); | 673 | |
674 | u300_gpio_init_pin(gpio, offset, conf); | ||
539 | } | 675 | } |
540 | } | 676 | } |
677 | } | ||
541 | 678 | ||
542 | /* Enable or disable the internal pull-ups in the GPIO ASIC block */ | 679 | static inline void u300_gpio_free_ports(struct u300_gpio *gpio) |
543 | for (i = 0; i < U300_GPIO_MAX; i++) { | 680 | { |
544 | val = 0; | 681 | struct u300_gpio_port *port; |
545 | for (j = 0; j < 8; j++) | 682 | struct list_head *p, *n; |
546 | val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j); | 683 | |
547 | local_irq_save(flags); | 684 | list_for_each_safe(p, n, &gpio->port_list) { |
548 | writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING); | 685 | port = list_entry(p, struct u300_gpio_port, node); |
549 | local_irq_restore(flags); | 686 | list_del(&port->node); |
687 | free_irq(port->irq, port); | ||
688 | kfree(port); | ||
550 | } | 689 | } |
551 | #endif | ||
552 | } | 690 | } |
553 | 691 | ||
554 | static int __init gpio_probe(struct platform_device *pdev) | 692 | static int __init u300_gpio_probe(struct platform_device *pdev) |
555 | { | 693 | { |
556 | u32 val; | 694 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); |
695 | struct u300_gpio *gpio; | ||
557 | int err = 0; | 696 | int err = 0; |
697 | int portno; | ||
698 | u32 val; | ||
699 | u32 ifr; | ||
558 | int i; | 700 | int i; |
559 | int num_irqs; | ||
560 | 701 | ||
561 | gpiodev = &pdev->dev; | 702 | gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); |
562 | memset(gpio_pin, 0, sizeof(gpio_pin)); | 703 | if (gpio == NULL) { |
704 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
705 | return -ENOMEM; | ||
706 | } | ||
707 | |||
708 | gpio->chip = u300_gpio_chip; | ||
709 | gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; | ||
710 | gpio->irq_base = plat->gpio_irq_base; | ||
711 | gpio->chip.dev = &pdev->dev; | ||
712 | gpio->chip.base = plat->gpio_base; | ||
713 | gpio->dev = &pdev->dev; | ||
563 | 714 | ||
564 | /* Get GPIO clock */ | 715 | /* Get GPIO clock */ |
565 | clk = clk_get(&pdev->dev, NULL); | 716 | gpio->clk = clk_get(gpio->dev, NULL); |
566 | if (IS_ERR(clk)) { | 717 | if (IS_ERR(gpio->clk)) { |
567 | err = PTR_ERR(clk); | 718 | err = PTR_ERR(gpio->clk); |
568 | dev_err(gpiodev, "could not get GPIO clock\n"); | 719 | dev_err(gpio->dev, "could not get GPIO clock\n"); |
569 | goto err_no_clk; | 720 | goto err_no_clk; |
570 | } | 721 | } |
571 | err = clk_enable(clk); | 722 | err = clk_enable(gpio->clk); |
572 | if (err) { | 723 | if (err) { |
573 | dev_err(gpiodev, "could not enable GPIO clock\n"); | 724 | dev_err(gpio->dev, "could not enable GPIO clock\n"); |
574 | goto err_no_clk_enable; | 725 | goto err_no_clk_enable; |
575 | } | 726 | } |
576 | 727 | ||
577 | memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 728 | gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
578 | if (!memres) | 729 | if (!gpio->memres) { |
730 | dev_err(gpio->dev, "could not get GPIO memory resource\n"); | ||
731 | err = -ENODEV; | ||
579 | goto err_no_resource; | 732 | goto err_no_resource; |
733 | } | ||
580 | 734 | ||
581 | if (!request_mem_region(memres->start, resource_size(memres), | 735 | if (!request_mem_region(gpio->memres->start, |
736 | resource_size(gpio->memres), | ||
582 | "GPIO Controller")) { | 737 | "GPIO Controller")) { |
583 | err = -ENODEV; | 738 | err = -ENODEV; |
584 | goto err_no_ioregion; | 739 | goto err_no_ioregion; |
585 | } | 740 | } |
586 | 741 | ||
587 | virtbase = ioremap(memres->start, resource_size(memres)); | 742 | gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); |
588 | if (!virtbase) { | 743 | if (!gpio->base) { |
589 | err = -ENOMEM; | 744 | err = -ENOMEM; |
590 | goto err_no_ioremap; | 745 | goto err_no_ioremap; |
591 | } | 746 | } |
592 | dev_info(gpiodev, "remapped 0x%08x to %p\n", | 747 | |
593 | memres->start, virtbase); | 748 | if (plat->variant == U300_GPIO_COH901335) { |
594 | 749 | dev_info(gpio->dev, | |
595 | #ifdef U300_COH901335 | 750 | "initializing GPIO Controller COH 901 335\n"); |
596 | dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n"); | 751 | gpio->stride = U300_335_PORT_STRIDE; |
597 | /* Turn on the GPIO block */ | 752 | gpio->pcr = U300_335_PXPCR; |
598 | writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR); | 753 | gpio->dor = U300_335_PXPDOR; |
599 | #endif | 754 | gpio->dir = U300_335_PXPDIR; |
600 | 755 | gpio->per = U300_335_PXPER; | |
601 | #ifdef U300_COH901571_3 | 756 | gpio->icr = U300_335_PXICR; |
602 | dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n"); | 757 | gpio->ien = U300_335_PXIEN; |
603 | val = readl(virtbase + U300_GPIO_CR); | 758 | gpio->iev = U300_335_PXIEV; |
604 | dev_info(gpiodev, "COH901571/3 block version: %d, " \ | 759 | ifr = U300_335_PXIFR; |
605 | "number of cores: %d\n", | 760 | |
606 | ((val & 0x0000FE00) >> 9), | 761 | /* Turn on the GPIO block */ |
607 | ((val & 0x000001FC) >> 2)); | 762 | writel(U300_335_CR_BLOCK_CLOCK_ENABLE, |
608 | writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR); | 763 | gpio->base + U300_335_CR); |
609 | #endif | 764 | } else if (plat->variant == U300_GPIO_COH901571_3_BS335 || |
610 | 765 | plat->variant == U300_GPIO_COH901571_3_BS365) { | |
611 | gpio_set_initial_values(); | 766 | dev_info(gpio->dev, |
612 | 767 | "initializing GPIO Controller COH 901 571/3\n"); | |
613 | for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) { | 768 | gpio->stride = U300_571_PORT_STRIDE; |
614 | 769 | gpio->pcr = U300_571_PXPCR; | |
615 | gpio_ports[num_irqs].irq = | 770 | gpio->dor = U300_571_PXPDOR; |
616 | platform_get_irq_byname(pdev, | 771 | gpio->dir = U300_571_PXPDIR; |
617 | gpio_ports[num_irqs].name); | 772 | gpio->per = U300_571_PXPER; |
618 | 773 | gpio->icr = U300_571_PXICR; | |
619 | err = request_irq(gpio_ports[num_irqs].irq, | 774 | gpio->ien = U300_571_PXIEN; |
620 | gpio_irq_handler, IRQF_DISABLED, | 775 | gpio->iev = U300_571_PXIEV; |
621 | gpio_ports[num_irqs].name, | 776 | ifr = U300_571_PXIFR; |
622 | &gpio_ports[num_irqs]); | 777 | |
623 | if (err) { | 778 | val = readl(gpio->base + U300_571_CR); |
624 | dev_err(gpiodev, "cannot allocate IRQ for %s!\n", | 779 | dev_info(gpio->dev, "COH901571/3 block version: %d, " \ |
625 | gpio_ports[num_irqs].name); | 780 | "number of cores: %d totalling %d pins\n", |
626 | goto err_no_irq; | 781 | ((val & 0x000001FC) >> 2), |
782 | ((val & 0x0000FE00) >> 9), | ||
783 | ((val & 0x0000FE00) >> 9) * 8); | ||
784 | writel(U300_571_CR_BLOCK_CLKRQ_ENABLE, | ||
785 | gpio->base + U300_571_CR); | ||
786 | u300_gpio_init_coh901571(gpio, plat); | ||
787 | } else { | ||
788 | dev_err(gpio->dev, "unknown block variant\n"); | ||
789 | err = -ENODEV; | ||
790 | goto err_unknown_variant; | ||
791 | } | ||
792 | |||
793 | /* Add each port with its IRQ separately */ | ||
794 | INIT_LIST_HEAD(&gpio->port_list); | ||
795 | for (portno = 0 ; portno < plat->ports; portno++) { | ||
796 | struct u300_gpio_port *port = | ||
797 | kmalloc(sizeof(struct u300_gpio_port), GFP_KERNEL); | ||
798 | |||
799 | if (!port) { | ||
800 | dev_err(gpio->dev, "out of memory\n"); | ||
801 | err = -ENOMEM; | ||
802 | goto err_no_port; | ||
627 | } | 803 | } |
628 | /* Turns off PortX_irq_force */ | 804 | |
629 | writel(0x0, virtbase + U300_GPIO_PXIFR + | 805 | snprintf(port->name, 8, "gpio%d", portno); |
630 | num_irqs * U300_GPIO_PORTX_SPACING); | 806 | port->number = portno; |
807 | port->gpio = gpio; | ||
808 | |||
809 | port->irq = platform_get_irq_byname(pdev, | ||
810 | port->name); | ||
811 | |||
812 | dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, | ||
813 | port->name); | ||
814 | |||
815 | irq_set_chained_handler(port->irq, u300_gpio_irq_handler); | ||
816 | irq_set_handler_data(port->irq, port); | ||
817 | |||
818 | /* For each GPIO pin set the unique IRQ handler */ | ||
819 | for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { | ||
820 | int irqno = gpio->irq_base + (portno << 3) + i; | ||
821 | |||
822 | dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", | ||
823 | irqno, port->name); | ||
824 | irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, | ||
825 | handle_simple_irq); | ||
826 | set_irq_flags(irqno, IRQF_VALID); | ||
827 | irq_set_chip_data(irqno, port); | ||
828 | } | ||
829 | |||
830 | /* Turns off irq force (test register) for this port */ | ||
831 | writel(0x0, gpio->base + portno * gpio->stride + ifr); | ||
832 | |||
833 | list_add_tail(&port->node, &gpio->port_list); | ||
631 | } | 834 | } |
835 | dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno); | ||
836 | |||
837 | err = gpiochip_add(&gpio->chip); | ||
838 | if (err) { | ||
839 | dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); | ||
840 | goto err_no_chip; | ||
841 | } | ||
842 | |||
843 | platform_set_drvdata(pdev, gpio); | ||
632 | 844 | ||
633 | return 0; | 845 | return 0; |
634 | 846 | ||
635 | err_no_irq: | 847 | err_no_chip: |
636 | for (i = 0; i < num_irqs; i++) | 848 | err_no_port: |
637 | free_irq(gpio_ports[i].irq, &gpio_ports[i]); | 849 | u300_gpio_free_ports(gpio); |
638 | iounmap(virtbase); | 850 | err_unknown_variant: |
639 | err_no_ioremap: | 851 | iounmap(gpio->base); |
640 | release_mem_region(memres->start, resource_size(memres)); | 852 | err_no_ioremap: |
641 | err_no_ioregion: | 853 | release_mem_region(gpio->memres->start, resource_size(gpio->memres)); |
642 | err_no_resource: | 854 | err_no_ioregion: |
643 | clk_disable(clk); | 855 | err_no_resource: |
644 | err_no_clk_enable: | 856 | clk_disable(gpio->clk); |
645 | clk_put(clk); | 857 | err_no_clk_enable: |
646 | err_no_clk: | 858 | clk_put(gpio->clk); |
647 | dev_info(gpiodev, "module ERROR:%d\n", err); | 859 | err_no_clk: |
860 | kfree(gpio); | ||
861 | dev_info(&pdev->dev, "module ERROR:%d\n", err); | ||
648 | return err; | 862 | return err; |
649 | } | 863 | } |
650 | 864 | ||
651 | static int __exit gpio_remove(struct platform_device *pdev) | 865 | static int __exit u300_gpio_remove(struct platform_device *pdev) |
652 | { | 866 | { |
653 | int i; | 867 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); |
868 | struct u300_gpio *gpio = platform_get_drvdata(pdev); | ||
869 | int err; | ||
654 | 870 | ||
655 | /* Turn off the GPIO block */ | 871 | /* Turn off the GPIO block */ |
656 | writel(0x00000000U, virtbase + U300_GPIO_CR); | 872 | if (plat->variant == U300_GPIO_COH901335) |
657 | for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++) | 873 | writel(0x00000000U, gpio->base + U300_335_CR); |
658 | free_irq(gpio_ports[i].irq, &gpio_ports[i]); | 874 | if (plat->variant == U300_GPIO_COH901571_3_BS335 || |
659 | iounmap(virtbase); | 875 | plat->variant == U300_GPIO_COH901571_3_BS365) |
660 | release_mem_region(memres->start, resource_size(memres)); | 876 | writel(0x00000000U, gpio->base + U300_571_CR); |
661 | clk_disable(clk); | 877 | |
662 | clk_put(clk); | 878 | err = gpiochip_remove(&gpio->chip); |
879 | if (err < 0) { | ||
880 | dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err); | ||
881 | return err; | ||
882 | } | ||
883 | u300_gpio_free_ports(gpio); | ||
884 | iounmap(gpio->base); | ||
885 | release_mem_region(gpio->memres->start, | ||
886 | resource_size(gpio->memres)); | ||
887 | clk_disable(gpio->clk); | ||
888 | clk_put(gpio->clk); | ||
889 | platform_set_drvdata(pdev, NULL); | ||
890 | kfree(gpio); | ||
663 | return 0; | 891 | return 0; |
664 | } | 892 | } |
665 | 893 | ||
666 | static struct platform_driver gpio_driver = { | 894 | static struct platform_driver u300_gpio_driver = { |
667 | .driver = { | 895 | .driver = { |
668 | .name = "u300-gpio", | 896 | .name = "u300-gpio", |
669 | }, | 897 | }, |
670 | .remove = __exit_p(gpio_remove), | 898 | .remove = __exit_p(u300_gpio_remove), |
671 | }; | 899 | }; |
672 | 900 | ||
673 | 901 | ||
674 | static int __init u300_gpio_init(void) | 902 | static int __init u300_gpio_init(void) |
675 | { | 903 | { |
676 | return platform_driver_probe(&gpio_driver, gpio_probe); | 904 | return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); |
677 | } | 905 | } |
678 | 906 | ||
679 | static void __exit u300_gpio_exit(void) | 907 | static void __exit u300_gpio_exit(void) |
680 | { | 908 | { |
681 | platform_driver_unregister(&gpio_driver); | 909 | platform_driver_unregister(&u300_gpio_driver); |
682 | } | 910 | } |
683 | 911 | ||
684 | arch_initcall(u300_gpio_init); | 912 | arch_initcall(u300_gpio_init); |
685 | module_exit(u300_gpio_exit); | 913 | module_exit(u300_gpio_exit); |
686 | 914 | ||
687 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); | 915 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); |
688 | 916 | MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver"); | |
689 | #ifdef U300_COH901571_3 | ||
690 | MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver"); | ||
691 | #endif | ||
692 | |||
693 | #ifdef U300_COH901335 | ||
694 | MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver"); | ||
695 | #endif | ||
696 | |||
697 | MODULE_LICENSE("GPL"); | 917 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 846fbd5e31bf..0ce6ac9898b1 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/module.h> | ||
17 | #include <linux/of_device.h> | 18 | #include <linux/of_device.h> |
18 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |