Merge tag 'ptrace_stop-cleanup-for-v5.19' of git://git.kernel.org/pub/scm/linux/kerne...
[linux-2.6-microblaze.git] / arch / arm / mach-s3c / gpio-samsung.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 //              http://www.samsung.com/
5 //
6 // Copyright 2008 Openmoko, Inc.
7 // Copyright 2008 Simtec Electronics
8 //      Ben Dooks <ben@simtec.co.uk>
9 //      http://armlinux.simtec.co.uk/
10 //
11 // Samsung - GPIOlib support
12
13 #include <linux/kernel.h>
14 #include <linux/irq.h>
15 #include <linux/io.h>
16 #include <linux/gpio.h>
17 #include <linux/init.h>
18 #include <linux/spinlock.h>
19 #include <linux/module.h>
20 #include <linux/interrupt.h>
21 #include <linux/device.h>
22 #include <linux/ioport.h>
23 #include <linux/of.h>
24 #include <linux/slab.h>
25 #include <linux/of_address.h>
26
27 #include <asm/irq.h>
28
29 #include "irqs.h"
30 #include "map.h"
31 #include "regs-gpio.h"
32 #include "gpio-samsung.h"
33
34 #include "cpu.h"
35 #include "gpio-core.h"
36 #include "gpio-cfg.h"
37 #include "gpio-cfg-helpers.h"
38 #include "hardware-s3c24xx.h"
39 #include "pm.h"
40
41 int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
42                                 unsigned int off, samsung_gpio_pull_t pull)
43 {
44         void __iomem *reg = chip->base + 0x08;
45         int shift = off * 2;
46         u32 pup;
47
48         pup = __raw_readl(reg);
49         pup &= ~(3 << shift);
50         pup |= pull << shift;
51         __raw_writel(pup, reg);
52
53         return 0;
54 }
55
56 samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
57                                                 unsigned int off)
58 {
59         void __iomem *reg = chip->base + 0x08;
60         int shift = off * 2;
61         u32 pup = __raw_readl(reg);
62
63         pup >>= shift;
64         pup &= 0x3;
65
66         return (__force samsung_gpio_pull_t)pup;
67 }
68
69 int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
70                          unsigned int off, samsung_gpio_pull_t pull)
71 {
72         switch (pull) {
73         case S3C_GPIO_PULL_NONE:
74                 pull = 0x01;
75                 break;
76         case S3C_GPIO_PULL_UP:
77                 pull = 0x00;
78                 break;
79         case S3C_GPIO_PULL_DOWN:
80                 pull = 0x02;
81                 break;
82         }
83         return samsung_gpio_setpull_updown(chip, off, pull);
84 }
85
86 samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
87                                          unsigned int off)
88 {
89         samsung_gpio_pull_t pull;
90
91         pull = samsung_gpio_getpull_updown(chip, off);
92
93         switch (pull) {
94         case 0x00:
95                 pull = S3C_GPIO_PULL_UP;
96                 break;
97         case 0x01:
98         case 0x03:
99                 pull = S3C_GPIO_PULL_NONE;
100                 break;
101         case 0x02:
102                 pull = S3C_GPIO_PULL_DOWN;
103                 break;
104         }
105
106         return pull;
107 }
108
109 static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
110                                   unsigned int off, samsung_gpio_pull_t pull,
111                                   samsung_gpio_pull_t updown)
112 {
113         void __iomem *reg = chip->base + 0x08;
114         u32 pup = __raw_readl(reg);
115
116         if (pull == updown)
117                 pup &= ~(1 << off);
118         else if (pull == S3C_GPIO_PULL_NONE)
119                 pup |= (1 << off);
120         else
121                 return -EINVAL;
122
123         __raw_writel(pup, reg);
124         return 0;
125 }
126
127 static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
128                                                   unsigned int off,
129                                                   samsung_gpio_pull_t updown)
130 {
131         void __iomem *reg = chip->base + 0x08;
132         u32 pup = __raw_readl(reg);
133
134         pup &= (1 << off);
135         return pup ? S3C_GPIO_PULL_NONE : updown;
136 }
137
138 samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
139                                              unsigned int off)
140 {
141         return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
142 }
143
144 int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
145                              unsigned int off, samsung_gpio_pull_t pull)
146 {
147         return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
148 }
149
150 samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
151                                                unsigned int off)
152 {
153         return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
154 }
155
156 int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
157                                unsigned int off, samsung_gpio_pull_t pull)
158 {
159         return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
160 }
161
162 /*
163  * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
164  * @chip: The gpio chip that is being configured.
165  * @off: The offset for the GPIO being configured.
166  * @cfg: The configuration value to set.
167  *
168  * This helper deal with the GPIO cases where the control register
169  * has two bits of configuration per gpio, which have the following
170  * functions:
171  *      00 = input
172  *      01 = output
173  *      1x = special function
174  */
175
176 static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
177                                     unsigned int off, unsigned int cfg)
178 {
179         void __iomem *reg = chip->base;
180         unsigned int shift = off * 2;
181         u32 con;
182
183         if (samsung_gpio_is_cfg_special(cfg)) {
184                 cfg &= 0xf;
185                 if (cfg > 3)
186                         return -EINVAL;
187
188                 cfg <<= shift;
189         }
190
191         con = __raw_readl(reg);
192         con &= ~(0x3 << shift);
193         con |= cfg;
194         __raw_writel(con, reg);
195
196         return 0;
197 }
198
199 /*
200  * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
201  * @chip: The gpio chip that is being configured.
202  * @off: The offset for the GPIO being configured.
203  *
204  * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
205  * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
206  * S3C_GPIO_SPECIAL() macro.
207  */
208
209 static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
210                                              unsigned int off)
211 {
212         u32 con;
213
214         con = __raw_readl(chip->base);
215         con >>= off * 2;
216         con &= 3;
217
218         /* this conversion works for IN and OUT as well as special mode */
219         return S3C_GPIO_SPECIAL(con);
220 }
221
222 /*
223  * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
224  * @chip: The gpio chip that is being configured.
225  * @off: The offset for the GPIO being configured.
226  * @cfg: The configuration value to set.
227  *
228  * This helper deal with the GPIO cases where the control register has 4 bits
229  * of control per GPIO, generally in the form of:
230  *      0000 = Input
231  *      0001 = Output
232  *      others = Special functions (dependent on bank)
233  *
234  * Note, since the code to deal with the case where there are two control
235  * registers instead of one, we do not have a separate set of functions for
236  * each case.
237  */
238
239 static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
240                                     unsigned int off, unsigned int cfg)
241 {
242         void __iomem *reg = chip->base;
243         unsigned int shift = (off & 7) * 4;
244         u32 con;
245
246         if (off < 8 && chip->chip.ngpio > 8)
247                 reg -= 4;
248
249         if (samsung_gpio_is_cfg_special(cfg)) {
250                 cfg &= 0xf;
251                 cfg <<= shift;
252         }
253
254         con = __raw_readl(reg);
255         con &= ~(0xf << shift);
256         con |= cfg;
257         __raw_writel(con, reg);
258
259         return 0;
260 }
261
262 /*
263  * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
264  * @chip: The gpio chip that is being configured.
265  * @off: The offset for the GPIO being configured.
266  *
267  * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
268  * register setting into a value the software can use, such as could be passed
269  * to samsung_gpio_setcfg_4bit().
270  *
271  * @sa samsung_gpio_getcfg_2bit
272  */
273
274 static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
275                                          unsigned int off)
276 {
277         void __iomem *reg = chip->base;
278         unsigned int shift = (off & 7) * 4;
279         u32 con;
280
281         if (off < 8 && chip->chip.ngpio > 8)
282                 reg -= 4;
283
284         con = __raw_readl(reg);
285         con >>= shift;
286         con &= 0xf;
287
288         /* this conversion works for IN and OUT as well as special mode */
289         return S3C_GPIO_SPECIAL(con);
290 }
291
292 #ifdef CONFIG_PLAT_S3C24XX
293 /*
294  * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
295  * @chip: The gpio chip that is being configured.
296  * @off: The offset for the GPIO being configured.
297  * @cfg: The configuration value to set.
298  *
299  * This helper deal with the GPIO cases where the control register
300  * has one bit of configuration for the gpio, where setting the bit
301  * means the pin is in special function mode and unset means output.
302  */
303
304 static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
305                                      unsigned int off, unsigned int cfg)
306 {
307         void __iomem *reg = chip->base;
308         unsigned int shift = off;
309         u32 con;
310
311         if (samsung_gpio_is_cfg_special(cfg)) {
312                 cfg &= 0xf;
313
314                 /* Map output to 0, and SFN2 to 1 */
315                 cfg -= 1;
316                 if (cfg > 1)
317                         return -EINVAL;
318
319                 cfg <<= shift;
320         }
321
322         con = __raw_readl(reg);
323         con &= ~(0x1 << shift);
324         con |= cfg;
325         __raw_writel(con, reg);
326
327         return 0;
328 }
329
330 /*
331  * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
332  * @chip: The gpio chip that is being configured.
333  * @off: The offset for the GPIO being configured.
334  *
335  * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
336  * GPIO configuration value.
337  *
338  * @sa samsung_gpio_getcfg_2bit
339  * @sa samsung_gpio_getcfg_4bit
340  */
341
342 static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
343                                           unsigned int off)
344 {
345         u32 con;
346
347         con = __raw_readl(chip->base);
348         con >>= off;
349         con &= 1;
350         con++;
351
352         return S3C_GPIO_SFN(con);
353 }
354 #endif
355
356 static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
357                                            int nr_chips)
358 {
359         for (; nr_chips > 0; nr_chips--, chipcfg++) {
360                 if (!chipcfg->set_config)
361                         chipcfg->set_config = samsung_gpio_setcfg_4bit;
362                 if (!chipcfg->get_config)
363                         chipcfg->get_config = samsung_gpio_getcfg_4bit;
364                 if (!chipcfg->set_pull)
365                         chipcfg->set_pull = samsung_gpio_setpull_updown;
366                 if (!chipcfg->get_pull)
367                         chipcfg->get_pull = samsung_gpio_getpull_updown;
368         }
369 }
370
371 struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
372         .set_config     = samsung_gpio_setcfg_2bit,
373         .get_config     = samsung_gpio_getcfg_2bit,
374 };
375
376 #ifdef CONFIG_PLAT_S3C24XX
377 static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
378         .set_config     = s3c24xx_gpio_setcfg_abank,
379         .get_config     = s3c24xx_gpio_getcfg_abank,
380 };
381 #endif
382
383 static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
384         [0] = {
385                 .cfg_eint       = 0x0,
386         },
387         [1] = {
388                 .cfg_eint       = 0x3,
389         },
390         [2] = {
391                 .cfg_eint       = 0x7,
392         },
393         [3] = {
394                 .cfg_eint       = 0xF,
395         },
396         [4] = {
397                 .cfg_eint       = 0x0,
398                 .set_config     = samsung_gpio_setcfg_2bit,
399                 .get_config     = samsung_gpio_getcfg_2bit,
400         },
401         [5] = {
402                 .cfg_eint       = 0x2,
403                 .set_config     = samsung_gpio_setcfg_2bit,
404                 .get_config     = samsung_gpio_getcfg_2bit,
405         },
406         [6] = {
407                 .cfg_eint       = 0x3,
408                 .set_config     = samsung_gpio_setcfg_2bit,
409                 .get_config     = samsung_gpio_getcfg_2bit,
410         },
411         [7] = {
412                 .set_config     = samsung_gpio_setcfg_2bit,
413                 .get_config     = samsung_gpio_getcfg_2bit,
414         },
415 };
416
417 /*
418  * Default routines for controlling GPIO, based on the original S3C24XX
419  * GPIO functions which deal with the case where each gpio bank of the
420  * chip is as following:
421  *
422  * base + 0x00: Control register, 2 bits per gpio
423  *              gpio n: 2 bits starting at (2*n)
424  *              00 = input, 01 = output, others mean special-function
425  * base + 0x04: Data register, 1 bit per gpio
426  *              bit n: data bit n
427 */
428
429 static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
430 {
431         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
432         void __iomem *base = ourchip->base;
433         unsigned long flags;
434         unsigned long con;
435
436         samsung_gpio_lock(ourchip, flags);
437
438         con = __raw_readl(base + 0x00);
439         con &= ~(3 << (offset * 2));
440
441         __raw_writel(con, base + 0x00);
442
443         samsung_gpio_unlock(ourchip, flags);
444         return 0;
445 }
446
447 static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
448                                        unsigned offset, int value)
449 {
450         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
451         void __iomem *base = ourchip->base;
452         unsigned long flags;
453         unsigned long dat;
454         unsigned long con;
455
456         samsung_gpio_lock(ourchip, flags);
457
458         dat = __raw_readl(base + 0x04);
459         dat &= ~(1 << offset);
460         if (value)
461                 dat |= 1 << offset;
462         __raw_writel(dat, base + 0x04);
463
464         con = __raw_readl(base + 0x00);
465         con &= ~(3 << (offset * 2));
466         con |= 1 << (offset * 2);
467
468         __raw_writel(con, base + 0x00);
469         __raw_writel(dat, base + 0x04);
470
471         samsung_gpio_unlock(ourchip, flags);
472         return 0;
473 }
474
475 /*
476  * The samsung_gpiolib_4bit routines are to control the gpio banks where
477  * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
478  * following example:
479  *
480  * base + 0x00: Control register, 4 bits per gpio
481  *              gpio n: 4 bits starting at (4*n)
482  *              0000 = input, 0001 = output, others mean special-function
483  * base + 0x04: Data register, 1 bit per gpio
484  *              bit n: data bit n
485  *
486  * Note, since the data register is one bit per gpio and is at base + 0x4
487  * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
488  * state of the output.
489  */
490
491 static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
492                                       unsigned int offset)
493 {
494         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
495         void __iomem *base = ourchip->base;
496         unsigned long con;
497
498         con = __raw_readl(base + GPIOCON_OFF);
499         if (ourchip->bitmap_gpio_int & BIT(offset))
500                 con |= 0xf << con_4bit_shift(offset);
501         else
502                 con &= ~(0xf << con_4bit_shift(offset));
503         __raw_writel(con, base + GPIOCON_OFF);
504
505         pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
506
507         return 0;
508 }
509
510 static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
511                                        unsigned int offset, int value)
512 {
513         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
514         void __iomem *base = ourchip->base;
515         unsigned long con;
516         unsigned long dat;
517
518         con = __raw_readl(base + GPIOCON_OFF);
519         con &= ~(0xf << con_4bit_shift(offset));
520         con |= 0x1 << con_4bit_shift(offset);
521
522         dat = __raw_readl(base + GPIODAT_OFF);
523
524         if (value)
525                 dat |= 1 << offset;
526         else
527                 dat &= ~(1 << offset);
528
529         __raw_writel(dat, base + GPIODAT_OFF);
530         __raw_writel(con, base + GPIOCON_OFF);
531         __raw_writel(dat, base + GPIODAT_OFF);
532
533         pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
534
535         return 0;
536 }
537
538 /*
539  * The next set of routines are for the case where the GPIO configuration
540  * registers are 4 bits per GPIO but there is more than one register (the
541  * bank has more than 8 GPIOs.
542  *
543  * This case is the similar to the 4 bit case, but the registers are as
544  * follows:
545  *
546  * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
547  *              gpio n: 4 bits starting at (4*n)
548  *              0000 = input, 0001 = output, others mean special-function
549  * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
550  *              gpio n: 4 bits starting at (4*n)
551  *              0000 = input, 0001 = output, others mean special-function
552  * base + 0x08: Data register, 1 bit per gpio
553  *              bit n: data bit n
554  *
555  * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
556  * routines we store the 'base + 0x4' address so that these routines see
557  * the data register at ourchip->base + 0x04.
558  */
559
560 static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
561                                        unsigned int offset)
562 {
563         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
564         void __iomem *base = ourchip->base;
565         void __iomem *regcon = base;
566         unsigned long con;
567
568         if (offset > 7)
569                 offset -= 8;
570         else
571                 regcon -= 4;
572
573         con = __raw_readl(regcon);
574         con &= ~(0xf << con_4bit_shift(offset));
575         __raw_writel(con, regcon);
576
577         pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
578
579         return 0;
580 }
581
582 static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
583                                         unsigned int offset, int value)
584 {
585         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
586         void __iomem *base = ourchip->base;
587         void __iomem *regcon = base;
588         unsigned long con;
589         unsigned long dat;
590         unsigned con_offset = offset;
591
592         if (con_offset > 7)
593                 con_offset -= 8;
594         else
595                 regcon -= 4;
596
597         con = __raw_readl(regcon);
598         con &= ~(0xf << con_4bit_shift(con_offset));
599         con |= 0x1 << con_4bit_shift(con_offset);
600
601         dat = __raw_readl(base + GPIODAT_OFF);
602
603         if (value)
604                 dat |= 1 << offset;
605         else
606                 dat &= ~(1 << offset);
607
608         __raw_writel(dat, base + GPIODAT_OFF);
609         __raw_writel(con, regcon);
610         __raw_writel(dat, base + GPIODAT_OFF);
611
612         pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
613
614         return 0;
615 }
616
617 #ifdef CONFIG_PLAT_S3C24XX
618 /* The next set of routines are for the case of s3c24xx bank a */
619
620 static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
621 {
622         return -EINVAL;
623 }
624
625 static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
626                                         unsigned offset, int value)
627 {
628         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
629         void __iomem *base = ourchip->base;
630         unsigned long flags;
631         unsigned long dat;
632         unsigned long con;
633
634         local_irq_save(flags);
635
636         con = __raw_readl(base + 0x00);
637         dat = __raw_readl(base + 0x04);
638
639         dat &= ~(1 << offset);
640         if (value)
641                 dat |= 1 << offset;
642
643         __raw_writel(dat, base + 0x04);
644
645         con &= ~(1 << offset);
646
647         __raw_writel(con, base + 0x00);
648         __raw_writel(dat, base + 0x04);
649
650         local_irq_restore(flags);
651         return 0;
652 }
653 #endif
654
655 static void samsung_gpiolib_set(struct gpio_chip *chip,
656                                 unsigned offset, int value)
657 {
658         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
659         void __iomem *base = ourchip->base;
660         unsigned long flags;
661         unsigned long dat;
662
663         samsung_gpio_lock(ourchip, flags);
664
665         dat = __raw_readl(base + 0x04);
666         dat &= ~(1 << offset);
667         if (value)
668                 dat |= 1 << offset;
669         __raw_writel(dat, base + 0x04);
670
671         samsung_gpio_unlock(ourchip, flags);
672 }
673
674 static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
675 {
676         struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
677         unsigned long val;
678
679         val = __raw_readl(ourchip->base + 0x04);
680         val >>= offset;
681         val &= 1;
682
683         return val;
684 }
685
686 /*
687  * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
688  * for use with the configuration calls, and other parts of the s3c gpiolib
689  * support code.
690  *
691  * Not all s3c support code will need this, as some configurations of cpu
692  * may only support one or two different configuration options and have an
693  * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
694  * the machine support file should provide its own samsung_gpiolib_getchip()
695  * and any other necessary functions.
696  */
697
698 #ifdef CONFIG_S3C_GPIO_TRACK
699 struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
700
701 static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
702 {
703         unsigned int gpn;
704         int i;
705
706         gpn = chip->chip.base;
707         for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
708                 BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
709                 s3c_gpios[gpn] = chip;
710         }
711 }
712 #endif /* CONFIG_S3C_GPIO_TRACK */
713
714 /*
715  * samsung_gpiolib_add() - add the Samsung gpio_chip.
716  * @chip: The chip to register
717  *
718  * This is a wrapper to gpiochip_add() that takes our specific gpio chip
719  * information and makes the necessary alterations for the platform and
720  * notes the information for use with the configuration systems and any
721  * other parts of the system.
722  */
723
724 static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
725 {
726         struct gpio_chip *gc = &chip->chip;
727         int ret;
728
729         BUG_ON(!chip->base);
730         BUG_ON(!gc->label);
731         BUG_ON(!gc->ngpio);
732
733         spin_lock_init(&chip->lock);
734
735         if (!gc->direction_input)
736                 gc->direction_input = samsung_gpiolib_2bit_input;
737         if (!gc->direction_output)
738                 gc->direction_output = samsung_gpiolib_2bit_output;
739         if (!gc->set)
740                 gc->set = samsung_gpiolib_set;
741         if (!gc->get)
742                 gc->get = samsung_gpiolib_get;
743
744 #ifdef CONFIG_PM
745         if (chip->pm != NULL) {
746                 if (!chip->pm->save || !chip->pm->resume)
747                         pr_err("gpio: %s has missing PM functions\n",
748                                gc->label);
749         } else
750                 pr_err("gpio: %s has no PM function\n", gc->label);
751 #endif
752
753         /* gpiochip_add() prints own failure message on error. */
754         ret = gpiochip_add_data(gc, chip);
755         if (ret >= 0)
756                 s3c_gpiolib_track(chip);
757 }
758
759 static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
760                                              int nr_chips, void __iomem *base)
761 {
762         int i;
763         struct gpio_chip *gc = &chip->chip;
764
765         for (i = 0 ; i < nr_chips; i++, chip++) {
766                 /* skip banks not present on SoC */
767                 if (chip->chip.base >= S3C_GPIO_END)
768                         continue;
769
770                 if (!chip->config)
771                         chip->config = &s3c24xx_gpiocfg_default;
772                 if (!chip->pm)
773                         chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
774                 if ((base != NULL) && (chip->base == NULL))
775                         chip->base = base + ((i) * 0x10);
776
777                 if (!gc->direction_input)
778                         gc->direction_input = samsung_gpiolib_2bit_input;
779                 if (!gc->direction_output)
780                         gc->direction_output = samsung_gpiolib_2bit_output;
781
782                 samsung_gpiolib_add(chip);
783         }
784 }
785
786 static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
787                                                   int nr_chips, void __iomem *base,
788                                                   unsigned int offset)
789 {
790         int i;
791
792         for (i = 0 ; i < nr_chips; i++, chip++) {
793                 chip->chip.direction_input = samsung_gpiolib_2bit_input;
794                 chip->chip.direction_output = samsung_gpiolib_2bit_output;
795
796                 if (!chip->config)
797                         chip->config = &samsung_gpio_cfgs[7];
798                 if (!chip->pm)
799                         chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
800                 if ((base != NULL) && (chip->base == NULL))
801                         chip->base = base + ((i) * offset);
802
803                 samsung_gpiolib_add(chip);
804         }
805 }
806
807 /*
808  * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
809  * @chip: The gpio chip that is being configured.
810  * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
811  *
812  * This helper deal with the GPIO cases where the control register has 4 bits
813  * of control per GPIO, generally in the form of:
814  * 0000 = Input
815  * 0001 = Output
816  * others = Special functions (dependent on bank)
817  *
818  * Note, since the code to deal with the case where there are two control
819  * registers instead of one, we do not have a separate set of function
820  * (samsung_gpiolib_add_4bit2_chips)for each case.
821  */
822
823 static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
824                                                   int nr_chips, void __iomem *base)
825 {
826         int i;
827
828         for (i = 0 ; i < nr_chips; i++, chip++) {
829                 chip->chip.direction_input = samsung_gpiolib_4bit_input;
830                 chip->chip.direction_output = samsung_gpiolib_4bit_output;
831
832                 if (!chip->config)
833                         chip->config = &samsung_gpio_cfgs[2];
834                 if (!chip->pm)
835                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
836                 if ((base != NULL) && (chip->base == NULL))
837                         chip->base = base + ((i) * 0x20);
838
839                 chip->bitmap_gpio_int = 0;
840
841                 samsung_gpiolib_add(chip);
842         }
843 }
844
845 static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
846                                                    int nr_chips)
847 {
848         for (; nr_chips > 0; nr_chips--, chip++) {
849                 chip->chip.direction_input = samsung_gpiolib_4bit2_input;
850                 chip->chip.direction_output = samsung_gpiolib_4bit2_output;
851
852                 if (!chip->config)
853                         chip->config = &samsung_gpio_cfgs[2];
854                 if (!chip->pm)
855                         chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
856
857                 samsung_gpiolib_add(chip);
858         }
859 }
860
861 int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
862 {
863         struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
864
865         return samsung_chip->irq_base + offset;
866 }
867
868 #ifdef CONFIG_PLAT_S3C24XX
869 static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
870 {
871         if (offset < 4) {
872                 if (soc_is_s3c2412())
873                         return IRQ_EINT0_2412 + offset;
874                 else
875                         return IRQ_EINT0 + offset;
876         }
877
878         if (offset < 8)
879                 return IRQ_EINT4 + offset - 4;
880
881         return -EINVAL;
882 }
883 #endif
884
885 #ifdef CONFIG_ARCH_S3C64XX
886 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
887 {
888         return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
889 }
890
891 static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
892 {
893         return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
894 }
895 #endif
896
897 struct samsung_gpio_chip s3c24xx_gpios[] = {
898 #ifdef CONFIG_PLAT_S3C24XX
899         {
900                 .config = &s3c24xx_gpiocfg_banka,
901                 .chip   = {
902                         .base                   = S3C2410_GPA(0),
903                         .owner                  = THIS_MODULE,
904                         .label                  = "GPIOA",
905                         .ngpio                  = 27,
906                         .direction_input        = s3c24xx_gpiolib_banka_input,
907                         .direction_output       = s3c24xx_gpiolib_banka_output,
908                 },
909         }, {
910                 .chip   = {
911                         .base   = S3C2410_GPB(0),
912                         .owner  = THIS_MODULE,
913                         .label  = "GPIOB",
914                         .ngpio  = 11,
915                 },
916         }, {
917                 .chip   = {
918                         .base   = S3C2410_GPC(0),
919                         .owner  = THIS_MODULE,
920                         .label  = "GPIOC",
921                         .ngpio  = 16,
922                 },
923         }, {
924                 .chip   = {
925                         .base   = S3C2410_GPD(0),
926                         .owner  = THIS_MODULE,
927                         .label  = "GPIOD",
928                         .ngpio  = 16,
929                 },
930         }, {
931                 .chip   = {
932                         .base   = S3C2410_GPE(0),
933                         .label  = "GPIOE",
934                         .owner  = THIS_MODULE,
935                         .ngpio  = 16,
936                 },
937         }, {
938                 .chip   = {
939                         .base   = S3C2410_GPF(0),
940                         .owner  = THIS_MODULE,
941                         .label  = "GPIOF",
942                         .ngpio  = 8,
943                         .to_irq = s3c24xx_gpiolib_fbank_to_irq,
944                 },
945         }, {
946                 .irq_base = IRQ_EINT8,
947                 .chip   = {
948                         .base   = S3C2410_GPG(0),
949                         .owner  = THIS_MODULE,
950                         .label  = "GPIOG",
951                         .ngpio  = 16,
952                         .to_irq = samsung_gpiolib_to_irq,
953                 },
954         }, {
955                 .chip   = {
956                         .base   = S3C2410_GPH(0),
957                         .owner  = THIS_MODULE,
958                         .label  = "GPIOH",
959                         .ngpio  = 15,
960                 },
961         },
962                 /* GPIOS for the S3C2443 and later devices. */
963         {
964                 .base   = S3C2440_GPJCON,
965                 .chip   = {
966                         .base   = S3C2410_GPJ(0),
967                         .owner  = THIS_MODULE,
968                         .label  = "GPIOJ",
969                         .ngpio  = 16,
970                 },
971         }, {
972                 .base   = S3C2443_GPKCON,
973                 .chip   = {
974                         .base   = S3C2410_GPK(0),
975                         .owner  = THIS_MODULE,
976                         .label  = "GPIOK",
977                         .ngpio  = 16,
978                 },
979         }, {
980                 .base   = S3C2443_GPLCON,
981                 .chip   = {
982                         .base   = S3C2410_GPL(0),
983                         .owner  = THIS_MODULE,
984                         .label  = "GPIOL",
985                         .ngpio  = 15,
986                 },
987         }, {
988                 .base   = S3C2443_GPMCON,
989                 .chip   = {
990                         .base   = S3C2410_GPM(0),
991                         .owner  = THIS_MODULE,
992                         .label  = "GPIOM",
993                         .ngpio  = 2,
994                 },
995         },
996 #endif
997 };
998
999 /*
1000  * GPIO bank summary:
1001  *
1002  * Bank GPIOs   Style   SlpCon  ExtInt Group
1003  * A    8       4Bit    Yes     1
1004  * B    7       4Bit    Yes     1
1005  * C    8       4Bit    Yes     2
1006  * D    5       4Bit    Yes     3
1007  * E    5       4Bit    Yes     None
1008  * F    16      2Bit    Yes     4 [1]
1009  * G    7       4Bit    Yes     5
1010  * H    10      4Bit[2] Yes     6
1011  * I    16      2Bit    Yes     None
1012  * J    12      2Bit    Yes     None
1013  * K    16      4Bit[2] No      None
1014  * L    15      4Bit[2] No      None
1015  * M    6       4Bit    No      IRQ_EINT
1016  * N    16      2Bit    No      IRQ_EINT
1017  * O    16      2Bit    Yes     7
1018  * P    15      2Bit    Yes     8
1019  * Q    9       2Bit    Yes     9
1020  *
1021  * [1] BANKF pins 14,15 do not form part of the external interrupt sources
1022  * [2] BANK has two control registers, GPxCON0 and GPxCON1
1023  */
1024
1025 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
1026 #ifdef CONFIG_ARCH_S3C64XX
1027         {
1028                 .chip   = {
1029                         .base   = S3C64XX_GPA(0),
1030                         .ngpio  = S3C64XX_GPIO_A_NR,
1031                         .label  = "GPA",
1032                 },
1033         }, {
1034                 .chip   = {
1035                         .base   = S3C64XX_GPB(0),
1036                         .ngpio  = S3C64XX_GPIO_B_NR,
1037                         .label  = "GPB",
1038                 },
1039         }, {
1040                 .chip   = {
1041                         .base   = S3C64XX_GPC(0),
1042                         .ngpio  = S3C64XX_GPIO_C_NR,
1043                         .label  = "GPC",
1044                 },
1045         }, {
1046                 .chip   = {
1047                         .base   = S3C64XX_GPD(0),
1048                         .ngpio  = S3C64XX_GPIO_D_NR,
1049                         .label  = "GPD",
1050                 },
1051         }, {
1052                 .config = &samsung_gpio_cfgs[0],
1053                 .chip   = {
1054                         .base   = S3C64XX_GPE(0),
1055                         .ngpio  = S3C64XX_GPIO_E_NR,
1056                         .label  = "GPE",
1057                 },
1058         }, {
1059                 .base   = S3C64XX_GPG_BASE,
1060                 .chip   = {
1061                         .base   = S3C64XX_GPG(0),
1062                         .ngpio  = S3C64XX_GPIO_G_NR,
1063                         .label  = "GPG",
1064                 },
1065         }, {
1066                 .base   = S3C64XX_GPM_BASE,
1067                 .config = &samsung_gpio_cfgs[1],
1068                 .chip   = {
1069                         .base   = S3C64XX_GPM(0),
1070                         .ngpio  = S3C64XX_GPIO_M_NR,
1071                         .label  = "GPM",
1072                         .to_irq = s3c64xx_gpiolib_mbank_to_irq,
1073                 },
1074         },
1075 #endif
1076 };
1077
1078 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
1079 #ifdef CONFIG_ARCH_S3C64XX
1080         {
1081                 .base   = S3C64XX_GPH_BASE + 0x4,
1082                 .chip   = {
1083                         .base   = S3C64XX_GPH(0),
1084                         .ngpio  = S3C64XX_GPIO_H_NR,
1085                         .label  = "GPH",
1086                 },
1087         }, {
1088                 .base   = S3C64XX_GPK_BASE + 0x4,
1089                 .config = &samsung_gpio_cfgs[0],
1090                 .chip   = {
1091                         .base   = S3C64XX_GPK(0),
1092                         .ngpio  = S3C64XX_GPIO_K_NR,
1093                         .label  = "GPK",
1094                 },
1095         }, {
1096                 .base   = S3C64XX_GPL_BASE + 0x4,
1097                 .config = &samsung_gpio_cfgs[1],
1098                 .chip   = {
1099                         .base   = S3C64XX_GPL(0),
1100                         .ngpio  = S3C64XX_GPIO_L_NR,
1101                         .label  = "GPL",
1102                         .to_irq = s3c64xx_gpiolib_lbank_to_irq,
1103                 },
1104         },
1105 #endif
1106 };
1107
1108 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
1109 #ifdef CONFIG_ARCH_S3C64XX
1110         {
1111                 .base   = S3C64XX_GPF_BASE,
1112                 .config = &samsung_gpio_cfgs[6],
1113                 .chip   = {
1114                         .base   = S3C64XX_GPF(0),
1115                         .ngpio  = S3C64XX_GPIO_F_NR,
1116                         .label  = "GPF",
1117                 },
1118         }, {
1119                 .config = &samsung_gpio_cfgs[7],
1120                 .chip   = {
1121                         .base   = S3C64XX_GPI(0),
1122                         .ngpio  = S3C64XX_GPIO_I_NR,
1123                         .label  = "GPI",
1124                 },
1125         }, {
1126                 .config = &samsung_gpio_cfgs[7],
1127                 .chip   = {
1128                         .base   = S3C64XX_GPJ(0),
1129                         .ngpio  = S3C64XX_GPIO_J_NR,
1130                         .label  = "GPJ",
1131                 },
1132         }, {
1133                 .config = &samsung_gpio_cfgs[6],
1134                 .chip   = {
1135                         .base   = S3C64XX_GPO(0),
1136                         .ngpio  = S3C64XX_GPIO_O_NR,
1137                         .label  = "GPO",
1138                 },
1139         }, {
1140                 .config = &samsung_gpio_cfgs[6],
1141                 .chip   = {
1142                         .base   = S3C64XX_GPP(0),
1143                         .ngpio  = S3C64XX_GPIO_P_NR,
1144                         .label  = "GPP",
1145                 },
1146         }, {
1147                 .config = &samsung_gpio_cfgs[6],
1148                 .chip   = {
1149                         .base   = S3C64XX_GPQ(0),
1150                         .ngpio  = S3C64XX_GPIO_Q_NR,
1151                         .label  = "GPQ",
1152                 },
1153         }, {
1154                 .base   = S3C64XX_GPN_BASE,
1155                 .irq_base = IRQ_EINT(0),
1156                 .config = &samsung_gpio_cfgs[5],
1157                 .chip   = {
1158                         .base   = S3C64XX_GPN(0),
1159                         .ngpio  = S3C64XX_GPIO_N_NR,
1160                         .label  = "GPN",
1161                         .to_irq = samsung_gpiolib_to_irq,
1162                 },
1163         },
1164 #endif
1165 };
1166
1167 /* TODO: cleanup soc_is_* */
1168 static __init int samsung_gpiolib_init(void)
1169 {
1170         /*
1171          * Currently there are two drivers that can provide GPIO support for
1172          * Samsung SoCs. For device tree enabled platforms, the new
1173          * pinctrl-samsung driver is used, providing both GPIO and pin control
1174          * interfaces. For legacy (non-DT) platforms this driver is used.
1175          */
1176         if (of_have_populated_dt())
1177                 return 0;
1178
1179         if (soc_is_s3c24xx()) {
1180                 samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
1181                                 ARRAY_SIZE(samsung_gpio_cfgs));
1182                 s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
1183                                 ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
1184         } else if (soc_is_s3c64xx()) {
1185                 samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
1186                                 ARRAY_SIZE(samsung_gpio_cfgs));
1187                 samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
1188                                 ARRAY_SIZE(s3c64xx_gpios_2bit),
1189                                 S3C64XX_VA_GPIO + 0xE0, 0x20);
1190                 samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
1191                                 ARRAY_SIZE(s3c64xx_gpios_4bit),
1192                                 S3C64XX_VA_GPIO);
1193                 samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
1194                                 ARRAY_SIZE(s3c64xx_gpios_4bit2));
1195         }
1196
1197         return 0;
1198 }
1199 core_initcall(samsung_gpiolib_init);
1200
1201 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
1202 {
1203         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
1204         unsigned long flags;
1205         int offset;
1206         int ret;
1207
1208         if (!chip)
1209                 return -EINVAL;
1210
1211         offset = pin - chip->chip.base;
1212
1213         samsung_gpio_lock(chip, flags);
1214         ret = samsung_gpio_do_setcfg(chip, offset, config);
1215         samsung_gpio_unlock(chip, flags);
1216
1217         return ret;
1218 }
1219 EXPORT_SYMBOL(s3c_gpio_cfgpin);
1220
1221 int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
1222                           unsigned int cfg)
1223 {
1224         int ret;
1225
1226         for (; nr > 0; nr--, start++) {
1227                 ret = s3c_gpio_cfgpin(start, cfg);
1228                 if (ret != 0)
1229                         return ret;
1230         }
1231
1232         return 0;
1233 }
1234 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
1235
1236 int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
1237                           unsigned int cfg, samsung_gpio_pull_t pull)
1238 {
1239         int ret;
1240
1241         for (; nr > 0; nr--, start++) {
1242                 s3c_gpio_setpull(start, pull);
1243                 ret = s3c_gpio_cfgpin(start, cfg);
1244                 if (ret != 0)
1245                         return ret;
1246         }
1247
1248         return 0;
1249 }
1250 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
1251
1252 unsigned s3c_gpio_getcfg(unsigned int pin)
1253 {
1254         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
1255         unsigned long flags;
1256         unsigned ret = 0;
1257         int offset;
1258
1259         if (chip) {
1260                 offset = pin - chip->chip.base;
1261
1262                 samsung_gpio_lock(chip, flags);
1263                 ret = samsung_gpio_do_getcfg(chip, offset);
1264                 samsung_gpio_unlock(chip, flags);
1265         }
1266
1267         return ret;
1268 }
1269 EXPORT_SYMBOL(s3c_gpio_getcfg);
1270
1271 int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
1272 {
1273         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
1274         unsigned long flags;
1275         int offset, ret;
1276
1277         if (!chip)
1278                 return -EINVAL;
1279
1280         offset = pin - chip->chip.base;
1281
1282         samsung_gpio_lock(chip, flags);
1283         ret = samsung_gpio_do_setpull(chip, offset, pull);
1284         samsung_gpio_unlock(chip, flags);
1285
1286         return ret;
1287 }
1288 EXPORT_SYMBOL(s3c_gpio_setpull);
1289
1290 samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
1291 {
1292         struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
1293         unsigned long flags;
1294         int offset;
1295         u32 pup = 0;
1296
1297         if (chip) {
1298                 offset = pin - chip->chip.base;
1299
1300                 samsung_gpio_lock(chip, flags);
1301                 pup = samsung_gpio_do_getpull(chip, offset);
1302                 samsung_gpio_unlock(chip, flags);
1303         }
1304
1305         return (__force samsung_gpio_pull_t)pup;
1306 }
1307 EXPORT_SYMBOL(s3c_gpio_getpull);
1308
1309 #ifdef CONFIG_PLAT_S3C24XX
1310 unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
1311 {
1312         unsigned long flags;
1313         unsigned long misccr;
1314
1315         local_irq_save(flags);
1316         misccr = __raw_readl(S3C24XX_MISCCR);
1317         misccr &= ~clear;
1318         misccr ^= change;
1319         __raw_writel(misccr, S3C24XX_MISCCR);
1320         local_irq_restore(flags);
1321
1322         return misccr;
1323 }
1324 EXPORT_SYMBOL(s3c2410_modify_misccr);
1325 #endif