blob: 3ad23fb042b44b9b86277b407d68f7800bb99c96 [file] [log] [blame]
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001/*
2 * Generic GPIO driver for logic cells found in the Nomadik SoC
3 *
4 * Copyright (C) 2008,2009 STMicroelectronics
5 * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
6 * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
Linus Walleij33d78642011-06-09 11:08:47 +02007 * Copyright (C) 2011 Linus Walleij <linus.walleij@linaro.org>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/device.h>
Rabin Vincent3e3c62c2010-03-03 04:52:34 +010017#include <linux/platform_device.h>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010018#include <linux/io.h>
Rabin Vincentaf7dc222010-05-06 11:14:17 +010019#include <linux/clk.h>
20#include <linux/err.h>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010021#include <linux/gpio.h>
22#include <linux/spinlock.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
Lee Jonesa60b57e2012-04-19 21:36:31 +010025#include <linux/irqdomain.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090026#include <linux/slab.h>
Lee Jones855f80c2012-05-26 06:09:29 +010027#include <linux/of_device.h>
Linus Walleije98ea772012-04-26 23:57:25 +020028#include <linux/pinctrl/pinctrl.h>
Linus Walleijdbfe8ca2012-05-02 22:56:47 +020029#include <linux/pinctrl/pinmux.h>
Linus Walleijd41af622012-05-03 15:58:12 +020030#include <linux/pinctrl/pinconf.h>
Linus Walleijdbfe8ca2012-05-02 22:56:47 +020031/* Since we request GPIOs from ourself */
32#include <linux/pinctrl/consumer.h>
Linus Walleijb7213702012-10-11 14:33:42 +020033/*
34 * For the U8500 archs, use the PRCMU register interface, for the older
35 * Nomadik, provide some stubs. The functions using these will only be
36 * called on the U8500 series.
37 */
38#ifdef CONFIG_ARCH_U8500
Jean-Nicolas Grauxc22df082012-09-27 15:38:50 +020039#include <linux/mfd/dbx500-prcmu.h>
Linus Walleijb7213702012-10-11 14:33:42 +020040#else
41static inline u32 prcmu_read(unsigned int reg) {
42 return 0;
43}
44static inline void prcmu_write(unsigned int reg, u32 value) {}
45static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
46#endif
Linus Walleij7cb15e12012-10-10 14:27:58 +020047#include <linux/platform_data/pinctrl-nomadik.h>
Will Deaconadfed152011-02-28 10:12:29 +000048#include <asm/mach/irq.h>
Linus Walleijc3b9d1d2012-10-18 11:08:05 +020049#include <mach/irqs.h>
Linus Walleije98ea772012-04-26 23:57:25 +020050#include "pinctrl-nomadik.h"
51
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010052/*
53 * The GPIO module in the Nomadik family of Systems-on-Chip is an
54 * AMBA device, managing 32 pins and alternate functions. The logic block
Jonas Aaberg9c66ee62010-10-13 13:14:17 +020055 * is currently used in the Nomadik and ux500.
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010056 *
57 * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
58 */
59
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010060struct nmk_gpio_chip {
61 struct gpio_chip chip;
Lee Jonesa60b57e2012-04-19 21:36:31 +010062 struct irq_domain *domain;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010063 void __iomem *addr;
Rabin Vincentaf7dc222010-05-06 11:14:17 +010064 struct clk *clk;
Rabin Vincent33b744b2010-10-14 10:38:03 +053065 unsigned int bank;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010066 unsigned int parent_irq;
Virupax Sadashivpetimath2c8bb0e2010-11-11 14:10:38 +053067 int secondary_parent_irq;
Rabin Vincent33b744b2010-10-14 10:38:03 +053068 u32 (*get_secondary_status)(unsigned int bank);
Rabin Vincent01727e62010-12-13 12:02:40 +053069 void (*set_ioforce)(bool enable);
Rabin Vincentc0fcb8d2010-03-03 04:48:54 +010070 spinlock_t lock;
Linus Walleij33d78642011-06-09 11:08:47 +020071 bool sleepmode;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010072 /* Keep track of configured edges */
73 u32 edge_rising;
74 u32 edge_falling;
Rabin Vincentb9df4682011-02-10 11:45:58 +053075 u32 real_wake;
76 u32 rwimsc;
77 u32 fwimsc;
Rabin Vincent6c12fe82011-05-23 12:13:33 +053078 u32 rimsc;
79 u32 fimsc;
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +020080 u32 pull_up;
Rabin Vincentebc61782011-09-28 15:49:11 +053081 u32 lowemi;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010082};
83
Linus Walleije98ea772012-04-26 23:57:25 +020084struct nmk_pinctrl {
85 struct device *dev;
86 struct pinctrl_dev *pctl;
87 const struct nmk_pinctrl_soc_data *soc;
88};
89
Rabin Vincent01727e62010-12-13 12:02:40 +053090static struct nmk_gpio_chip *
91nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
92
93static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
94
95#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
96
Rabin Vincent6f9a9742010-06-02 05:50:28 +010097static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
98 unsigned offset, int gpio_mode)
99{
100 u32 bit = 1 << offset;
101 u32 afunc, bfunc;
102
103 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
104 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
105 if (gpio_mode & NMK_GPIO_ALT_A)
106 afunc |= bit;
107 if (gpio_mode & NMK_GPIO_ALT_B)
108 bfunc |= bit;
109 writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
110 writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
111}
112
Rabin Vincent81a3c292010-05-27 12:39:23 +0100113static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
114 unsigned offset, enum nmk_gpio_slpm mode)
115{
116 u32 bit = 1 << offset;
117 u32 slpm;
118
119 slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
120 if (mode == NMK_GPIO_SLPM_NOCHANGE)
121 slpm |= bit;
122 else
123 slpm &= ~bit;
124 writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
125}
126
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100127static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
128 unsigned offset, enum nmk_gpio_pull pull)
129{
130 u32 bit = 1 << offset;
131 u32 pdis;
132
133 pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +0200134 if (pull == NMK_GPIO_PULL_NONE) {
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100135 pdis |= bit;
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +0200136 nmk_chip->pull_up &= ~bit;
137 } else {
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100138 pdis &= ~bit;
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +0200139 }
140
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100141 writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
142
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +0200143 if (pull == NMK_GPIO_PULL_UP) {
144 nmk_chip->pull_up |= bit;
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100145 writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +0200146 } else if (pull == NMK_GPIO_PULL_DOWN) {
147 nmk_chip->pull_up &= ~bit;
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100148 writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +0200149 }
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100150}
151
Rabin Vincentebc61782011-09-28 15:49:11 +0530152static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
153 unsigned offset, bool lowemi)
154{
155 u32 bit = BIT(offset);
156 bool enabled = nmk_chip->lowemi & bit;
157
158 if (lowemi == enabled)
159 return;
160
161 if (lowemi)
162 nmk_chip->lowemi |= bit;
163 else
164 nmk_chip->lowemi &= ~bit;
165
166 writel_relaxed(nmk_chip->lowemi,
167 nmk_chip->addr + NMK_GPIO_LOWEMI);
168}
169
Rabin Vincent378be062010-06-02 06:06:29 +0100170static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
171 unsigned offset)
172{
173 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
174}
175
Rabin Vincent6720db72010-09-02 11:28:48 +0100176static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
177 unsigned offset, int val)
178{
179 if (val)
180 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
181 else
182 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
183}
184
185static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
186 unsigned offset, int val)
187{
188 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
189 __nmk_gpio_set_output(nmk_chip, offset, val);
190}
191
Rabin Vincent01727e62010-12-13 12:02:40 +0530192static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
193 unsigned offset, int gpio_mode,
194 bool glitch)
195{
Rabin Vincent6c12fe82011-05-23 12:13:33 +0530196 u32 rwimsc = nmk_chip->rwimsc;
197 u32 fwimsc = nmk_chip->fwimsc;
Rabin Vincent01727e62010-12-13 12:02:40 +0530198
199 if (glitch && nmk_chip->set_ioforce) {
200 u32 bit = BIT(offset);
201
Rabin Vincent01727e62010-12-13 12:02:40 +0530202 /* Prevent spurious wakeups */
203 writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
204 writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
205
206 nmk_chip->set_ioforce(true);
207 }
208
209 __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
210
211 if (glitch && nmk_chip->set_ioforce) {
212 nmk_chip->set_ioforce(false);
213
214 writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
215 writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
216 }
217}
218
Rabin Vincent6c42ad12011-05-23 12:22:18 +0530219static void
220nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
221{
222 u32 falling = nmk_chip->fimsc & BIT(offset);
223 u32 rising = nmk_chip->rimsc & BIT(offset);
224 int gpio = nmk_chip->chip.base + offset;
225 int irq = NOMADIK_GPIO_TO_IRQ(gpio);
226 struct irq_data *d = irq_get_irq_data(irq);
227
228 if (!rising && !falling)
229 return;
230
231 if (!d || !irqd_irq_disabled(d))
232 return;
233
234 if (rising) {
235 nmk_chip->rimsc &= ~BIT(offset);
236 writel_relaxed(nmk_chip->rimsc,
237 nmk_chip->addr + NMK_GPIO_RIMSC);
238 }
239
240 if (falling) {
241 nmk_chip->fimsc &= ~BIT(offset);
242 writel_relaxed(nmk_chip->fimsc,
243 nmk_chip->addr + NMK_GPIO_FIMSC);
244 }
245
246 dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
247}
248
Jean-Nicolas Grauxc22df082012-09-27 15:38:50 +0200249static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
250 unsigned offset, unsigned alt_num)
251{
252 int i;
253 u16 reg;
254 u8 bit;
255 u8 alt_index;
256 const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
257 const u16 *gpiocr_regs;
258
259 if (alt_num > PRCM_IDX_GPIOCR_ALTC_MAX) {
260 dev_err(npct->dev, "PRCM GPIOCR: alternate-C%i is invalid\n",
261 alt_num);
262 return;
263 }
264
265 for (i = 0 ; i < npct->soc->npins_altcx ; i++) {
266 if (npct->soc->altcx_pins[i].pin == offset)
267 break;
268 }
269 if (i == npct->soc->npins_altcx) {
270 dev_dbg(npct->dev, "PRCM GPIOCR: pin %i is not found\n",
271 offset);
272 return;
273 }
274
275 pin_desc = npct->soc->altcx_pins + i;
276 gpiocr_regs = npct->soc->prcm_gpiocr_registers;
277
278 /*
279 * If alt_num is NULL, just clear current ALTCx selection
280 * to make sure we come back to a pure ALTC selection
281 */
282 if (!alt_num) {
283 for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
284 if (pin_desc->altcx[i].used == true) {
285 reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
286 bit = pin_desc->altcx[i].control_bit;
287 if (prcmu_read(reg) & BIT(bit)) {
288 prcmu_write_masked(reg, BIT(bit), 0);
289 dev_dbg(npct->dev,
290 "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
291 offset, i+1);
292 }
293 }
294 }
295 return;
296 }
297
298 alt_index = alt_num - 1;
299 if (pin_desc->altcx[alt_index].used == false) {
300 dev_warn(npct->dev,
301 "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
302 offset, alt_num);
303 return;
304 }
305
306 /*
307 * Check if any other ALTCx functions are activated on this pin
308 * and disable it first.
309 */
310 for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
311 if (i == alt_index)
312 continue;
313 if (pin_desc->altcx[i].used == true) {
314 reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
315 bit = pin_desc->altcx[i].control_bit;
316 if (prcmu_read(reg) & BIT(bit)) {
317 prcmu_write_masked(reg, BIT(bit), 0);
318 dev_dbg(npct->dev,
319 "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
320 offset, i+1);
321 }
322 }
323 }
324
325 reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index];
326 bit = pin_desc->altcx[alt_index].control_bit;
327 dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
328 offset, alt_index+1);
329 prcmu_write_masked(reg, BIT(bit), BIT(bit));
330}
331
Rabin Vincent378be062010-06-02 06:06:29 +0100332static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
Rabin Vincent01727e62010-12-13 12:02:40 +0530333 pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
Rabin Vincent378be062010-06-02 06:06:29 +0100334{
335 static const char *afnames[] = {
336 [NMK_GPIO_ALT_GPIO] = "GPIO",
337 [NMK_GPIO_ALT_A] = "A",
338 [NMK_GPIO_ALT_B] = "B",
339 [NMK_GPIO_ALT_C] = "C"
340 };
341 static const char *pullnames[] = {
342 [NMK_GPIO_PULL_NONE] = "none",
343 [NMK_GPIO_PULL_UP] = "up",
344 [NMK_GPIO_PULL_DOWN] = "down",
345 [3] /* illegal */ = "??"
346 };
347 static const char *slpmnames[] = {
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100348 [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
349 [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
Rabin Vincent378be062010-06-02 06:06:29 +0100350 };
351
352 int pin = PIN_NUM(cfg);
353 int pull = PIN_PULL(cfg);
354 int af = PIN_ALT(cfg);
355 int slpm = PIN_SLPM(cfg);
Rabin Vincent6720db72010-09-02 11:28:48 +0100356 int output = PIN_DIR(cfg);
357 int val = PIN_VAL(cfg);
Rabin Vincent01727e62010-12-13 12:02:40 +0530358 bool glitch = af == NMK_GPIO_ALT_C;
Rabin Vincent378be062010-06-02 06:06:29 +0100359
Rabin Vincentdacdc962010-12-03 20:35:37 +0530360 dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
361 pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
Rabin Vincent6720db72010-09-02 11:28:48 +0100362 output ? "output " : "input",
363 output ? (val ? "high" : "low") : "");
Rabin Vincent378be062010-06-02 06:06:29 +0100364
Rabin Vincentdacdc962010-12-03 20:35:37 +0530365 if (sleep) {
366 int slpm_pull = PIN_SLPM_PULL(cfg);
367 int slpm_output = PIN_SLPM_DIR(cfg);
368 int slpm_val = PIN_SLPM_VAL(cfg);
369
Rabin Vincent3546d152010-11-25 11:38:27 +0530370 af = NMK_GPIO_ALT_GPIO;
371
Rabin Vincentdacdc962010-12-03 20:35:37 +0530372 /*
373 * The SLPM_* values are normal values + 1 to allow zero to
374 * mean "same as normal".
375 */
376 if (slpm_pull)
377 pull = slpm_pull - 1;
378 if (slpm_output)
379 output = slpm_output - 1;
380 if (slpm_val)
381 val = slpm_val - 1;
382
383 dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
384 pin,
385 slpm_pull ? pullnames[pull] : "same",
386 slpm_output ? (output ? "output" : "input") : "same",
387 slpm_val ? (val ? "high" : "low") : "same");
388 }
389
Rabin Vincent6720db72010-09-02 11:28:48 +0100390 if (output)
391 __nmk_gpio_make_output(nmk_chip, offset, val);
392 else {
393 __nmk_gpio_make_input(nmk_chip, offset);
394 __nmk_gpio_set_pull(nmk_chip, offset, pull);
395 }
396
Rabin Vincentebc61782011-09-28 15:49:11 +0530397 __nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg));
398
Rabin Vincent01727e62010-12-13 12:02:40 +0530399 /*
Rabin Vincent6c42ad12011-05-23 12:22:18 +0530400 * If the pin is switching to altfunc, and there was an interrupt
401 * installed on it which has been lazy disabled, actually mask the
402 * interrupt to prevent spurious interrupts that would occur while the
403 * pin is under control of the peripheral. Only SKE does this.
404 */
405 if (af != NMK_GPIO_ALT_GPIO)
406 nmk_gpio_disable_lazy_irq(nmk_chip, offset);
407
408 /*
Rabin Vincent01727e62010-12-13 12:02:40 +0530409 * If we've backed up the SLPM registers (glitch workaround), modify
410 * the backups since they will be restored.
411 */
412 if (slpmregs) {
413 if (slpm == NMK_GPIO_SLPM_NOCHANGE)
414 slpmregs[nmk_chip->bank] |= BIT(offset);
415 else
416 slpmregs[nmk_chip->bank] &= ~BIT(offset);
417 } else
418 __nmk_gpio_set_slpm(nmk_chip, offset, slpm);
419
420 __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
421}
422
423/*
424 * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
425 * - Save SLPM registers
426 * - Set SLPM=0 for the IOs you want to switch and others to 1
427 * - Configure the GPIO registers for the IOs that are being switched
428 * - Set IOFORCE=1
429 * - Modify the AFLSA/B registers for the IOs that are being switched
430 * - Set IOFORCE=0
431 * - Restore SLPM registers
432 * - Any spurious wake up event during switch sequence to be ignored and
433 * cleared
434 */
435static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
436{
437 int i;
438
439 for (i = 0; i < NUM_BANKS; i++) {
440 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
441 unsigned int temp = slpm[i];
442
443 if (!chip)
444 break;
445
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200446 clk_enable(chip->clk);
447
Rabin Vincent01727e62010-12-13 12:02:40 +0530448 slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
449 writel(temp, chip->addr + NMK_GPIO_SLPC);
450 }
451}
452
453static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
454{
455 int i;
456
457 for (i = 0; i < NUM_BANKS; i++) {
458 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
459
460 if (!chip)
461 break;
462
463 writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200464
465 clk_disable(chip->clk);
Rabin Vincent01727e62010-12-13 12:02:40 +0530466 }
467}
468
469static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
470{
471 static unsigned int slpm[NUM_BANKS];
472 unsigned long flags;
473 bool glitch = false;
474 int ret = 0;
475 int i;
476
477 for (i = 0; i < num; i++) {
478 if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) {
479 glitch = true;
480 break;
481 }
482 }
483
484 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
485
486 if (glitch) {
487 memset(slpm, 0xff, sizeof(slpm));
488
489 for (i = 0; i < num; i++) {
490 int pin = PIN_NUM(cfgs[i]);
491 int offset = pin % NMK_GPIO_PER_CHIP;
492
493 if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C)
494 slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset);
495 }
496
497 nmk_gpio_glitch_slpm_init(slpm);
498 }
499
500 for (i = 0; i < num; i++) {
501 struct nmk_gpio_chip *nmk_chip;
502 int pin = PIN_NUM(cfgs[i]);
503
Lee Jonesa60b57e2012-04-19 21:36:31 +0100504 nmk_chip = nmk_gpio_chips[pin / NMK_GPIO_PER_CHIP];
Rabin Vincent01727e62010-12-13 12:02:40 +0530505 if (!nmk_chip) {
506 ret = -EINVAL;
507 break;
508 }
509
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200510 clk_enable(nmk_chip->clk);
Rabin Vincent01727e62010-12-13 12:02:40 +0530511 spin_lock(&nmk_chip->lock);
Lee Jonesa60b57e2012-04-19 21:36:31 +0100512 __nmk_config_pin(nmk_chip, pin % NMK_GPIO_PER_CHIP,
Rabin Vincent01727e62010-12-13 12:02:40 +0530513 cfgs[i], sleep, glitch ? slpm : NULL);
514 spin_unlock(&nmk_chip->lock);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200515 clk_disable(nmk_chip->clk);
Rabin Vincent01727e62010-12-13 12:02:40 +0530516 }
517
518 if (glitch)
519 nmk_gpio_glitch_slpm_restore(slpm);
520
521 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
522
523 return ret;
Rabin Vincent378be062010-06-02 06:06:29 +0100524}
525
526/**
527 * nmk_config_pin - configure a pin's mux attributes
528 * @cfg: pin confguration
Linus Walleij50bcd472012-07-04 11:25:36 +0200529 * @sleep: Non-zero to apply the sleep mode configuration
Rabin Vincent378be062010-06-02 06:06:29 +0100530 * Configures a pin's mode (alternate function or GPIO), its pull up status,
531 * and its sleep mode based on the specified configuration. The @cfg is
532 * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These
533 * are constructed using, and can be further enhanced with, the macros in
Linus Walleijc3123cf2012-10-10 14:35:17 +0200534 * <linux/platform_data/pinctrl-nomadik.h>
Rabin Vincent378be062010-06-02 06:06:29 +0100535 *
536 * If a pin's mode is set to GPIO, it is configured as an input to avoid
537 * side-effects. The gpio can be manipulated later using standard GPIO API
538 * calls.
539 */
Rabin Vincentdacdc962010-12-03 20:35:37 +0530540int nmk_config_pin(pin_cfg_t cfg, bool sleep)
Rabin Vincent378be062010-06-02 06:06:29 +0100541{
Rabin Vincent01727e62010-12-13 12:02:40 +0530542 return __nmk_config_pins(&cfg, 1, sleep);
Rabin Vincent378be062010-06-02 06:06:29 +0100543}
544EXPORT_SYMBOL(nmk_config_pin);
545
546/**
547 * nmk_config_pins - configure several pins at once
548 * @cfgs: array of pin configurations
549 * @num: number of elments in the array
550 *
551 * Configures several pins using nmk_config_pin(). Refer to that function for
552 * further information.
553 */
554int nmk_config_pins(pin_cfg_t *cfgs, int num)
555{
Rabin Vincent01727e62010-12-13 12:02:40 +0530556 return __nmk_config_pins(cfgs, num, false);
Rabin Vincent378be062010-06-02 06:06:29 +0100557}
558EXPORT_SYMBOL(nmk_config_pins);
559
Rabin Vincentdacdc962010-12-03 20:35:37 +0530560int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
561{
Rabin Vincent01727e62010-12-13 12:02:40 +0530562 return __nmk_config_pins(cfgs, num, true);
Rabin Vincentdacdc962010-12-03 20:35:37 +0530563}
564EXPORT_SYMBOL(nmk_config_pins_sleep);
565
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100566/**
Rabin Vincent81a3c292010-05-27 12:39:23 +0100567 * nmk_gpio_set_slpm() - configure the sleep mode of a pin
568 * @gpio: pin number
569 * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
570 *
Linus Walleij33d78642011-06-09 11:08:47 +0200571 * This register is actually in the pinmux layer, not the GPIO block itself.
572 * The GPIO1B_SLPM register defines the GPIO mode when SLEEP/DEEP-SLEEP
573 * mode is entered (i.e. when signal IOFORCE is HIGH by the platform code).
574 * Each GPIO can be configured to be forced into GPIO mode when IOFORCE is
575 * HIGH, overriding the normal setting defined by GPIO_AFSELx registers.
576 * When IOFORCE returns LOW (by software, after SLEEP/DEEP-SLEEP exit),
577 * the GPIOs return to the normal setting defined by GPIO_AFSELx registers.
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100578 *
Linus Walleij33d78642011-06-09 11:08:47 +0200579 * If @mode is NMK_GPIO_SLPM_INPUT, the corresponding GPIO is switched to GPIO
580 * mode when signal IOFORCE is HIGH (i.e. when SLEEP/DEEP-SLEEP mode is
581 * entered) regardless of the altfunction selected. Also wake-up detection is
582 * ENABLED.
583 *
584 * If @mode is NMK_GPIO_SLPM_NOCHANGE, the corresponding GPIO remains
585 * controlled by NMK_GPIO_DATC, NMK_GPIO_DATS, NMK_GPIO_DIR, NMK_GPIO_PDIS
586 * (for altfunction GPIO) or respective on-chip peripherals (for other
587 * altfuncs) when IOFORCE is HIGH. Also wake-up detection DISABLED.
588 *
589 * Note that enable_irq_wake() will automatically enable wakeup detection.
Rabin Vincent81a3c292010-05-27 12:39:23 +0100590 */
591int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
592{
593 struct nmk_gpio_chip *nmk_chip;
594 unsigned long flags;
595
Lee Jonesa60b57e2012-04-19 21:36:31 +0100596 nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
Rabin Vincent81a3c292010-05-27 12:39:23 +0100597 if (!nmk_chip)
598 return -EINVAL;
599
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200600 clk_enable(nmk_chip->clk);
Rabin Vincent01727e62010-12-13 12:02:40 +0530601 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
602 spin_lock(&nmk_chip->lock);
603
Lee Jonesa60b57e2012-04-19 21:36:31 +0100604 __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP, mode);
Rabin Vincent01727e62010-12-13 12:02:40 +0530605
606 spin_unlock(&nmk_chip->lock);
607 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200608 clk_disable(nmk_chip->clk);
Rabin Vincent81a3c292010-05-27 12:39:23 +0100609
610 return 0;
611}
612
613/**
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100614 * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
615 * @gpio: pin number
616 * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
617 *
618 * Enables/disables pull up/down on a specified pin. This only takes effect if
619 * the pin is configured as an input (either explicitly or by the alternate
620 * function).
621 *
622 * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
623 * configured as an input. Otherwise, due to the way the controller registers
624 * work, this function will change the value output on the pin.
625 */
626int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
627{
628 struct nmk_gpio_chip *nmk_chip;
629 unsigned long flags;
630
Lee Jonesa60b57e2012-04-19 21:36:31 +0100631 nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100632 if (!nmk_chip)
633 return -EINVAL;
634
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200635 clk_enable(nmk_chip->clk);
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100636 spin_lock_irqsave(&nmk_chip->lock, flags);
Lee Jonesa60b57e2012-04-19 21:36:31 +0100637 __nmk_gpio_set_pull(nmk_chip, gpio % NMK_GPIO_PER_CHIP, pull);
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100638 spin_unlock_irqrestore(&nmk_chip->lock, flags);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200639 clk_disable(nmk_chip->clk);
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100640
641 return 0;
642}
643
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100644/* Mode functions */
Jonas Aaberg9c66ee62010-10-13 13:14:17 +0200645/**
646 * nmk_gpio_set_mode() - set the mux mode of a gpio pin
647 * @gpio: pin number
648 * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A,
649 * NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C
650 *
651 * Sets the mode of the specified pin to one of the alternate functions or
652 * plain GPIO.
653 */
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100654int nmk_gpio_set_mode(int gpio, int gpio_mode)
655{
656 struct nmk_gpio_chip *nmk_chip;
657 unsigned long flags;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100658
Lee Jonesa60b57e2012-04-19 21:36:31 +0100659 nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100660 if (!nmk_chip)
661 return -EINVAL;
662
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200663 clk_enable(nmk_chip->clk);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100664 spin_lock_irqsave(&nmk_chip->lock, flags);
Lee Jonesa60b57e2012-04-19 21:36:31 +0100665 __nmk_gpio_set_mode(nmk_chip, gpio % NMK_GPIO_PER_CHIP, gpio_mode);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100666 spin_unlock_irqrestore(&nmk_chip->lock, flags);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200667 clk_disable(nmk_chip->clk);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100668
669 return 0;
670}
671EXPORT_SYMBOL(nmk_gpio_set_mode);
672
673int nmk_gpio_get_mode(int gpio)
674{
675 struct nmk_gpio_chip *nmk_chip;
676 u32 afunc, bfunc, bit;
677
Lee Jonesa60b57e2012-04-19 21:36:31 +0100678 nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100679 if (!nmk_chip)
680 return -EINVAL;
681
Lee Jonesa60b57e2012-04-19 21:36:31 +0100682 bit = 1 << (gpio % NMK_GPIO_PER_CHIP);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100683
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200684 clk_enable(nmk_chip->clk);
685
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100686 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
687 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
688
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200689 clk_disable(nmk_chip->clk);
690
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100691 return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
692}
693EXPORT_SYMBOL(nmk_gpio_get_mode);
694
695
696/* IRQ functions */
697static inline int nmk_gpio_get_bitmask(int gpio)
698{
Lee Jonesa60b57e2012-04-19 21:36:31 +0100699 return 1 << (gpio % NMK_GPIO_PER_CHIP);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100700}
701
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100702static void nmk_gpio_irq_ack(struct irq_data *d)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100703{
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100704 struct nmk_gpio_chip *nmk_chip;
705
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100706 nmk_chip = irq_data_get_irq_chip_data(d);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100707 if (!nmk_chip)
708 return;
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200709
710 clk_enable(nmk_chip->clk);
Lee Jonesa60b57e2012-04-19 21:36:31 +0100711 writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200712 clk_disable(nmk_chip->clk);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100713}
714
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100715enum nmk_gpio_irq_type {
716 NORMAL,
717 WAKE,
718};
719
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100720static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100721 int gpio, enum nmk_gpio_irq_type which,
722 bool enable)
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100723{
724 u32 bitmask = nmk_gpio_get_bitmask(gpio);
Rabin Vincent6c12fe82011-05-23 12:13:33 +0530725 u32 *rimscval;
726 u32 *fimscval;
727 u32 rimscreg;
728 u32 fimscreg;
729
730 if (which == NORMAL) {
731 rimscreg = NMK_GPIO_RIMSC;
732 fimscreg = NMK_GPIO_FIMSC;
733 rimscval = &nmk_chip->rimsc;
734 fimscval = &nmk_chip->fimsc;
735 } else {
736 rimscreg = NMK_GPIO_RWIMSC;
737 fimscreg = NMK_GPIO_FWIMSC;
738 rimscval = &nmk_chip->rwimsc;
739 fimscval = &nmk_chip->fwimsc;
740 }
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100741
742 /* we must individually set/clear the two edges */
743 if (nmk_chip->edge_rising & bitmask) {
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100744 if (enable)
Rabin Vincent6c12fe82011-05-23 12:13:33 +0530745 *rimscval |= bitmask;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100746 else
Rabin Vincent6c12fe82011-05-23 12:13:33 +0530747 *rimscval &= ~bitmask;
748 writel(*rimscval, nmk_chip->addr + rimscreg);
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100749 }
750 if (nmk_chip->edge_falling & bitmask) {
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100751 if (enable)
Rabin Vincent6c12fe82011-05-23 12:13:33 +0530752 *fimscval |= bitmask;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100753 else
Rabin Vincent6c12fe82011-05-23 12:13:33 +0530754 *fimscval &= ~bitmask;
755 writel(*fimscval, nmk_chip->addr + fimscreg);
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100756 }
757}
758
Rabin Vincentb9df4682011-02-10 11:45:58 +0530759static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
760 int gpio, bool on)
761{
Rabin Vincentb982ff02011-04-26 09:03:27 +0530762 /*
763 * Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is
764 * disabled, since setting SLPM to 1 increases power consumption, and
765 * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
766 */
767 if (nmk_chip->sleepmode && on) {
Linus Walleije85bbc12012-06-12 12:43:06 +0200768 __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP,
Rabin Vincentb982ff02011-04-26 09:03:27 +0530769 NMK_GPIO_SLPM_WAKEUP_ENABLE);
Linus Walleij33d78642011-06-09 11:08:47 +0200770 }
771
Rabin Vincentb9df4682011-02-10 11:45:58 +0530772 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
773}
774
775static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100776{
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100777 struct nmk_gpio_chip *nmk_chip;
778 unsigned long flags;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100779 u32 bitmask;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100780
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100781 nmk_chip = irq_data_get_irq_chip_data(d);
Lee Jonesa60b57e2012-04-19 21:36:31 +0100782 bitmask = nmk_gpio_get_bitmask(d->hwirq);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100783 if (!nmk_chip)
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100784 return -EINVAL;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100785
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200786 clk_enable(nmk_chip->clk);
Rabin Vincentb9df4682011-02-10 11:45:58 +0530787 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
788 spin_lock(&nmk_chip->lock);
789
Lee Jonesa60b57e2012-04-19 21:36:31 +0100790 __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
Rabin Vincentb9df4682011-02-10 11:45:58 +0530791
792 if (!(nmk_chip->real_wake & bitmask))
Lee Jonesa60b57e2012-04-19 21:36:31 +0100793 __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
Rabin Vincentb9df4682011-02-10 11:45:58 +0530794
795 spin_unlock(&nmk_chip->lock);
796 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200797 clk_disable(nmk_chip->clk);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100798
799 return 0;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100800}
801
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100802static void nmk_gpio_irq_mask(struct irq_data *d)
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100803{
Rabin Vincentb9df4682011-02-10 11:45:58 +0530804 nmk_gpio_irq_maskunmask(d, false);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100805}
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100806
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100807static void nmk_gpio_irq_unmask(struct irq_data *d)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100808{
Rabin Vincentb9df4682011-02-10 11:45:58 +0530809 nmk_gpio_irq_maskunmask(d, true);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100810}
811
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100812static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100813{
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100814 struct nmk_gpio_chip *nmk_chip;
815 unsigned long flags;
Rabin Vincentb9df4682011-02-10 11:45:58 +0530816 u32 bitmask;
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100817
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100818 nmk_chip = irq_data_get_irq_chip_data(d);
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100819 if (!nmk_chip)
820 return -EINVAL;
Lee Jonesa60b57e2012-04-19 21:36:31 +0100821 bitmask = nmk_gpio_get_bitmask(d->hwirq);
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100822
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200823 clk_enable(nmk_chip->clk);
Rabin Vincent01727e62010-12-13 12:02:40 +0530824 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
825 spin_lock(&nmk_chip->lock);
826
Linus Walleij479a0c72011-09-20 10:50:15 +0200827 if (irqd_irq_disabled(d))
Lee Jonesa60b57e2012-04-19 21:36:31 +0100828 __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
Rabin Vincentb9df4682011-02-10 11:45:58 +0530829
830 if (on)
831 nmk_chip->real_wake |= bitmask;
832 else
833 nmk_chip->real_wake &= ~bitmask;
Rabin Vincent01727e62010-12-13 12:02:40 +0530834
835 spin_unlock(&nmk_chip->lock);
836 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200837 clk_disable(nmk_chip->clk);
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100838
839 return 0;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100840}
841
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100842static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100843{
Linus Walleij479a0c72011-09-20 10:50:15 +0200844 bool enabled = !irqd_irq_disabled(d);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200845 bool wake = irqd_is_wakeup_set(d);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100846 struct nmk_gpio_chip *nmk_chip;
847 unsigned long flags;
848 u32 bitmask;
849
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100850 nmk_chip = irq_data_get_irq_chip_data(d);
Lee Jonesa60b57e2012-04-19 21:36:31 +0100851 bitmask = nmk_gpio_get_bitmask(d->hwirq);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100852 if (!nmk_chip)
853 return -EINVAL;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100854 if (type & IRQ_TYPE_LEVEL_HIGH)
855 return -EINVAL;
856 if (type & IRQ_TYPE_LEVEL_LOW)
857 return -EINVAL;
858
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200859 clk_enable(nmk_chip->clk);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100860 spin_lock_irqsave(&nmk_chip->lock, flags);
861
Rabin Vincent7a852d82010-05-06 10:43:55 +0100862 if (enabled)
Lee Jonesa60b57e2012-04-19 21:36:31 +0100863 __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100864
Rabin Vincentb9df4682011-02-10 11:45:58 +0530865 if (enabled || wake)
Lee Jonesa60b57e2012-04-19 21:36:31 +0100866 __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
Rabin Vincent7a852d82010-05-06 10:43:55 +0100867
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100868 nmk_chip->edge_rising &= ~bitmask;
869 if (type & IRQ_TYPE_EDGE_RISING)
870 nmk_chip->edge_rising |= bitmask;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100871
872 nmk_chip->edge_falling &= ~bitmask;
873 if (type & IRQ_TYPE_EDGE_FALLING)
874 nmk_chip->edge_falling |= bitmask;
Rabin Vincent7a852d82010-05-06 10:43:55 +0100875
876 if (enabled)
Lee Jonesa60b57e2012-04-19 21:36:31 +0100877 __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100878
Rabin Vincentb9df4682011-02-10 11:45:58 +0530879 if (enabled || wake)
Lee Jonesa60b57e2012-04-19 21:36:31 +0100880 __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100881
882 spin_unlock_irqrestore(&nmk_chip->lock, flags);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200883 clk_disable(nmk_chip->clk);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100884
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100885 return 0;
886}
887
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200888static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
889{
890 struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
891
892 clk_enable(nmk_chip->clk);
893 nmk_gpio_irq_unmask(d);
894 return 0;
895}
896
897static void nmk_gpio_irq_shutdown(struct irq_data *d)
898{
899 struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
900
901 nmk_gpio_irq_mask(d);
902 clk_disable(nmk_chip->clk);
903}
904
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100905static struct irq_chip nmk_gpio_irq_chip = {
906 .name = "Nomadik-GPIO",
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100907 .irq_ack = nmk_gpio_irq_ack,
908 .irq_mask = nmk_gpio_irq_mask,
909 .irq_unmask = nmk_gpio_irq_unmask,
910 .irq_set_type = nmk_gpio_irq_set_type,
911 .irq_set_wake = nmk_gpio_irq_set_wake,
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200912 .irq_startup = nmk_gpio_irq_startup,
913 .irq_shutdown = nmk_gpio_irq_shutdown,
Etienne Carriere4921e7452012-08-22 10:44:16 +0200914 .flags = IRQCHIP_MASK_ON_SUSPEND,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100915};
916
Rabin Vincent33b744b2010-10-14 10:38:03 +0530917static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
918 u32 status)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100919{
920 struct nmk_gpio_chip *nmk_chip;
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100921 struct irq_chip *host_chip = irq_get_chip(irq);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100922
Will Deaconadfed152011-02-28 10:12:29 +0000923 chained_irq_enter(host_chip, desc);
Rabin Vincentaaedaa22010-03-03 04:50:27 +0100924
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100925 nmk_chip = irq_get_handler_data(irq);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530926 while (status) {
927 int bit = __ffs(status);
928
Linus Walleij95f0bc92012-09-27 14:14:09 +0200929 generic_handle_irq(irq_find_mapping(nmk_chip->domain, bit));
Rabin Vincent33b744b2010-10-14 10:38:03 +0530930 status &= ~BIT(bit);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100931 }
Rabin Vincentaaedaa22010-03-03 04:50:27 +0100932
Will Deaconadfed152011-02-28 10:12:29 +0000933 chained_irq_exit(host_chip, desc);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100934}
935
Rabin Vincent33b744b2010-10-14 10:38:03 +0530936static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
937{
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100938 struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200939 u32 status;
940
941 clk_enable(nmk_chip->clk);
942 status = readl(nmk_chip->addr + NMK_GPIO_IS);
943 clk_disable(nmk_chip->clk);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530944
945 __nmk_gpio_irq_handler(irq, desc, status);
946}
947
948static void nmk_gpio_secondary_irq_handler(unsigned int irq,
949 struct irq_desc *desc)
950{
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100951 struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530952 u32 status = nmk_chip->get_secondary_status(nmk_chip->bank);
953
954 __nmk_gpio_irq_handler(irq, desc, status);
955}
956
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100957static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
958{
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100959 irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
960 irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530961
962 if (nmk_chip->secondary_parent_irq >= 0) {
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100963 irq_set_chained_handler(nmk_chip->secondary_parent_irq,
Rabin Vincent33b744b2010-10-14 10:38:03 +0530964 nmk_gpio_secondary_irq_handler);
Thomas Gleixner6845664a2011-03-24 13:25:22 +0100965 irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530966 }
967
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100968 return 0;
969}
970
971/* I/O Functions */
Linus Walleijdbfe8ca2012-05-02 22:56:47 +0200972
973static int nmk_gpio_request(struct gpio_chip *chip, unsigned offset)
974{
975 /*
976 * Map back to global GPIO space and request muxing, the direction
977 * parameter does not matter for this controller.
978 */
979 int gpio = chip->base + offset;
980
981 return pinctrl_request_gpio(gpio);
982}
983
984static void nmk_gpio_free(struct gpio_chip *chip, unsigned offset)
985{
986 int gpio = chip->base + offset;
987
988 pinctrl_free_gpio(gpio);
989}
990
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100991static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
992{
993 struct nmk_gpio_chip *nmk_chip =
994 container_of(chip, struct nmk_gpio_chip, chip);
995
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200996 clk_enable(nmk_chip->clk);
997
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100998 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
Rabin Vincent3c0227d2011-09-20 10:50:03 +0200999
1000 clk_disable(nmk_chip->clk);
1001
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001002 return 0;
1003}
1004
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001005static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
1006{
1007 struct nmk_gpio_chip *nmk_chip =
1008 container_of(chip, struct nmk_gpio_chip, chip);
1009 u32 bit = 1 << offset;
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001010 int value;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001011
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001012 clk_enable(nmk_chip->clk);
1013
1014 value = (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
1015
1016 clk_disable(nmk_chip->clk);
1017
1018 return value;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001019}
1020
1021static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
1022 int val)
1023{
1024 struct nmk_gpio_chip *nmk_chip =
1025 container_of(chip, struct nmk_gpio_chip, chip);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001026
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001027 clk_enable(nmk_chip->clk);
1028
Rabin Vincent6720db72010-09-02 11:28:48 +01001029 __nmk_gpio_set_output(nmk_chip, offset, val);
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001030
1031 clk_disable(nmk_chip->clk);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001032}
1033
Rabin Vincent6647c6c2010-05-27 12:22:42 +01001034static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
1035 int val)
1036{
1037 struct nmk_gpio_chip *nmk_chip =
1038 container_of(chip, struct nmk_gpio_chip, chip);
1039
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001040 clk_enable(nmk_chip->clk);
1041
Rabin Vincent6720db72010-09-02 11:28:48 +01001042 __nmk_gpio_make_output(nmk_chip, offset, val);
Rabin Vincent6647c6c2010-05-27 12:22:42 +01001043
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001044 clk_disable(nmk_chip->clk);
1045
Rabin Vincent6647c6c2010-05-27 12:22:42 +01001046 return 0;
1047}
1048
Rabin Vincent0d2aec92010-06-16 06:10:43 +01001049static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
1050{
1051 struct nmk_gpio_chip *nmk_chip =
1052 container_of(chip, struct nmk_gpio_chip, chip);
1053
Linus Walleij268300b2012-10-19 17:06:54 +02001054 return irq_create_mapping(nmk_chip->domain, offset);
Rabin Vincent0d2aec92010-06-16 06:10:43 +01001055}
1056
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301057#ifdef CONFIG_DEBUG_FS
1058
1059#include <linux/seq_file.h>
1060
Linus Walleij6f4350a2012-05-02 21:06:13 +02001061static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip,
1062 unsigned offset, unsigned gpio)
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301063{
Linus Walleij6f4350a2012-05-02 21:06:13 +02001064 const char *label = gpiochip_is_requested(chip, offset);
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301065 struct nmk_gpio_chip *nmk_chip =
1066 container_of(chip, struct nmk_gpio_chip, chip);
Linus Walleij6f4350a2012-05-02 21:06:13 +02001067 int mode;
1068 bool is_out;
1069 bool pull;
1070 u32 bit = 1 << offset;
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301071 const char *modes[] = {
1072 [NMK_GPIO_ALT_GPIO] = "gpio",
1073 [NMK_GPIO_ALT_A] = "altA",
1074 [NMK_GPIO_ALT_B] = "altB",
1075 [NMK_GPIO_ALT_C] = "altC",
1076 };
1077
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001078 clk_enable(nmk_chip->clk);
Linus Walleij6f4350a2012-05-02 21:06:13 +02001079 is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit);
1080 pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
1081 mode = nmk_gpio_get_mode(gpio);
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001082
Linus Walleij6f4350a2012-05-02 21:06:13 +02001083 seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
1084 gpio, label ?: "(none)",
1085 is_out ? "out" : "in ",
1086 chip->get
1087 ? (chip->get(chip, offset) ? "hi" : "lo")
1088 : "? ",
1089 (mode < 0) ? "unknown" : modes[mode],
1090 pull ? "pull" : "none");
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301091
Linus Walleij6f4350a2012-05-02 21:06:13 +02001092 if (label && !is_out) {
1093 int irq = gpio_to_irq(gpio);
1094 struct irq_desc *desc = irq_to_desc(irq);
Rabin Vincent8ea72a32011-05-24 23:07:09 +02001095
Linus Walleij6f4350a2012-05-02 21:06:13 +02001096 /* This races with request_irq(), set_irq_type(),
1097 * and set_irq_wake() ... but those are "rare".
1098 */
1099 if (irq >= 0 && desc->action) {
1100 char *trigger;
1101 u32 bitmask = nmk_gpio_get_bitmask(gpio);
Rabin Vincent8ea72a32011-05-24 23:07:09 +02001102
Linus Walleij6f4350a2012-05-02 21:06:13 +02001103 if (nmk_chip->edge_rising & bitmask)
1104 trigger = "edge-rising";
1105 else if (nmk_chip->edge_falling & bitmask)
1106 trigger = "edge-falling";
1107 else
1108 trigger = "edge-undefined";
Rabin Vincent8ea72a32011-05-24 23:07:09 +02001109
Linus Walleij6f4350a2012-05-02 21:06:13 +02001110 seq_printf(s, " irq-%d %s%s",
1111 irq, trigger,
1112 irqd_is_wakeup_set(&desc->irq_data)
1113 ? " wakeup" : "");
Rabin Vincent8ea72a32011-05-24 23:07:09 +02001114 }
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301115 }
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001116 clk_disable(nmk_chip->clk);
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301117}
1118
Linus Walleij6f4350a2012-05-02 21:06:13 +02001119static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
1120{
1121 unsigned i;
1122 unsigned gpio = chip->base;
1123
1124 for (i = 0; i < chip->ngpio; i++, gpio++) {
1125 nmk_gpio_dbg_show_one(s, chip, i, gpio);
1126 seq_printf(s, "\n");
1127 }
1128}
1129
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301130#else
Linus Walleij6f4350a2012-05-02 21:06:13 +02001131static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
1132 struct gpio_chip *chip,
1133 unsigned offset, unsigned gpio)
1134{
1135}
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301136#define nmk_gpio_dbg_show NULL
1137#endif
1138
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001139/* This structure is replicated for each GPIO block allocated at probe time */
1140static struct gpio_chip nmk_gpio_template = {
Linus Walleijdbfe8ca2012-05-02 22:56:47 +02001141 .request = nmk_gpio_request,
1142 .free = nmk_gpio_free,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001143 .direction_input = nmk_gpio_make_input,
1144 .get = nmk_gpio_get_input,
1145 .direction_output = nmk_gpio_make_output,
1146 .set = nmk_gpio_set_output,
Rabin Vincent0d2aec92010-06-16 06:10:43 +01001147 .to_irq = nmk_gpio_to_irq,
Rabin Vincentd0b543c2010-03-04 17:39:05 +05301148 .dbg_show = nmk_gpio_dbg_show,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001149 .can_sleep = 0,
1150};
1151
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001152void nmk_gpio_clocks_enable(void)
1153{
1154 int i;
1155
1156 for (i = 0; i < NUM_BANKS; i++) {
1157 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
1158
1159 if (!chip)
1160 continue;
1161
1162 clk_enable(chip->clk);
1163 }
1164}
1165
1166void nmk_gpio_clocks_disable(void)
1167{
1168 int i;
1169
1170 for (i = 0; i < NUM_BANKS; i++) {
1171 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
1172
1173 if (!chip)
1174 continue;
1175
1176 clk_disable(chip->clk);
1177 }
1178}
1179
Rabin Vincentb9df4682011-02-10 11:45:58 +05301180/*
1181 * Called from the suspend/resume path to only keep the real wakeup interrupts
1182 * (those that have had set_irq_wake() called on them) as wakeup interrupts,
1183 * and not the rest of the interrupts which we needed to have as wakeups for
1184 * cpuidle.
1185 *
1186 * PM ops are not used since this needs to be done at the end, after all the
1187 * other drivers are done with their suspend callbacks.
1188 */
1189void nmk_gpio_wakeups_suspend(void)
1190{
1191 int i;
1192
1193 for (i = 0; i < NUM_BANKS; i++) {
1194 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
1195
1196 if (!chip)
1197 break;
1198
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001199 clk_enable(chip->clk);
1200
Rabin Vincentb9df4682011-02-10 11:45:58 +05301201 writel(chip->rwimsc & chip->real_wake,
1202 chip->addr + NMK_GPIO_RWIMSC);
1203 writel(chip->fwimsc & chip->real_wake,
1204 chip->addr + NMK_GPIO_FWIMSC);
1205
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001206 clk_disable(chip->clk);
Rabin Vincentb9df4682011-02-10 11:45:58 +05301207 }
1208}
1209
1210void nmk_gpio_wakeups_resume(void)
1211{
1212 int i;
1213
1214 for (i = 0; i < NUM_BANKS; i++) {
1215 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
1216
1217 if (!chip)
1218 break;
1219
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001220 clk_enable(chip->clk);
1221
Rabin Vincentb9df4682011-02-10 11:45:58 +05301222 writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
1223 writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
1224
Rabin Vincent3c0227d2011-09-20 10:50:03 +02001225 clk_disable(chip->clk);
Rabin Vincentb9df4682011-02-10 11:45:58 +05301226 }
1227}
1228
Rickard Anderssonbc6f5cf2011-05-24 23:07:17 +02001229/*
1230 * Read the pull up/pull down status.
1231 * A bit set in 'pull_up' means that pull up
1232 * is selected if pull is enabled in PDIS register.
1233 * Note: only pull up/down set via this driver can
1234 * be detected due to HW limitations.
1235 */
1236void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
1237{
1238 if (gpio_bank < NUM_BANKS) {
1239 struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
1240
1241 if (!chip)
1242 return;
1243
1244 *pull_up = chip->pull_up;
1245 }
1246}
1247
Lee Jonesa60b57e2012-04-19 21:36:31 +01001248int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
1249 irq_hw_number_t hwirq)
1250{
1251 struct nmk_gpio_chip *nmk_chip = d->host_data;
1252
1253 if (!nmk_chip)
1254 return -EINVAL;
1255
1256 irq_set_chip_and_handler(irq, &nmk_gpio_irq_chip, handle_edge_irq);
1257 set_irq_flags(irq, IRQF_VALID);
1258 irq_set_chip_data(irq, nmk_chip);
1259 irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
1260
1261 return 0;
1262}
1263
1264const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
1265 .map = nmk_gpio_irq_map,
1266 .xlate = irq_domain_xlate_twocell,
1267};
1268
Uwe Kleine-Königfd0d67d2010-09-02 16:13:35 +01001269static int __devinit nmk_gpio_probe(struct platform_device *dev)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001270{
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001271 struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
Lee Jones513c27f2012-04-13 15:05:05 +01001272 struct device_node *np = dev->dev.of_node;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001273 struct nmk_gpio_chip *nmk_chip;
1274 struct gpio_chip *chip;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001275 struct resource *res;
Rabin Vincentaf7dc222010-05-06 11:14:17 +01001276 struct clk *clk;
Rabin Vincent33b744b2010-10-14 10:38:03 +05301277 int secondary_irq;
Linus Walleij8d917712012-04-17 10:15:54 +02001278 void __iomem *base;
Linus Walleij832b6cd2012-10-23 09:50:17 +02001279 int irq_start = 0;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001280 int irq;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001281 int ret;
1282
Lee Jones513c27f2012-04-13 15:05:05 +01001283 if (!pdata && !np) {
1284 dev_err(&dev->dev, "No platform data or device tree found\n");
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001285 return -ENODEV;
Lee Jones513c27f2012-04-13 15:05:05 +01001286 }
1287
1288 if (np) {
Linus Walleij5e754f32012-07-03 23:05:14 +02001289 pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
Lee Jones513c27f2012-04-13 15:05:05 +01001290 if (!pdata)
1291 return -ENOMEM;
1292
Lee Jones612e1d52012-06-14 11:27:56 +01001293 if (of_get_property(np, "st,supports-sleepmode", NULL))
Lee Jones513c27f2012-04-13 15:05:05 +01001294 pdata->supports_sleepmode = true;
1295
1296 if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
1297 dev_err(&dev->dev, "gpio-bank property not found\n");
1298 ret = -EINVAL;
Lee Jonesa60b57e2012-04-19 21:36:31 +01001299 goto out;
Lee Jones513c27f2012-04-13 15:05:05 +01001300 }
1301
1302 pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP;
1303 pdata->num_gpio = NMK_GPIO_PER_CHIP;
1304 }
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001305
1306 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
1307 if (!res) {
1308 ret = -ENOENT;
1309 goto out;
1310 }
1311
1312 irq = platform_get_irq(dev, 0);
1313 if (irq < 0) {
1314 ret = irq;
1315 goto out;
1316 }
1317
Rabin Vincent33b744b2010-10-14 10:38:03 +05301318 secondary_irq = platform_get_irq(dev, 1);
1319 if (secondary_irq >= 0 && !pdata->get_secondary_status) {
1320 ret = -EINVAL;
1321 goto out;
1322 }
1323
Linus Walleij5e754f32012-07-03 23:05:14 +02001324 base = devm_request_and_ioremap(&dev->dev, res);
1325 if (!base) {
1326 ret = -ENOMEM;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001327 goto out;
1328 }
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001329
Linus Walleij5e754f32012-07-03 23:05:14 +02001330 clk = devm_clk_get(&dev->dev, NULL);
Rabin Vincentaf7dc222010-05-06 11:14:17 +01001331 if (IS_ERR(clk)) {
1332 ret = PTR_ERR(clk);
Linus Walleij5e754f32012-07-03 23:05:14 +02001333 goto out;
Rabin Vincentaf7dc222010-05-06 11:14:17 +01001334 }
Linus Walleijefec3812012-06-06 22:50:41 +02001335 clk_prepare(clk);
Rabin Vincentaf7dc222010-05-06 11:14:17 +01001336
Linus Walleij5e754f32012-07-03 23:05:14 +02001337 nmk_chip = devm_kzalloc(&dev->dev, sizeof(*nmk_chip), GFP_KERNEL);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001338 if (!nmk_chip) {
1339 ret = -ENOMEM;
Linus Walleij5e754f32012-07-03 23:05:14 +02001340 goto out;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001341 }
Lee Jones513c27f2012-04-13 15:05:05 +01001342
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001343 /*
1344 * The virt address in nmk_chip->addr is in the nomadik register space,
1345 * so we can simply convert the resource address, without remapping
1346 */
Rabin Vincent33b744b2010-10-14 10:38:03 +05301347 nmk_chip->bank = dev->id;
Rabin Vincentaf7dc222010-05-06 11:14:17 +01001348 nmk_chip->clk = clk;
Linus Walleij8d917712012-04-17 10:15:54 +02001349 nmk_chip->addr = base;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001350 nmk_chip->chip = nmk_gpio_template;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001351 nmk_chip->parent_irq = irq;
Rabin Vincent33b744b2010-10-14 10:38:03 +05301352 nmk_chip->secondary_parent_irq = secondary_irq;
1353 nmk_chip->get_secondary_status = pdata->get_secondary_status;
Rabin Vincent01727e62010-12-13 12:02:40 +05301354 nmk_chip->set_ioforce = pdata->set_ioforce;
Linus Walleij33d78642011-06-09 11:08:47 +02001355 nmk_chip->sleepmode = pdata->supports_sleepmode;
Rabin Vincentc0fcb8d2010-03-03 04:48:54 +01001356 spin_lock_init(&nmk_chip->lock);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001357
1358 chip = &nmk_chip->chip;
1359 chip->base = pdata->first_gpio;
Rabin Vincente493e062010-03-18 12:35:22 +05301360 chip->ngpio = pdata->num_gpio;
Rabin Vincent8d568ae2010-12-08 11:07:54 +05301361 chip->label = pdata->name ?: dev_name(&dev->dev);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001362 chip->dev = &dev->dev;
1363 chip->owner = THIS_MODULE;
1364
Rabin Vincentebc61782011-09-28 15:49:11 +05301365 clk_enable(nmk_chip->clk);
1366 nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
1367 clk_disable(nmk_chip->clk);
1368
Arnd Bergmann072e82a2012-05-10 13:39:52 +02001369#ifdef CONFIG_OF_GPIO
Lee Jones513c27f2012-04-13 15:05:05 +01001370 chip->of_node = np;
Arnd Bergmann072e82a2012-05-10 13:39:52 +02001371#endif
Lee Jones513c27f2012-04-13 15:05:05 +01001372
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001373 ret = gpiochip_add(&nmk_chip->chip);
1374 if (ret)
Linus Walleij5e754f32012-07-03 23:05:14 +02001375 goto out;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001376
Rabin Vincent01727e62010-12-13 12:02:40 +05301377 BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
1378
1379 nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
Lee Jones513c27f2012-04-13 15:05:05 +01001380
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001381 platform_set_drvdata(dev, nmk_chip);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001382
Linus Walleij51f58c62012-10-11 16:33:44 +02001383 if (!np)
Linus Walleij6054b9c2012-09-26 19:03:51 +02001384 irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
Linus Walleij38843e22012-10-23 11:44:42 +02001385 nmk_chip->domain = irq_domain_add_simple(np,
Linus Walleij6054b9c2012-09-26 19:03:51 +02001386 NMK_GPIO_PER_CHIP, irq_start,
1387 &nmk_gpio_irq_simple_ops, nmk_chip);
Lee Jonesa60b57e2012-04-19 21:36:31 +01001388 if (!nmk_chip->domain) {
Linus Walleij2ee38d42012-08-10 11:07:51 +02001389 dev_err(&dev->dev, "failed to create irqdomain\n");
Lee Jonesa60b57e2012-04-19 21:36:31 +01001390 ret = -ENOSYS;
Linus Walleij5e754f32012-07-03 23:05:14 +02001391 goto out;
Lee Jonesa60b57e2012-04-19 21:36:31 +01001392 }
1393
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001394 nmk_gpio_init_irq(nmk_chip);
1395
Lee Jones513c27f2012-04-13 15:05:05 +01001396 dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
1397
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001398 return 0;
1399
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001400out:
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001401 dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
1402 pdata->first_gpio, pdata->first_gpio+31);
Lee Jones513c27f2012-04-13 15:05:05 +01001403
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001404 return ret;
1405}
1406
Linus Walleije98ea772012-04-26 23:57:25 +02001407static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
1408{
1409 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1410
1411 return npct->soc->ngroups;
1412}
1413
1414static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
1415 unsigned selector)
1416{
1417 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1418
1419 return npct->soc->groups[selector].name;
1420}
1421
1422static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
1423 const unsigned **pins,
1424 unsigned *num_pins)
1425{
1426 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1427
1428 *pins = npct->soc->groups[selector].pins;
1429 *num_pins = npct->soc->groups[selector].npins;
1430 return 0;
1431}
1432
Linus Walleij24cbdd72012-05-02 21:28:00 +02001433static struct pinctrl_gpio_range *
1434nmk_match_gpio_range(struct pinctrl_dev *pctldev, unsigned offset)
1435{
1436 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1437 int i;
1438
1439 for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
1440 struct pinctrl_gpio_range *range;
1441
1442 range = &npct->soc->gpio_ranges[i];
1443 if (offset >= range->pin_base &&
1444 offset <= (range->pin_base + range->npins - 1))
1445 return range;
1446 }
1447 return NULL;
1448}
1449
Linus Walleije98ea772012-04-26 23:57:25 +02001450static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
1451 unsigned offset)
1452{
Linus Walleij24cbdd72012-05-02 21:28:00 +02001453 struct pinctrl_gpio_range *range;
1454 struct gpio_chip *chip;
1455
1456 range = nmk_match_gpio_range(pctldev, offset);
1457 if (!range || !range->gc) {
1458 seq_printf(s, "invalid pin offset");
1459 return;
1460 }
1461 chip = range->gc;
1462 nmk_gpio_dbg_show_one(s, chip, offset - chip->base, offset);
Linus Walleije98ea772012-04-26 23:57:25 +02001463}
1464
1465static struct pinctrl_ops nmk_pinctrl_ops = {
1466 .get_groups_count = nmk_get_groups_cnt,
1467 .get_group_name = nmk_get_group_name,
1468 .get_group_pins = nmk_get_group_pins,
1469 .pin_dbg_show = nmk_pin_dbg_show,
1470};
1471
Linus Walleijdbfe8ca2012-05-02 22:56:47 +02001472static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
1473{
1474 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1475
1476 return npct->soc->nfunctions;
1477}
1478
1479static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
1480 unsigned function)
1481{
1482 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1483
1484 return npct->soc->functions[function].name;
1485}
1486
1487static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
1488 unsigned function,
1489 const char * const **groups,
1490 unsigned * const num_groups)
1491{
1492 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1493
1494 *groups = npct->soc->functions[function].groups;
1495 *num_groups = npct->soc->functions[function].ngroups;
1496
1497 return 0;
1498}
1499
1500static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
1501 unsigned group)
1502{
1503 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1504 const struct nmk_pingroup *g;
1505 static unsigned int slpm[NUM_BANKS];
1506 unsigned long flags;
1507 bool glitch;
1508 int ret = -EINVAL;
1509 int i;
1510
1511 g = &npct->soc->groups[group];
1512
1513 if (g->altsetting < 0)
1514 return -EINVAL;
1515
1516 dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins);
1517
Linus Walleijdaf73172012-05-22 11:46:45 +02001518 /*
1519 * If we're setting altfunc C by setting both AFSLA and AFSLB to 1,
1520 * we may pass through an undesired state. In this case we take
1521 * some extra care.
1522 *
1523 * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
1524 * - Save SLPM registers (since we have a shadow register in the
1525 * nmk_chip we're using that as backup)
1526 * - Set SLPM=0 for the IOs you want to switch and others to 1
1527 * - Configure the GPIO registers for the IOs that are being switched
1528 * - Set IOFORCE=1
1529 * - Modify the AFLSA/B registers for the IOs that are being switched
1530 * - Set IOFORCE=0
1531 * - Restore SLPM registers
1532 * - Any spurious wake up event during switch sequence to be ignored
1533 * and cleared
1534 *
1535 * We REALLY need to save ALL slpm registers, because the external
1536 * IOFORCE will switch *all* ports to their sleepmode setting to as
1537 * to avoid glitches. (Not just one port!)
1538 */
Jean-Nicolas Grauxc22df082012-09-27 15:38:50 +02001539 glitch = ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C);
Linus Walleijdbfe8ca2012-05-02 22:56:47 +02001540
1541 if (glitch) {
1542 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
1543
1544 /* Initially don't put any pins to sleep when switching */
1545 memset(slpm, 0xff, sizeof(slpm));
1546
1547 /*
1548 * Then mask the pins that need to be sleeping now when we're
1549 * switching to the ALT C function.
1550 */
1551 for (i = 0; i < g->npins; i++)
1552 slpm[g->pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->pins[i]);
1553 nmk_gpio_glitch_slpm_init(slpm);
1554 }
1555
1556 for (i = 0; i < g->npins; i++) {
1557 struct pinctrl_gpio_range *range;
1558 struct nmk_gpio_chip *nmk_chip;
1559 struct gpio_chip *chip;
1560 unsigned bit;
1561
1562 range = nmk_match_gpio_range(pctldev, g->pins[i]);
1563 if (!range) {
1564 dev_err(npct->dev,
1565 "invalid pin offset %d in group %s at index %d\n",
1566 g->pins[i], g->name, i);
1567 goto out_glitch;
1568 }
1569 if (!range->gc) {
1570 dev_err(npct->dev, "GPIO chip missing in range for pin offset %d in group %s at index %d\n",
1571 g->pins[i], g->name, i);
1572 goto out_glitch;
1573 }
1574 chip = range->gc;
1575 nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
1576 dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->pins[i], g->altsetting);
1577
1578 clk_enable(nmk_chip->clk);
1579 bit = g->pins[i] % NMK_GPIO_PER_CHIP;
1580 /*
1581 * If the pin is switching to altfunc, and there was an
1582 * interrupt installed on it which has been lazy disabled,
1583 * actually mask the interrupt to prevent spurious interrupts
1584 * that would occur while the pin is under control of the
1585 * peripheral. Only SKE does this.
1586 */
1587 nmk_gpio_disable_lazy_irq(nmk_chip, bit);
1588
Jean-Nicolas Grauxc22df082012-09-27 15:38:50 +02001589 __nmk_gpio_set_mode_safe(nmk_chip, bit,
1590 (g->altsetting & NMK_GPIO_ALT_C), glitch);
Linus Walleijdbfe8ca2012-05-02 22:56:47 +02001591 clk_disable(nmk_chip->clk);
Jean-Nicolas Grauxc22df082012-09-27 15:38:50 +02001592
1593 /*
1594 * Call PRCM GPIOCR config function in case ALTC
1595 * has been selected:
1596 * - If selection is a ALTCx, some bits in PRCM GPIOCR registers
1597 * must be set.
1598 * - If selection is pure ALTC and previous selection was ALTCx,
1599 * then some bits in PRCM GPIOCR registers must be cleared.
1600 */
1601 if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C)
1602 nmk_prcm_altcx_set_mode(npct, g->pins[i],
1603 g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
Linus Walleijdbfe8ca2012-05-02 22:56:47 +02001604 }
1605
1606 /* When all pins are successfully reconfigured we get here */
1607 ret = 0;
1608
1609out_glitch:
1610 if (glitch) {
1611 nmk_gpio_glitch_slpm_restore(slpm);
1612 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
1613 }
1614
1615 return ret;
1616}
1617
1618static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
1619 unsigned function, unsigned group)
1620{
1621 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1622 const struct nmk_pingroup *g;
1623
1624 g = &npct->soc->groups[group];
1625
1626 if (g->altsetting < 0)
1627 return;
1628
1629 /* Poke out the mux, set the pin to some default state? */
1630 dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
1631}
1632
1633int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
1634 struct pinctrl_gpio_range *range,
1635 unsigned offset)
1636{
1637 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1638 struct nmk_gpio_chip *nmk_chip;
1639 struct gpio_chip *chip;
1640 unsigned bit;
1641
1642 if (!range) {
1643 dev_err(npct->dev, "invalid range\n");
1644 return -EINVAL;
1645 }
1646 if (!range->gc) {
1647 dev_err(npct->dev, "missing GPIO chip in range\n");
1648 return -EINVAL;
1649 }
1650 chip = range->gc;
1651 nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
1652
1653 dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
1654
1655 clk_enable(nmk_chip->clk);
1656 bit = offset % NMK_GPIO_PER_CHIP;
1657 /* There is no glitch when converting any pin to GPIO */
1658 __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
1659 clk_disable(nmk_chip->clk);
1660
1661 return 0;
1662}
1663
1664void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
1665 struct pinctrl_gpio_range *range,
1666 unsigned offset)
1667{
1668 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1669
1670 dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
1671 /* Set the pin to some default state, GPIO is usually default */
1672}
1673
1674static struct pinmux_ops nmk_pinmux_ops = {
1675 .get_functions_count = nmk_pmx_get_funcs_cnt,
1676 .get_function_name = nmk_pmx_get_func_name,
1677 .get_function_groups = nmk_pmx_get_func_groups,
1678 .enable = nmk_pmx_enable,
1679 .disable = nmk_pmx_disable,
1680 .gpio_request_enable = nmk_gpio_request_enable,
1681 .gpio_disable_free = nmk_gpio_disable_free,
1682};
1683
Linus Walleijd41af622012-05-03 15:58:12 +02001684int nmk_pin_config_get(struct pinctrl_dev *pctldev,
1685 unsigned pin,
1686 unsigned long *config)
1687{
1688 /* Not implemented */
1689 return -EINVAL;
1690}
1691
1692int nmk_pin_config_set(struct pinctrl_dev *pctldev,
1693 unsigned pin,
1694 unsigned long config)
1695{
1696 static const char *pullnames[] = {
1697 [NMK_GPIO_PULL_NONE] = "none",
1698 [NMK_GPIO_PULL_UP] = "up",
1699 [NMK_GPIO_PULL_DOWN] = "down",
1700 [3] /* illegal */ = "??"
1701 };
1702 static const char *slpmnames[] = {
1703 [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
1704 [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
1705 };
1706 struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
1707 struct nmk_gpio_chip *nmk_chip;
1708 struct pinctrl_gpio_range *range;
1709 struct gpio_chip *chip;
1710 unsigned bit;
1711
1712 /*
1713 * The pin config contains pin number and altfunction fields, here
1714 * we just ignore that part. It's being handled by the framework and
1715 * pinmux callback respectively.
1716 */
1717 pin_cfg_t cfg = (pin_cfg_t) config;
1718 int pull = PIN_PULL(cfg);
1719 int slpm = PIN_SLPM(cfg);
1720 int output = PIN_DIR(cfg);
1721 int val = PIN_VAL(cfg);
1722 bool lowemi = PIN_LOWEMI(cfg);
1723 bool gpiomode = PIN_GPIOMODE(cfg);
1724 bool sleep = PIN_SLEEPMODE(cfg);
1725
1726 range = nmk_match_gpio_range(pctldev, pin);
1727 if (!range) {
1728 dev_err(npct->dev, "invalid pin offset %d\n", pin);
1729 return -EINVAL;
1730 }
1731 if (!range->gc) {
1732 dev_err(npct->dev, "GPIO chip missing in range for pin %d\n",
1733 pin);
1734 return -EINVAL;
1735 }
1736 chip = range->gc;
1737 nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
1738
1739 if (sleep) {
1740 int slpm_pull = PIN_SLPM_PULL(cfg);
1741 int slpm_output = PIN_SLPM_DIR(cfg);
1742 int slpm_val = PIN_SLPM_VAL(cfg);
1743
1744 /* All pins go into GPIO mode at sleep */
1745 gpiomode = true;
1746
1747 /*
1748 * The SLPM_* values are normal values + 1 to allow zero to
1749 * mean "same as normal".
1750 */
1751 if (slpm_pull)
1752 pull = slpm_pull - 1;
1753 if (slpm_output)
1754 output = slpm_output - 1;
1755 if (slpm_val)
1756 val = slpm_val - 1;
1757
1758 dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
1759 pin,
1760 slpm_pull ? pullnames[pull] : "same",
1761 slpm_output ? (output ? "output" : "input") : "same",
1762 slpm_val ? (val ? "high" : "low") : "same");
1763 }
1764
1765 dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n",
1766 pin, cfg, pullnames[pull], slpmnames[slpm],
1767 output ? "output " : "input",
1768 output ? (val ? "high" : "low") : "",
1769 lowemi ? "on" : "off" );
1770
1771 clk_enable(nmk_chip->clk);
1772 bit = pin % NMK_GPIO_PER_CHIP;
1773 if (gpiomode)
1774 /* No glitch when going to GPIO mode */
1775 __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
1776 if (output)
1777 __nmk_gpio_make_output(nmk_chip, bit, val);
1778 else {
1779 __nmk_gpio_make_input(nmk_chip, bit);
1780 __nmk_gpio_set_pull(nmk_chip, bit, pull);
1781 }
1782 /* TODO: isn't this only applicable on output pins? */
1783 __nmk_gpio_set_lowemi(nmk_chip, bit, lowemi);
1784
1785 __nmk_gpio_set_slpm(nmk_chip, bit, slpm);
1786 clk_disable(nmk_chip->clk);
1787 return 0;
1788}
1789
1790static struct pinconf_ops nmk_pinconf_ops = {
1791 .pin_config_get = nmk_pin_config_get,
1792 .pin_config_set = nmk_pin_config_set,
1793};
1794
Linus Walleije98ea772012-04-26 23:57:25 +02001795static struct pinctrl_desc nmk_pinctrl_desc = {
1796 .name = "pinctrl-nomadik",
1797 .pctlops = &nmk_pinctrl_ops,
Linus Walleijdbfe8ca2012-05-02 22:56:47 +02001798 .pmxops = &nmk_pinmux_ops,
Linus Walleijd41af622012-05-03 15:58:12 +02001799 .confops = &nmk_pinconf_ops,
Linus Walleije98ea772012-04-26 23:57:25 +02001800 .owner = THIS_MODULE,
1801};
1802
Lee Jones855f80c2012-05-26 06:09:29 +01001803static const struct of_device_id nmk_pinctrl_match[] = {
1804 {
1805 .compatible = "stericsson,nmk_pinctrl",
1806 .data = (void *)PINCTRL_NMK_DB8500,
1807 },
1808 {},
1809};
1810
Linus Walleije98ea772012-04-26 23:57:25 +02001811static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
1812{
1813 const struct platform_device_id *platid = platform_get_device_id(pdev);
Lee Jones855f80c2012-05-26 06:09:29 +01001814 struct device_node *np = pdev->dev.of_node;
Linus Walleije98ea772012-04-26 23:57:25 +02001815 struct nmk_pinctrl *npct;
Lee Jones855f80c2012-05-26 06:09:29 +01001816 unsigned int version = 0;
Linus Walleije98ea772012-04-26 23:57:25 +02001817 int i;
1818
1819 npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL);
1820 if (!npct)
1821 return -ENOMEM;
1822
Lee Jones855f80c2012-05-26 06:09:29 +01001823 if (platid)
1824 version = platid->driver_data;
1825 else if (np)
1826 version = (unsigned int)
1827 of_match_device(nmk_pinctrl_match, &pdev->dev)->data;
1828
Linus Walleije98ea772012-04-26 23:57:25 +02001829 /* Poke in other ASIC variants here */
Linus Walleijf79c5ed2012-08-10 00:43:28 +02001830 if (version == PINCTRL_NMK_STN8815)
1831 nmk_pinctrl_stn8815_init(&npct->soc);
Lee Jones855f80c2012-05-26 06:09:29 +01001832 if (version == PINCTRL_NMK_DB8500)
Linus Walleije98ea772012-04-26 23:57:25 +02001833 nmk_pinctrl_db8500_init(&npct->soc);
Patrice Chotard45a1b532012-07-20 15:45:22 +02001834 if (version == PINCTRL_NMK_DB8540)
1835 nmk_pinctrl_db8540_init(&npct->soc);
Linus Walleije98ea772012-04-26 23:57:25 +02001836
1837 /*
1838 * We need all the GPIO drivers to probe FIRST, or we will not be able
1839 * to obtain references to the struct gpio_chip * for them, and we
1840 * need this to proceed.
1841 */
1842 for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
1843 if (!nmk_gpio_chips[i]) {
1844 dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
Linus Walleije98ea772012-04-26 23:57:25 +02001845 return -EPROBE_DEFER;
1846 }
1847 npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip;
1848 }
1849
1850 nmk_pinctrl_desc.pins = npct->soc->pins;
1851 nmk_pinctrl_desc.npins = npct->soc->npins;
1852 npct->dev = &pdev->dev;
1853 npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct);
1854 if (!npct->pctl) {
1855 dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n");
1856 return -EINVAL;
1857 }
1858
1859 /* We will handle a range of GPIO pins */
1860 for (i = 0; i < npct->soc->gpio_num_ranges; i++)
1861 pinctrl_add_gpio_range(npct->pctl, &npct->soc->gpio_ranges[i]);
1862
1863 platform_set_drvdata(pdev, npct);
1864 dev_info(&pdev->dev, "initialized Nomadik pin control driver\n");
1865
1866 return 0;
1867}
1868
Lee Jones513c27f2012-04-13 15:05:05 +01001869static const struct of_device_id nmk_gpio_match[] = {
1870 { .compatible = "st,nomadik-gpio", },
1871 {}
1872};
1873
Rabin Vincent3e3c62c2010-03-03 04:52:34 +01001874static struct platform_driver nmk_gpio_driver = {
1875 .driver = {
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001876 .owner = THIS_MODULE,
1877 .name = "gpio",
Lee Jones513c27f2012-04-13 15:05:05 +01001878 .of_match_table = nmk_gpio_match,
Rabin Vincent5317e4d12011-02-10 09:29:53 +05301879 },
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001880 .probe = nmk_gpio_probe,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001881};
1882
Linus Walleije98ea772012-04-26 23:57:25 +02001883static const struct platform_device_id nmk_pinctrl_id[] = {
1884 { "pinctrl-stn8815", PINCTRL_NMK_STN8815 },
1885 { "pinctrl-db8500", PINCTRL_NMK_DB8500 },
Patrice Chotard45a1b532012-07-20 15:45:22 +02001886 { "pinctrl-db8540", PINCTRL_NMK_DB8540 },
Linus Walleije98ea772012-04-26 23:57:25 +02001887};
1888
1889static struct platform_driver nmk_pinctrl_driver = {
1890 .driver = {
1891 .owner = THIS_MODULE,
1892 .name = "pinctrl-nomadik",
Lee Jones855f80c2012-05-26 06:09:29 +01001893 .of_match_table = nmk_pinctrl_match,
Linus Walleije98ea772012-04-26 23:57:25 +02001894 },
1895 .probe = nmk_pinctrl_probe,
1896 .id_table = nmk_pinctrl_id,
1897};
1898
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001899static int __init nmk_gpio_init(void)
1900{
Linus Walleije98ea772012-04-26 23:57:25 +02001901 int ret;
1902
1903 ret = platform_driver_register(&nmk_gpio_driver);
1904 if (ret)
1905 return ret;
1906 return platform_driver_register(&nmk_pinctrl_driver);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001907}
1908
Rabin Vincent33f45ea2010-06-02 06:09:52 +01001909core_initcall(nmk_gpio_init);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +01001910
1911MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
1912MODULE_DESCRIPTION("Nomadik GPIO Driver");
1913MODULE_LICENSE("GPL");