blob: 45b1cf95e378f9eb62183c6cd3a6ffb3d2485009 [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>
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#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/device.h>
Rabin Vincent3e3c62c2010-03-03 04:52:34 +010016#include <linux/platform_device.h>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010017#include <linux/io.h>
Rabin Vincentaf7dc222010-05-06 11:14:17 +010018#include <linux/clk.h>
19#include <linux/err.h>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010020#include <linux/gpio.h>
21#include <linux/spinlock.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090024#include <linux/slab.h>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010025
Rabin Vincent378be062010-06-02 06:06:29 +010026#include <plat/pincfg.h>
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010027#include <mach/hardware.h>
28#include <mach/gpio.h>
29
30/*
31 * The GPIO module in the Nomadik family of Systems-on-Chip is an
32 * AMBA device, managing 32 pins and alternate functions. The logic block
Jonas Aaberg9c66ee62010-10-13 13:14:17 +020033 * is currently used in the Nomadik and ux500.
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010034 *
35 * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
36 */
37
Rabin Vincent01727e62010-12-13 12:02:40 +053038#define NMK_GPIO_PER_CHIP 32
39
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010040struct nmk_gpio_chip {
41 struct gpio_chip chip;
42 void __iomem *addr;
Rabin Vincentaf7dc222010-05-06 11:14:17 +010043 struct clk *clk;
Rabin Vincent33b744b2010-10-14 10:38:03 +053044 unsigned int bank;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010045 unsigned int parent_irq;
Virupax Sadashivpetimath2c8bb0e2010-11-11 14:10:38 +053046 int secondary_parent_irq;
Rabin Vincent33b744b2010-10-14 10:38:03 +053047 u32 (*get_secondary_status)(unsigned int bank);
Rabin Vincent01727e62010-12-13 12:02:40 +053048 void (*set_ioforce)(bool enable);
Rabin Vincentc0fcb8d2010-03-03 04:48:54 +010049 spinlock_t lock;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +010050 /* Keep track of configured edges */
51 u32 edge_rising;
52 u32 edge_falling;
53};
54
Rabin Vincent01727e62010-12-13 12:02:40 +053055static struct nmk_gpio_chip *
56nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
57
58static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
59
60#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
61
Rabin Vincent6f9a9742010-06-02 05:50:28 +010062static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
63 unsigned offset, int gpio_mode)
64{
65 u32 bit = 1 << offset;
66 u32 afunc, bfunc;
67
68 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
69 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
70 if (gpio_mode & NMK_GPIO_ALT_A)
71 afunc |= bit;
72 if (gpio_mode & NMK_GPIO_ALT_B)
73 bfunc |= bit;
74 writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
75 writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
76}
77
Rabin Vincent81a3c292010-05-27 12:39:23 +010078static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
79 unsigned offset, enum nmk_gpio_slpm mode)
80{
81 u32 bit = 1 << offset;
82 u32 slpm;
83
84 slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
85 if (mode == NMK_GPIO_SLPM_NOCHANGE)
86 slpm |= bit;
87 else
88 slpm &= ~bit;
89 writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
90}
91
Rabin Vincent5b327ed2010-05-27 12:29:50 +010092static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
93 unsigned offset, enum nmk_gpio_pull pull)
94{
95 u32 bit = 1 << offset;
96 u32 pdis;
97
98 pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
99 if (pull == NMK_GPIO_PULL_NONE)
100 pdis |= bit;
101 else
102 pdis &= ~bit;
103 writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
104
Rabin Vincent5317e4d12011-02-10 09:29:53 +0530105 if (pull == NMK_GPIO_PULL_UP)
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100106 writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
Rabin Vincent5317e4d12011-02-10 09:29:53 +0530107 else if (pull == NMK_GPIO_PULL_DOWN)
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100108 writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
109}
110
Rabin Vincent378be062010-06-02 06:06:29 +0100111static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
112 unsigned offset)
113{
114 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
115}
116
Rabin Vincent6720db72010-09-02 11:28:48 +0100117static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
118 unsigned offset, int val)
119{
120 if (val)
121 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
122 else
123 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
124}
125
126static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
127 unsigned offset, int val)
128{
129 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
130 __nmk_gpio_set_output(nmk_chip, offset, val);
131}
132
Rabin Vincent01727e62010-12-13 12:02:40 +0530133static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
134 unsigned offset, int gpio_mode,
135 bool glitch)
136{
Linus Walleij3c4bee02011-02-16 10:37:52 +0100137 u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
138 u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
Rabin Vincent01727e62010-12-13 12:02:40 +0530139
140 if (glitch && nmk_chip->set_ioforce) {
141 u32 bit = BIT(offset);
142
Rabin Vincent01727e62010-12-13 12:02:40 +0530143 /* Prevent spurious wakeups */
144 writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
145 writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
146
147 nmk_chip->set_ioforce(true);
148 }
149
150 __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
151
152 if (glitch && nmk_chip->set_ioforce) {
153 nmk_chip->set_ioforce(false);
154
155 writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
156 writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
157 }
158}
159
Rabin Vincent378be062010-06-02 06:06:29 +0100160static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
Rabin Vincent01727e62010-12-13 12:02:40 +0530161 pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
Rabin Vincent378be062010-06-02 06:06:29 +0100162{
163 static const char *afnames[] = {
164 [NMK_GPIO_ALT_GPIO] = "GPIO",
165 [NMK_GPIO_ALT_A] = "A",
166 [NMK_GPIO_ALT_B] = "B",
167 [NMK_GPIO_ALT_C] = "C"
168 };
169 static const char *pullnames[] = {
170 [NMK_GPIO_PULL_NONE] = "none",
171 [NMK_GPIO_PULL_UP] = "up",
172 [NMK_GPIO_PULL_DOWN] = "down",
173 [3] /* illegal */ = "??"
174 };
175 static const char *slpmnames[] = {
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100176 [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
177 [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
Rabin Vincent378be062010-06-02 06:06:29 +0100178 };
179
180 int pin = PIN_NUM(cfg);
181 int pull = PIN_PULL(cfg);
182 int af = PIN_ALT(cfg);
183 int slpm = PIN_SLPM(cfg);
Rabin Vincent6720db72010-09-02 11:28:48 +0100184 int output = PIN_DIR(cfg);
185 int val = PIN_VAL(cfg);
Rabin Vincent01727e62010-12-13 12:02:40 +0530186 bool glitch = af == NMK_GPIO_ALT_C;
Rabin Vincent378be062010-06-02 06:06:29 +0100187
Rabin Vincentdacdc962010-12-03 20:35:37 +0530188 dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
189 pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
Rabin Vincent6720db72010-09-02 11:28:48 +0100190 output ? "output " : "input",
191 output ? (val ? "high" : "low") : "");
Rabin Vincent378be062010-06-02 06:06:29 +0100192
Rabin Vincentdacdc962010-12-03 20:35:37 +0530193 if (sleep) {
194 int slpm_pull = PIN_SLPM_PULL(cfg);
195 int slpm_output = PIN_SLPM_DIR(cfg);
196 int slpm_val = PIN_SLPM_VAL(cfg);
197
Rabin Vincent3546d152010-11-25 11:38:27 +0530198 af = NMK_GPIO_ALT_GPIO;
199
Rabin Vincentdacdc962010-12-03 20:35:37 +0530200 /*
201 * The SLPM_* values are normal values + 1 to allow zero to
202 * mean "same as normal".
203 */
204 if (slpm_pull)
205 pull = slpm_pull - 1;
206 if (slpm_output)
207 output = slpm_output - 1;
208 if (slpm_val)
209 val = slpm_val - 1;
210
211 dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
212 pin,
213 slpm_pull ? pullnames[pull] : "same",
214 slpm_output ? (output ? "output" : "input") : "same",
215 slpm_val ? (val ? "high" : "low") : "same");
216 }
217
Rabin Vincent6720db72010-09-02 11:28:48 +0100218 if (output)
219 __nmk_gpio_make_output(nmk_chip, offset, val);
220 else {
221 __nmk_gpio_make_input(nmk_chip, offset);
222 __nmk_gpio_set_pull(nmk_chip, offset, pull);
223 }
224
Rabin Vincent01727e62010-12-13 12:02:40 +0530225 /*
226 * If we've backed up the SLPM registers (glitch workaround), modify
227 * the backups since they will be restored.
228 */
229 if (slpmregs) {
230 if (slpm == NMK_GPIO_SLPM_NOCHANGE)
231 slpmregs[nmk_chip->bank] |= BIT(offset);
232 else
233 slpmregs[nmk_chip->bank] &= ~BIT(offset);
234 } else
235 __nmk_gpio_set_slpm(nmk_chip, offset, slpm);
236
237 __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
238}
239
240/*
241 * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
242 * - Save SLPM registers
243 * - Set SLPM=0 for the IOs you want to switch and others to 1
244 * - Configure the GPIO registers for the IOs that are being switched
245 * - Set IOFORCE=1
246 * - Modify the AFLSA/B registers for the IOs that are being switched
247 * - Set IOFORCE=0
248 * - Restore SLPM registers
249 * - Any spurious wake up event during switch sequence to be ignored and
250 * cleared
251 */
252static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
253{
254 int i;
255
256 for (i = 0; i < NUM_BANKS; i++) {
257 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
258 unsigned int temp = slpm[i];
259
260 if (!chip)
261 break;
262
263 slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
264 writel(temp, chip->addr + NMK_GPIO_SLPC);
265 }
266}
267
268static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
269{
270 int i;
271
272 for (i = 0; i < NUM_BANKS; i++) {
273 struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
274
275 if (!chip)
276 break;
277
278 writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
279 }
280}
281
282static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
283{
284 static unsigned int slpm[NUM_BANKS];
285 unsigned long flags;
286 bool glitch = false;
287 int ret = 0;
288 int i;
289
290 for (i = 0; i < num; i++) {
291 if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) {
292 glitch = true;
293 break;
294 }
295 }
296
297 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
298
299 if (glitch) {
300 memset(slpm, 0xff, sizeof(slpm));
301
302 for (i = 0; i < num; i++) {
303 int pin = PIN_NUM(cfgs[i]);
304 int offset = pin % NMK_GPIO_PER_CHIP;
305
306 if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C)
307 slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset);
308 }
309
310 nmk_gpio_glitch_slpm_init(slpm);
311 }
312
313 for (i = 0; i < num; i++) {
314 struct nmk_gpio_chip *nmk_chip;
315 int pin = PIN_NUM(cfgs[i]);
316
317 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
318 if (!nmk_chip) {
319 ret = -EINVAL;
320 break;
321 }
322
323 spin_lock(&nmk_chip->lock);
324 __nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base,
325 cfgs[i], sleep, glitch ? slpm : NULL);
326 spin_unlock(&nmk_chip->lock);
327 }
328
329 if (glitch)
330 nmk_gpio_glitch_slpm_restore(slpm);
331
332 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
333
334 return ret;
Rabin Vincent378be062010-06-02 06:06:29 +0100335}
336
337/**
338 * nmk_config_pin - configure a pin's mux attributes
339 * @cfg: pin confguration
340 *
341 * Configures a pin's mode (alternate function or GPIO), its pull up status,
342 * and its sleep mode based on the specified configuration. The @cfg is
343 * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These
344 * are constructed using, and can be further enhanced with, the macros in
345 * plat/pincfg.h.
346 *
347 * If a pin's mode is set to GPIO, it is configured as an input to avoid
348 * side-effects. The gpio can be manipulated later using standard GPIO API
349 * calls.
350 */
Rabin Vincentdacdc962010-12-03 20:35:37 +0530351int nmk_config_pin(pin_cfg_t cfg, bool sleep)
Rabin Vincent378be062010-06-02 06:06:29 +0100352{
Rabin Vincent01727e62010-12-13 12:02:40 +0530353 return __nmk_config_pins(&cfg, 1, sleep);
Rabin Vincent378be062010-06-02 06:06:29 +0100354}
355EXPORT_SYMBOL(nmk_config_pin);
356
357/**
358 * nmk_config_pins - configure several pins at once
359 * @cfgs: array of pin configurations
360 * @num: number of elments in the array
361 *
362 * Configures several pins using nmk_config_pin(). Refer to that function for
363 * further information.
364 */
365int nmk_config_pins(pin_cfg_t *cfgs, int num)
366{
Rabin Vincent01727e62010-12-13 12:02:40 +0530367 return __nmk_config_pins(cfgs, num, false);
Rabin Vincent378be062010-06-02 06:06:29 +0100368}
369EXPORT_SYMBOL(nmk_config_pins);
370
Rabin Vincentdacdc962010-12-03 20:35:37 +0530371int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
372{
Rabin Vincent01727e62010-12-13 12:02:40 +0530373 return __nmk_config_pins(cfgs, num, true);
Rabin Vincentdacdc962010-12-03 20:35:37 +0530374}
375EXPORT_SYMBOL(nmk_config_pins_sleep);
376
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100377/**
Rabin Vincent81a3c292010-05-27 12:39:23 +0100378 * nmk_gpio_set_slpm() - configure the sleep mode of a pin
379 * @gpio: pin number
380 * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
381 *
382 * Sets the sleep mode of a pin. If @mode is NMK_GPIO_SLPM_INPUT, the pin is
383 * changed to an input (with pullup/down enabled) in sleep and deep sleep. If
384 * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
385 * configured even when in sleep and deep sleep.
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100386 *
387 * On DB8500v2 onwards, this setting loses the previous meaning and instead
388 * indicates if wakeup detection is enabled on the pin. Note that
389 * enable_irq_wake() will automatically enable wakeup detection.
Rabin Vincent81a3c292010-05-27 12:39:23 +0100390 */
391int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
392{
393 struct nmk_gpio_chip *nmk_chip;
394 unsigned long flags;
395
396 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
397 if (!nmk_chip)
398 return -EINVAL;
399
Rabin Vincent01727e62010-12-13 12:02:40 +0530400 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
401 spin_lock(&nmk_chip->lock);
402
Rabin Vincent81a3c292010-05-27 12:39:23 +0100403 __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
Rabin Vincent01727e62010-12-13 12:02:40 +0530404
405 spin_unlock(&nmk_chip->lock);
406 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
Rabin Vincent81a3c292010-05-27 12:39:23 +0100407
408 return 0;
409}
410
411/**
Rabin Vincent5b327ed2010-05-27 12:29:50 +0100412 * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
413 * @gpio: pin number
414 * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
415 *
416 * Enables/disables pull up/down on a specified pin. This only takes effect if
417 * the pin is configured as an input (either explicitly or by the alternate
418 * function).
419 *
420 * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
421 * configured as an input. Otherwise, due to the way the controller registers
422 * work, this function will change the value output on the pin.
423 */
424int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
425{
426 struct nmk_gpio_chip *nmk_chip;
427 unsigned long flags;
428
429 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
430 if (!nmk_chip)
431 return -EINVAL;
432
433 spin_lock_irqsave(&nmk_chip->lock, flags);
434 __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
435 spin_unlock_irqrestore(&nmk_chip->lock, flags);
436
437 return 0;
438}
439
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100440/* Mode functions */
Jonas Aaberg9c66ee62010-10-13 13:14:17 +0200441/**
442 * nmk_gpio_set_mode() - set the mux mode of a gpio pin
443 * @gpio: pin number
444 * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A,
445 * NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C
446 *
447 * Sets the mode of the specified pin to one of the alternate functions or
448 * plain GPIO.
449 */
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100450int nmk_gpio_set_mode(int gpio, int gpio_mode)
451{
452 struct nmk_gpio_chip *nmk_chip;
453 unsigned long flags;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100454
455 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
456 if (!nmk_chip)
457 return -EINVAL;
458
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100459 spin_lock_irqsave(&nmk_chip->lock, flags);
Rabin Vincent6f9a9742010-06-02 05:50:28 +0100460 __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100461 spin_unlock_irqrestore(&nmk_chip->lock, flags);
462
463 return 0;
464}
465EXPORT_SYMBOL(nmk_gpio_set_mode);
466
467int nmk_gpio_get_mode(int gpio)
468{
469 struct nmk_gpio_chip *nmk_chip;
470 u32 afunc, bfunc, bit;
471
472 nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
473 if (!nmk_chip)
474 return -EINVAL;
475
476 bit = 1 << (gpio - nmk_chip->chip.base);
477
478 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
479 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
480
481 return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
482}
483EXPORT_SYMBOL(nmk_gpio_get_mode);
484
485
486/* IRQ functions */
487static inline int nmk_gpio_get_bitmask(int gpio)
488{
489 return 1 << (gpio % 32);
490}
491
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100492static void nmk_gpio_irq_ack(struct irq_data *d)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100493{
494 int gpio;
495 struct nmk_gpio_chip *nmk_chip;
496
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100497 gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
498 nmk_chip = irq_data_get_irq_chip_data(d);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100499 if (!nmk_chip)
500 return;
501 writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
502}
503
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100504enum nmk_gpio_irq_type {
505 NORMAL,
506 WAKE,
507};
508
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100509static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100510 int gpio, enum nmk_gpio_irq_type which,
511 bool enable)
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100512{
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100513 u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
514 u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100515 u32 bitmask = nmk_gpio_get_bitmask(gpio);
516 u32 reg;
517
518 /* we must individually set/clear the two edges */
519 if (nmk_chip->edge_rising & bitmask) {
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100520 reg = readl(nmk_chip->addr + rimsc);
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100521 if (enable)
522 reg |= bitmask;
523 else
524 reg &= ~bitmask;
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100525 writel(reg, nmk_chip->addr + rimsc);
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100526 }
527 if (nmk_chip->edge_falling & bitmask) {
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100528 reg = readl(nmk_chip->addr + fimsc);
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100529 if (enable)
530 reg |= bitmask;
531 else
532 reg &= ~bitmask;
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100533 writel(reg, nmk_chip->addr + fimsc);
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100534 }
535}
536
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100537static int nmk_gpio_irq_modify(struct irq_data *d, enum nmk_gpio_irq_type which,
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100538 bool enable)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100539{
540 int gpio;
541 struct nmk_gpio_chip *nmk_chip;
542 unsigned long flags;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100543 u32 bitmask;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100544
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100545 gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
546 nmk_chip = irq_data_get_irq_chip_data(d);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100547 bitmask = nmk_gpio_get_bitmask(gpio);
548 if (!nmk_chip)
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100549 return -EINVAL;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100550
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100551 spin_lock_irqsave(&nmk_chip->lock, flags);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100552 __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100553 spin_unlock_irqrestore(&nmk_chip->lock, flags);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100554
555 return 0;
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100556}
557
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100558static void nmk_gpio_irq_mask(struct irq_data *d)
Rabin Vincent040e5ec2010-05-06 10:42:42 +0100559{
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100560 nmk_gpio_irq_modify(d, NORMAL, false);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100561}
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100562
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100563static void nmk_gpio_irq_unmask(struct irq_data *d)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100564{
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100565 nmk_gpio_irq_modify(d, NORMAL, true);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100566}
567
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100568static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100569{
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100570 struct nmk_gpio_chip *nmk_chip;
571 unsigned long flags;
572 int gpio;
573
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100574 gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
575 nmk_chip = irq_data_get_irq_chip_data(d);
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100576 if (!nmk_chip)
577 return -EINVAL;
578
Rabin Vincent01727e62010-12-13 12:02:40 +0530579 spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
580 spin_lock(&nmk_chip->lock);
581
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100582#ifdef CONFIG_ARCH_U8500
583 if (cpu_is_u8500v2()) {
Rikard Olsson8b40eee2011-01-03 14:30:41 +0100584 __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base,
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100585 on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
586 : NMK_GPIO_SLPM_WAKEUP_DISABLE);
587 }
588#endif
589 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
Rabin Vincent01727e62010-12-13 12:02:40 +0530590
591 spin_unlock(&nmk_chip->lock);
592 spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
Rabin Vincent7e3f7e52010-09-02 11:28:05 +0100593
594 return 0;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100595}
596
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100597static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100598{
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100599 struct irq_desc *desc = irq_to_desc(d->irq);
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100600 bool enabled = !(desc->status & IRQ_DISABLED);
601 bool wake = desc->wake_depth;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100602 int gpio;
603 struct nmk_gpio_chip *nmk_chip;
604 unsigned long flags;
605 u32 bitmask;
606
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100607 gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
608 nmk_chip = irq_data_get_irq_chip_data(d);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100609 bitmask = nmk_gpio_get_bitmask(gpio);
610 if (!nmk_chip)
611 return -EINVAL;
612
613 if (type & IRQ_TYPE_LEVEL_HIGH)
614 return -EINVAL;
615 if (type & IRQ_TYPE_LEVEL_LOW)
616 return -EINVAL;
617
618 spin_lock_irqsave(&nmk_chip->lock, flags);
619
Rabin Vincent7a852d82010-05-06 10:43:55 +0100620 if (enabled)
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100621 __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
622
623 if (wake)
624 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
Rabin Vincent7a852d82010-05-06 10:43:55 +0100625
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100626 nmk_chip->edge_rising &= ~bitmask;
627 if (type & IRQ_TYPE_EDGE_RISING)
628 nmk_chip->edge_rising |= bitmask;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100629
630 nmk_chip->edge_falling &= ~bitmask;
631 if (type & IRQ_TYPE_EDGE_FALLING)
632 nmk_chip->edge_falling |= bitmask;
Rabin Vincent7a852d82010-05-06 10:43:55 +0100633
634 if (enabled)
Rabin Vincent4d4e20f2010-06-16 06:09:34 +0100635 __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
636
637 if (wake)
638 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100639
640 spin_unlock_irqrestore(&nmk_chip->lock, flags);
641
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100642 return 0;
643}
644
645static struct irq_chip nmk_gpio_irq_chip = {
646 .name = "Nomadik-GPIO",
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100647 .irq_ack = nmk_gpio_irq_ack,
648 .irq_mask = nmk_gpio_irq_mask,
649 .irq_unmask = nmk_gpio_irq_unmask,
650 .irq_set_type = nmk_gpio_irq_set_type,
651 .irq_set_wake = nmk_gpio_irq_set_wake,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100652};
653
Rabin Vincent33b744b2010-10-14 10:38:03 +0530654static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
655 u32 status)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100656{
657 struct nmk_gpio_chip *nmk_chip;
Rabin Vincentaaedaa22010-03-03 04:50:27 +0100658 struct irq_chip *host_chip = get_irq_chip(irq);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100659 unsigned int first_irq;
660
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100661 if (host_chip->irq_mask_ack)
662 host_chip->irq_mask_ack(&desc->irq_data);
Rabin Vincentaaedaa22010-03-03 04:50:27 +0100663 else {
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100664 host_chip->irq_mask(&desc->irq_data);
665 if (host_chip->irq_ack)
666 host_chip->irq_ack(&desc->irq_data);
Rabin Vincentaaedaa22010-03-03 04:50:27 +0100667 }
668
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100669 nmk_chip = get_irq_data(irq);
670 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530671 while (status) {
672 int bit = __ffs(status);
673
674 generic_handle_irq(first_irq + bit);
675 status &= ~BIT(bit);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100676 }
Rabin Vincentaaedaa22010-03-03 04:50:27 +0100677
Lennert Buytenhekf272c002010-11-29 11:16:48 +0100678 host_chip->irq_unmask(&desc->irq_data);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100679}
680
Rabin Vincent33b744b2010-10-14 10:38:03 +0530681static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
682{
683 struct nmk_gpio_chip *nmk_chip = get_irq_data(irq);
684 u32 status = readl(nmk_chip->addr + NMK_GPIO_IS);
685
686 __nmk_gpio_irq_handler(irq, desc, status);
687}
688
689static void nmk_gpio_secondary_irq_handler(unsigned int irq,
690 struct irq_desc *desc)
691{
692 struct nmk_gpio_chip *nmk_chip = get_irq_data(irq);
693 u32 status = nmk_chip->get_secondary_status(nmk_chip->bank);
694
695 __nmk_gpio_irq_handler(irq, desc, status);
696}
697
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100698static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
699{
700 unsigned int first_irq;
701 int i;
702
703 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
Rabin Vincente493e062010-03-18 12:35:22 +0530704 for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) {
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100705 set_irq_chip(i, &nmk_gpio_irq_chip);
706 set_irq_handler(i, handle_edge_irq);
707 set_irq_flags(i, IRQF_VALID);
708 set_irq_chip_data(i, nmk_chip);
Rabin Vincent2210d642010-05-06 10:45:18 +0100709 set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100710 }
Rabin Vincent33b744b2010-10-14 10:38:03 +0530711
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100712 set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
713 set_irq_data(nmk_chip->parent_irq, nmk_chip);
Rabin Vincent33b744b2010-10-14 10:38:03 +0530714
715 if (nmk_chip->secondary_parent_irq >= 0) {
716 set_irq_chained_handler(nmk_chip->secondary_parent_irq,
717 nmk_gpio_secondary_irq_handler);
718 set_irq_data(nmk_chip->secondary_parent_irq, nmk_chip);
719 }
720
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100721 return 0;
722}
723
724/* I/O Functions */
725static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
726{
727 struct nmk_gpio_chip *nmk_chip =
728 container_of(chip, struct nmk_gpio_chip, chip);
729
730 writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
731 return 0;
732}
733
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100734static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
735{
736 struct nmk_gpio_chip *nmk_chip =
737 container_of(chip, struct nmk_gpio_chip, chip);
738 u32 bit = 1 << offset;
739
740 return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
741}
742
743static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
744 int val)
745{
746 struct nmk_gpio_chip *nmk_chip =
747 container_of(chip, struct nmk_gpio_chip, chip);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100748
Rabin Vincent6720db72010-09-02 11:28:48 +0100749 __nmk_gpio_set_output(nmk_chip, offset, val);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100750}
751
Rabin Vincent6647c6c2010-05-27 12:22:42 +0100752static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
753 int val)
754{
755 struct nmk_gpio_chip *nmk_chip =
756 container_of(chip, struct nmk_gpio_chip, chip);
757
Rabin Vincent6720db72010-09-02 11:28:48 +0100758 __nmk_gpio_make_output(nmk_chip, offset, val);
Rabin Vincent6647c6c2010-05-27 12:22:42 +0100759
760 return 0;
761}
762
Rabin Vincent0d2aec92010-06-16 06:10:43 +0100763static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
764{
765 struct nmk_gpio_chip *nmk_chip =
766 container_of(chip, struct nmk_gpio_chip, chip);
767
768 return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
769}
770
Rabin Vincentd0b543c2010-03-04 17:39:05 +0530771#ifdef CONFIG_DEBUG_FS
772
773#include <linux/seq_file.h>
774
775static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
776{
777 int mode;
778 unsigned i;
779 unsigned gpio = chip->base;
780 int is_out;
781 struct nmk_gpio_chip *nmk_chip =
782 container_of(chip, struct nmk_gpio_chip, chip);
783 const char *modes[] = {
784 [NMK_GPIO_ALT_GPIO] = "gpio",
785 [NMK_GPIO_ALT_A] = "altA",
786 [NMK_GPIO_ALT_B] = "altB",
787 [NMK_GPIO_ALT_C] = "altC",
788 };
789
790 for (i = 0; i < chip->ngpio; i++, gpio++) {
791 const char *label = gpiochip_is_requested(chip, i);
792 bool pull;
793 u32 bit = 1 << i;
794
795 if (!label)
796 continue;
797
798 is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit;
799 pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
800 mode = nmk_gpio_get_mode(gpio);
801 seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
802 gpio, label,
803 is_out ? "out" : "in ",
804 chip->get
805 ? (chip->get(chip, i) ? "hi" : "lo")
806 : "? ",
807 (mode < 0) ? "unknown" : modes[mode],
808 pull ? "pull" : "none");
809
810 if (!is_out) {
811 int irq = gpio_to_irq(gpio);
812 struct irq_desc *desc = irq_to_desc(irq);
813
814 /* This races with request_irq(), set_irq_type(),
815 * and set_irq_wake() ... but those are "rare".
816 *
817 * More significantly, trigger type flags aren't
818 * currently maintained by genirq.
819 */
820 if (irq >= 0 && desc->action) {
821 char *trigger;
822
823 switch (desc->status & IRQ_TYPE_SENSE_MASK) {
824 case IRQ_TYPE_NONE:
825 trigger = "(default)";
826 break;
827 case IRQ_TYPE_EDGE_FALLING:
828 trigger = "edge-falling";
829 break;
830 case IRQ_TYPE_EDGE_RISING:
831 trigger = "edge-rising";
832 break;
833 case IRQ_TYPE_EDGE_BOTH:
834 trigger = "edge-both";
835 break;
836 case IRQ_TYPE_LEVEL_HIGH:
837 trigger = "level-high";
838 break;
839 case IRQ_TYPE_LEVEL_LOW:
840 trigger = "level-low";
841 break;
842 default:
843 trigger = "?trigger?";
844 break;
845 }
846
847 seq_printf(s, " irq-%d %s%s",
848 irq, trigger,
849 (desc->status & IRQ_WAKEUP)
850 ? " wakeup" : "");
851 }
852 }
853
854 seq_printf(s, "\n");
855 }
856}
857
858#else
859#define nmk_gpio_dbg_show NULL
860#endif
861
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100862/* This structure is replicated for each GPIO block allocated at probe time */
863static struct gpio_chip nmk_gpio_template = {
864 .direction_input = nmk_gpio_make_input,
865 .get = nmk_gpio_get_input,
866 .direction_output = nmk_gpio_make_output,
867 .set = nmk_gpio_set_output,
Rabin Vincent0d2aec92010-06-16 06:10:43 +0100868 .to_irq = nmk_gpio_to_irq,
Rabin Vincentd0b543c2010-03-04 17:39:05 +0530869 .dbg_show = nmk_gpio_dbg_show,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100870 .can_sleep = 0,
871};
872
Uwe Kleine-Königfd0d67d2010-09-02 16:13:35 +0100873static int __devinit nmk_gpio_probe(struct platform_device *dev)
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100874{
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100875 struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100876 struct nmk_gpio_chip *nmk_chip;
877 struct gpio_chip *chip;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100878 struct resource *res;
Rabin Vincentaf7dc222010-05-06 11:14:17 +0100879 struct clk *clk;
Rabin Vincent33b744b2010-10-14 10:38:03 +0530880 int secondary_irq;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100881 int irq;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100882 int ret;
883
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100884 if (!pdata)
885 return -ENODEV;
886
887 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
888 if (!res) {
889 ret = -ENOENT;
890 goto out;
891 }
892
893 irq = platform_get_irq(dev, 0);
894 if (irq < 0) {
895 ret = irq;
896 goto out;
897 }
898
Rabin Vincent33b744b2010-10-14 10:38:03 +0530899 secondary_irq = platform_get_irq(dev, 1);
900 if (secondary_irq >= 0 && !pdata->get_secondary_status) {
901 ret = -EINVAL;
902 goto out;
903 }
904
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100905 if (request_mem_region(res->start, resource_size(res),
906 dev_name(&dev->dev)) == NULL) {
907 ret = -EBUSY;
908 goto out;
909 }
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100910
Rabin Vincentaf7dc222010-05-06 11:14:17 +0100911 clk = clk_get(&dev->dev, NULL);
912 if (IS_ERR(clk)) {
913 ret = PTR_ERR(clk);
914 goto out_release;
915 }
916
917 clk_enable(clk);
918
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100919 nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
920 if (!nmk_chip) {
921 ret = -ENOMEM;
Rabin Vincentaf7dc222010-05-06 11:14:17 +0100922 goto out_clk;
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100923 }
924 /*
925 * The virt address in nmk_chip->addr is in the nomadik register space,
926 * so we can simply convert the resource address, without remapping
927 */
Rabin Vincent33b744b2010-10-14 10:38:03 +0530928 nmk_chip->bank = dev->id;
Rabin Vincentaf7dc222010-05-06 11:14:17 +0100929 nmk_chip->clk = clk;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100930 nmk_chip->addr = io_p2v(res->start);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100931 nmk_chip->chip = nmk_gpio_template;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100932 nmk_chip->parent_irq = irq;
Rabin Vincent33b744b2010-10-14 10:38:03 +0530933 nmk_chip->secondary_parent_irq = secondary_irq;
934 nmk_chip->get_secondary_status = pdata->get_secondary_status;
Rabin Vincent01727e62010-12-13 12:02:40 +0530935 nmk_chip->set_ioforce = pdata->set_ioforce;
Rabin Vincentc0fcb8d2010-03-03 04:48:54 +0100936 spin_lock_init(&nmk_chip->lock);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100937
938 chip = &nmk_chip->chip;
939 chip->base = pdata->first_gpio;
Rabin Vincente493e062010-03-18 12:35:22 +0530940 chip->ngpio = pdata->num_gpio;
Rabin Vincent8d568ae2010-12-08 11:07:54 +0530941 chip->label = pdata->name ?: dev_name(&dev->dev);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100942 chip->dev = &dev->dev;
943 chip->owner = THIS_MODULE;
944
945 ret = gpiochip_add(&nmk_chip->chip);
946 if (ret)
947 goto out_free;
948
Rabin Vincent01727e62010-12-13 12:02:40 +0530949 BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
950
951 nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100952 platform_set_drvdata(dev, nmk_chip);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100953
954 nmk_gpio_init_irq(nmk_chip);
955
956 dev_info(&dev->dev, "Bits %i-%i at address %p\n",
957 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
958 return 0;
959
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100960out_free:
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100961 kfree(nmk_chip);
Rabin Vincentaf7dc222010-05-06 11:14:17 +0100962out_clk:
963 clk_disable(clk);
964 clk_put(clk);
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100965out_release:
966 release_mem_region(res->start, resource_size(res));
967out:
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100968 dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
969 pdata->first_gpio, pdata->first_gpio+31);
970 return ret;
971}
972
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100973static struct platform_driver nmk_gpio_driver = {
974 .driver = {
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100975 .owner = THIS_MODULE,
976 .name = "gpio",
Rabin Vincent5317e4d12011-02-10 09:29:53 +0530977 },
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100978 .probe = nmk_gpio_probe,
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100979};
980
981static int __init nmk_gpio_init(void)
982{
Rabin Vincent3e3c62c2010-03-03 04:52:34 +0100983 return platform_driver_register(&nmk_gpio_driver);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100984}
985
Rabin Vincent33f45ea2010-06-02 06:09:52 +0100986core_initcall(nmk_gpio_init);
Alessandro Rubini2ec1d352009-07-02 15:29:12 +0100987
988MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
989MODULE_DESCRIPTION("Nomadik GPIO Driver");
990MODULE_LICENSE("GPL");
991
992