xref: /linux/arch/arm/mach-s3c/gpio-samsung.c (revision e7d759f31ca295d589f7420719c311870bb3166f)
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 "pm.h"
39 
40 static int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
41 				unsigned int off, samsung_gpio_pull_t pull)
42 {
43 	void __iomem *reg = chip->base + 0x08;
44 	int shift = off * 2;
45 	u32 pup;
46 
47 	pup = __raw_readl(reg);
48 	pup &= ~(3 << shift);
49 	pup |= pull << shift;
50 	__raw_writel(pup, reg);
51 
52 	return 0;
53 }
54 
55 static samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
56 						unsigned int off)
57 {
58 	void __iomem *reg = chip->base + 0x08;
59 	int shift = off * 2;
60 	u32 pup = __raw_readl(reg);
61 
62 	pup >>= shift;
63 	pup &= 0x3;
64 
65 	return (__force samsung_gpio_pull_t)pup;
66 }
67 
68 static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
69 				    unsigned int off, unsigned int cfg)
70 {
71 	void __iomem *reg = chip->base;
72 	unsigned int shift = off * 2;
73 	u32 con;
74 
75 	if (samsung_gpio_is_cfg_special(cfg)) {
76 		cfg &= 0xf;
77 		if (cfg > 3)
78 			return -EINVAL;
79 
80 		cfg <<= shift;
81 	}
82 
83 	con = __raw_readl(reg);
84 	con &= ~(0x3 << shift);
85 	con |= cfg;
86 	__raw_writel(con, reg);
87 
88 	return 0;
89 }
90 
91 /*
92  * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
93  * @chip: The gpio chip that is being configured.
94  * @off: The offset for the GPIO being configured.
95  *
96  * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
97  * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
98  * S3C_GPIO_SPECIAL() macro.
99  */
100 
101 static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
102 					     unsigned int off)
103 {
104 	u32 con;
105 
106 	con = __raw_readl(chip->base);
107 	con >>= off * 2;
108 	con &= 3;
109 
110 	/* this conversion works for IN and OUT as well as special mode */
111 	return S3C_GPIO_SPECIAL(con);
112 }
113 
114 /*
115  * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
116  * @chip: The gpio chip that is being configured.
117  * @off: The offset for the GPIO being configured.
118  * @cfg: The configuration value to set.
119  *
120  * This helper deal with the GPIO cases where the control register has 4 bits
121  * of control per GPIO, generally in the form of:
122  *	0000 = Input
123  *	0001 = Output
124  *	others = Special functions (dependent on bank)
125  *
126  * Note, since the code to deal with the case where there are two control
127  * registers instead of one, we do not have a separate set of functions for
128  * each case.
129  */
130 
131 static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
132 				    unsigned int off, unsigned int cfg)
133 {
134 	void __iomem *reg = chip->base;
135 	unsigned int shift = (off & 7) * 4;
136 	u32 con;
137 
138 	if (off < 8 && chip->chip.ngpio > 8)
139 		reg -= 4;
140 
141 	if (samsung_gpio_is_cfg_special(cfg)) {
142 		cfg &= 0xf;
143 		cfg <<= shift;
144 	}
145 
146 	con = __raw_readl(reg);
147 	con &= ~(0xf << shift);
148 	con |= cfg;
149 	__raw_writel(con, reg);
150 
151 	return 0;
152 }
153 
154 /*
155  * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
156  * @chip: The gpio chip that is being configured.
157  * @off: The offset for the GPIO being configured.
158  *
159  * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
160  * register setting into a value the software can use, such as could be passed
161  * to samsung_gpio_setcfg_4bit().
162  *
163  * @sa samsung_gpio_getcfg_2bit
164  */
165 
166 static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
167 					 unsigned int off)
168 {
169 	void __iomem *reg = chip->base;
170 	unsigned int shift = (off & 7) * 4;
171 	u32 con;
172 
173 	if (off < 8 && chip->chip.ngpio > 8)
174 		reg -= 4;
175 
176 	con = __raw_readl(reg);
177 	con >>= shift;
178 	con &= 0xf;
179 
180 	/* this conversion works for IN and OUT as well as special mode */
181 	return S3C_GPIO_SPECIAL(con);
182 }
183 
184 static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
185 					   int nr_chips)
186 {
187 	for (; nr_chips > 0; nr_chips--, chipcfg++) {
188 		if (!chipcfg->set_config)
189 			chipcfg->set_config = samsung_gpio_setcfg_4bit;
190 		if (!chipcfg->get_config)
191 			chipcfg->get_config = samsung_gpio_getcfg_4bit;
192 		if (!chipcfg->set_pull)
193 			chipcfg->set_pull = samsung_gpio_setpull_updown;
194 		if (!chipcfg->get_pull)
195 			chipcfg->get_pull = samsung_gpio_getpull_updown;
196 	}
197 }
198 
199 static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
200 	[0] = {
201 		.cfg_eint	= 0x0,
202 	},
203 	[1] = {
204 		.cfg_eint	= 0x3,
205 	},
206 	[2] = {
207 		.cfg_eint	= 0x7,
208 	},
209 	[3] = {
210 		.cfg_eint	= 0xF,
211 	},
212 	[4] = {
213 		.cfg_eint	= 0x0,
214 		.set_config	= samsung_gpio_setcfg_2bit,
215 		.get_config	= samsung_gpio_getcfg_2bit,
216 	},
217 	[5] = {
218 		.cfg_eint	= 0x2,
219 		.set_config	= samsung_gpio_setcfg_2bit,
220 		.get_config	= samsung_gpio_getcfg_2bit,
221 	},
222 	[6] = {
223 		.cfg_eint	= 0x3,
224 		.set_config	= samsung_gpio_setcfg_2bit,
225 		.get_config	= samsung_gpio_getcfg_2bit,
226 	},
227 	[7] = {
228 		.set_config	= samsung_gpio_setcfg_2bit,
229 		.get_config	= samsung_gpio_getcfg_2bit,
230 	},
231 };
232 
233 /*
234  * Default routines for controlling GPIO, based on the original S3C24XX
235  * GPIO functions which deal with the case where each gpio bank of the
236  * chip is as following:
237  *
238  * base + 0x00: Control register, 2 bits per gpio
239  *	        gpio n: 2 bits starting at (2*n)
240  *		00 = input, 01 = output, others mean special-function
241  * base + 0x04: Data register, 1 bit per gpio
242  *		bit n: data bit n
243 */
244 
245 static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
246 {
247 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
248 	void __iomem *base = ourchip->base;
249 	unsigned long flags;
250 	unsigned long con;
251 
252 	samsung_gpio_lock(ourchip, flags);
253 
254 	con = __raw_readl(base + 0x00);
255 	con &= ~(3 << (offset * 2));
256 
257 	__raw_writel(con, base + 0x00);
258 
259 	samsung_gpio_unlock(ourchip, flags);
260 	return 0;
261 }
262 
263 static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
264 				       unsigned offset, int value)
265 {
266 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
267 	void __iomem *base = ourchip->base;
268 	unsigned long flags;
269 	unsigned long dat;
270 	unsigned long con;
271 
272 	samsung_gpio_lock(ourchip, flags);
273 
274 	dat = __raw_readl(base + 0x04);
275 	dat &= ~(1 << offset);
276 	if (value)
277 		dat |= 1 << offset;
278 	__raw_writel(dat, base + 0x04);
279 
280 	con = __raw_readl(base + 0x00);
281 	con &= ~(3 << (offset * 2));
282 	con |= 1 << (offset * 2);
283 
284 	__raw_writel(con, base + 0x00);
285 	__raw_writel(dat, base + 0x04);
286 
287 	samsung_gpio_unlock(ourchip, flags);
288 	return 0;
289 }
290 
291 /*
292  * The samsung_gpiolib_4bit routines are to control the gpio banks where
293  * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
294  * following example:
295  *
296  * base + 0x00: Control register, 4 bits per gpio
297  *		gpio n: 4 bits starting at (4*n)
298  *		0000 = input, 0001 = output, others mean special-function
299  * base + 0x04: Data register, 1 bit per gpio
300  *		bit n: data bit n
301  *
302  * Note, since the data register is one bit per gpio and is at base + 0x4
303  * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
304  * state of the output.
305  */
306 
307 static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
308 				      unsigned int offset)
309 {
310 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
311 	void __iomem *base = ourchip->base;
312 	unsigned long con;
313 
314 	con = __raw_readl(base + GPIOCON_OFF);
315 	if (ourchip->bitmap_gpio_int & BIT(offset))
316 		con |= 0xf << con_4bit_shift(offset);
317 	else
318 		con &= ~(0xf << con_4bit_shift(offset));
319 	__raw_writel(con, base + GPIOCON_OFF);
320 
321 	pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
322 
323 	return 0;
324 }
325 
326 static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
327 				       unsigned int offset, int value)
328 {
329 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
330 	void __iomem *base = ourchip->base;
331 	unsigned long con;
332 	unsigned long dat;
333 
334 	con = __raw_readl(base + GPIOCON_OFF);
335 	con &= ~(0xf << con_4bit_shift(offset));
336 	con |= 0x1 << con_4bit_shift(offset);
337 
338 	dat = __raw_readl(base + GPIODAT_OFF);
339 
340 	if (value)
341 		dat |= 1 << offset;
342 	else
343 		dat &= ~(1 << offset);
344 
345 	__raw_writel(dat, base + GPIODAT_OFF);
346 	__raw_writel(con, base + GPIOCON_OFF);
347 	__raw_writel(dat, base + GPIODAT_OFF);
348 
349 	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
350 
351 	return 0;
352 }
353 
354 /*
355  * The next set of routines are for the case where the GPIO configuration
356  * registers are 4 bits per GPIO but there is more than one register (the
357  * bank has more than 8 GPIOs.
358  *
359  * This case is the similar to the 4 bit case, but the registers are as
360  * follows:
361  *
362  * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
363  *		gpio n: 4 bits starting at (4*n)
364  *		0000 = input, 0001 = output, others mean special-function
365  * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
366  *		gpio n: 4 bits starting at (4*n)
367  *		0000 = input, 0001 = output, others mean special-function
368  * base + 0x08: Data register, 1 bit per gpio
369  *		bit n: data bit n
370  *
371  * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
372  * routines we store the 'base + 0x4' address so that these routines see
373  * the data register at ourchip->base + 0x04.
374  */
375 
376 static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
377 				       unsigned int offset)
378 {
379 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
380 	void __iomem *base = ourchip->base;
381 	void __iomem *regcon = base;
382 	unsigned long con;
383 
384 	if (offset > 7)
385 		offset -= 8;
386 	else
387 		regcon -= 4;
388 
389 	con = __raw_readl(regcon);
390 	con &= ~(0xf << con_4bit_shift(offset));
391 	__raw_writel(con, regcon);
392 
393 	pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
394 
395 	return 0;
396 }
397 
398 static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
399 					unsigned int offset, int value)
400 {
401 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
402 	void __iomem *base = ourchip->base;
403 	void __iomem *regcon = base;
404 	unsigned long con;
405 	unsigned long dat;
406 	unsigned con_offset = offset;
407 
408 	if (con_offset > 7)
409 		con_offset -= 8;
410 	else
411 		regcon -= 4;
412 
413 	con = __raw_readl(regcon);
414 	con &= ~(0xf << con_4bit_shift(con_offset));
415 	con |= 0x1 << con_4bit_shift(con_offset);
416 
417 	dat = __raw_readl(base + GPIODAT_OFF);
418 
419 	if (value)
420 		dat |= 1 << offset;
421 	else
422 		dat &= ~(1 << offset);
423 
424 	__raw_writel(dat, base + GPIODAT_OFF);
425 	__raw_writel(con, regcon);
426 	__raw_writel(dat, base + GPIODAT_OFF);
427 
428 	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
429 
430 	return 0;
431 }
432 
433 static void samsung_gpiolib_set(struct gpio_chip *chip,
434 				unsigned offset, int value)
435 {
436 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
437 	void __iomem *base = ourchip->base;
438 	unsigned long flags;
439 	unsigned long dat;
440 
441 	samsung_gpio_lock(ourchip, flags);
442 
443 	dat = __raw_readl(base + 0x04);
444 	dat &= ~(1 << offset);
445 	if (value)
446 		dat |= 1 << offset;
447 	__raw_writel(dat, base + 0x04);
448 
449 	samsung_gpio_unlock(ourchip, flags);
450 }
451 
452 static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
453 {
454 	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
455 	unsigned long val;
456 
457 	val = __raw_readl(ourchip->base + 0x04);
458 	val >>= offset;
459 	val &= 1;
460 
461 	return val;
462 }
463 
464 /*
465  * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
466  * for use with the configuration calls, and other parts of the s3c gpiolib
467  * support code.
468  *
469  * Not all s3c support code will need this, as some configurations of cpu
470  * may only support one or two different configuration options and have an
471  * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
472  * the machine support file should provide its own samsung_gpiolib_getchip()
473  * and any other necessary functions.
474  */
475 
476 #ifdef CONFIG_S3C_GPIO_TRACK
477 struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
478 
479 static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
480 {
481 	unsigned int gpn;
482 	int i;
483 
484 	gpn = chip->chip.base;
485 	for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
486 		BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
487 		s3c_gpios[gpn] = chip;
488 	}
489 }
490 #endif /* CONFIG_S3C_GPIO_TRACK */
491 
492 /*
493  * samsung_gpiolib_add() - add the Samsung gpio_chip.
494  * @chip: The chip to register
495  *
496  * This is a wrapper to gpiochip_add() that takes our specific gpio chip
497  * information and makes the necessary alterations for the platform and
498  * notes the information for use with the configuration systems and any
499  * other parts of the system.
500  */
501 
502 static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
503 {
504 	struct gpio_chip *gc = &chip->chip;
505 	int ret;
506 
507 	BUG_ON(!chip->base);
508 	BUG_ON(!gc->label);
509 	BUG_ON(!gc->ngpio);
510 
511 	spin_lock_init(&chip->lock);
512 
513 	if (!gc->direction_input)
514 		gc->direction_input = samsung_gpiolib_2bit_input;
515 	if (!gc->direction_output)
516 		gc->direction_output = samsung_gpiolib_2bit_output;
517 	if (!gc->set)
518 		gc->set = samsung_gpiolib_set;
519 	if (!gc->get)
520 		gc->get = samsung_gpiolib_get;
521 
522 #ifdef CONFIG_PM
523 	if (chip->pm != NULL) {
524 		if (!chip->pm->save || !chip->pm->resume)
525 			pr_err("gpio: %s has missing PM functions\n",
526 			       gc->label);
527 	} else
528 		pr_err("gpio: %s has no PM function\n", gc->label);
529 #endif
530 
531 	/* gpiochip_add() prints own failure message on error. */
532 	ret = gpiochip_add_data(gc, chip);
533 	if (ret >= 0)
534 		s3c_gpiolib_track(chip);
535 }
536 
537 static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
538 						  int nr_chips, void __iomem *base,
539 						  unsigned int offset)
540 {
541 	int i;
542 
543 	for (i = 0 ; i < nr_chips; i++, chip++) {
544 		chip->chip.direction_input = samsung_gpiolib_2bit_input;
545 		chip->chip.direction_output = samsung_gpiolib_2bit_output;
546 
547 		if (!chip->config)
548 			chip->config = &samsung_gpio_cfgs[7];
549 		if (!chip->pm)
550 			chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
551 		if ((base != NULL) && (chip->base == NULL))
552 			chip->base = base + ((i) * offset);
553 
554 		samsung_gpiolib_add(chip);
555 	}
556 }
557 
558 /*
559  * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
560  * @chip: The gpio chip that is being configured.
561  * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
562  *
563  * This helper deal with the GPIO cases where the control register has 4 bits
564  * of control per GPIO, generally in the form of:
565  * 0000 = Input
566  * 0001 = Output
567  * others = Special functions (dependent on bank)
568  *
569  * Note, since the code to deal with the case where there are two control
570  * registers instead of one, we do not have a separate set of function
571  * (samsung_gpiolib_add_4bit2_chips)for each case.
572  */
573 
574 static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
575 						  int nr_chips, void __iomem *base)
576 {
577 	int i;
578 
579 	for (i = 0 ; i < nr_chips; i++, chip++) {
580 		chip->chip.direction_input = samsung_gpiolib_4bit_input;
581 		chip->chip.direction_output = samsung_gpiolib_4bit_output;
582 
583 		if (!chip->config)
584 			chip->config = &samsung_gpio_cfgs[2];
585 		if (!chip->pm)
586 			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
587 		if ((base != NULL) && (chip->base == NULL))
588 			chip->base = base + ((i) * 0x20);
589 
590 		chip->bitmap_gpio_int = 0;
591 
592 		samsung_gpiolib_add(chip);
593 	}
594 }
595 
596 static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
597 						   int nr_chips)
598 {
599 	for (; nr_chips > 0; nr_chips--, chip++) {
600 		chip->chip.direction_input = samsung_gpiolib_4bit2_input;
601 		chip->chip.direction_output = samsung_gpiolib_4bit2_output;
602 
603 		if (!chip->config)
604 			chip->config = &samsung_gpio_cfgs[2];
605 		if (!chip->pm)
606 			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
607 
608 		samsung_gpiolib_add(chip);
609 	}
610 }
611 
612 int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
613 {
614 	struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
615 
616 	return samsung_chip->irq_base + offset;
617 }
618 
619 static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
620 {
621 	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
622 }
623 
624 static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
625 {
626 	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
627 }
628 
629 /*
630  * GPIO bank summary:
631  *
632  * Bank	GPIOs	Style	SlpCon	ExtInt Group
633  * A	8	4Bit	Yes	1
634  * B	7	4Bit	Yes	1
635  * C	8	4Bit	Yes	2
636  * D	5	4Bit	Yes	3
637  * E	5	4Bit	Yes	None
638  * F	16	2Bit	Yes	4 [1]
639  * G	7	4Bit	Yes	5
640  * H	10	4Bit[2]	Yes	6
641  * I	16	2Bit	Yes	None
642  * J	12	2Bit	Yes	None
643  * K	16	4Bit[2]	No	None
644  * L	15	4Bit[2] No	None
645  * M	6	4Bit	No	IRQ_EINT
646  * N	16	2Bit	No	IRQ_EINT
647  * O	16	2Bit	Yes	7
648  * P	15	2Bit	Yes	8
649  * Q	9	2Bit	Yes	9
650  *
651  * [1] BANKF pins 14,15 do not form part of the external interrupt sources
652  * [2] BANK has two control registers, GPxCON0 and GPxCON1
653  */
654 
655 static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
656 	{
657 		.chip	= {
658 			.base	= S3C64XX_GPA(0),
659 			.ngpio	= S3C64XX_GPIO_A_NR,
660 			.label	= "GPA",
661 		},
662 	}, {
663 		.chip	= {
664 			.base	= S3C64XX_GPB(0),
665 			.ngpio	= S3C64XX_GPIO_B_NR,
666 			.label	= "GPB",
667 		},
668 	}, {
669 		.chip	= {
670 			.base	= S3C64XX_GPC(0),
671 			.ngpio	= S3C64XX_GPIO_C_NR,
672 			.label	= "GPC",
673 		},
674 	}, {
675 		.chip	= {
676 			.base	= S3C64XX_GPD(0),
677 			.ngpio	= S3C64XX_GPIO_D_NR,
678 			.label	= "GPD",
679 		},
680 	}, {
681 		.config	= &samsung_gpio_cfgs[0],
682 		.chip	= {
683 			.base	= S3C64XX_GPE(0),
684 			.ngpio	= S3C64XX_GPIO_E_NR,
685 			.label	= "GPE",
686 		},
687 	}, {
688 		.base	= S3C64XX_GPG_BASE,
689 		.chip	= {
690 			.base	= S3C64XX_GPG(0),
691 			.ngpio	= S3C64XX_GPIO_G_NR,
692 			.label	= "GPG",
693 		},
694 	}, {
695 		.base	= S3C64XX_GPM_BASE,
696 		.config	= &samsung_gpio_cfgs[1],
697 		.chip	= {
698 			.base	= S3C64XX_GPM(0),
699 			.ngpio	= S3C64XX_GPIO_M_NR,
700 			.label	= "GPM",
701 			.to_irq = s3c64xx_gpiolib_mbank_to_irq,
702 		},
703 	},
704 };
705 
706 static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
707 	{
708 		.base	= S3C64XX_GPH_BASE + 0x4,
709 		.chip	= {
710 			.base	= S3C64XX_GPH(0),
711 			.ngpio	= S3C64XX_GPIO_H_NR,
712 			.label	= "GPH",
713 		},
714 	}, {
715 		.base	= S3C64XX_GPK_BASE + 0x4,
716 		.config	= &samsung_gpio_cfgs[0],
717 		.chip	= {
718 			.base	= S3C64XX_GPK(0),
719 			.ngpio	= S3C64XX_GPIO_K_NR,
720 			.label	= "GPK",
721 		},
722 	}, {
723 		.base	= S3C64XX_GPL_BASE + 0x4,
724 		.config	= &samsung_gpio_cfgs[1],
725 		.chip	= {
726 			.base	= S3C64XX_GPL(0),
727 			.ngpio	= S3C64XX_GPIO_L_NR,
728 			.label	= "GPL",
729 			.to_irq = s3c64xx_gpiolib_lbank_to_irq,
730 		},
731 	},
732 };
733 
734 static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
735 	{
736 		.base	= S3C64XX_GPF_BASE,
737 		.config	= &samsung_gpio_cfgs[6],
738 		.chip	= {
739 			.base	= S3C64XX_GPF(0),
740 			.ngpio	= S3C64XX_GPIO_F_NR,
741 			.label	= "GPF",
742 		},
743 	}, {
744 		.config	= &samsung_gpio_cfgs[7],
745 		.chip	= {
746 			.base	= S3C64XX_GPI(0),
747 			.ngpio	= S3C64XX_GPIO_I_NR,
748 			.label	= "GPI",
749 		},
750 	}, {
751 		.config	= &samsung_gpio_cfgs[7],
752 		.chip	= {
753 			.base	= S3C64XX_GPJ(0),
754 			.ngpio	= S3C64XX_GPIO_J_NR,
755 			.label	= "GPJ",
756 		},
757 	}, {
758 		.config	= &samsung_gpio_cfgs[6],
759 		.chip	= {
760 			.base	= S3C64XX_GPO(0),
761 			.ngpio	= S3C64XX_GPIO_O_NR,
762 			.label	= "GPO",
763 		},
764 	}, {
765 		.config	= &samsung_gpio_cfgs[6],
766 		.chip	= {
767 			.base	= S3C64XX_GPP(0),
768 			.ngpio	= S3C64XX_GPIO_P_NR,
769 			.label	= "GPP",
770 		},
771 	}, {
772 		.config	= &samsung_gpio_cfgs[6],
773 		.chip	= {
774 			.base	= S3C64XX_GPQ(0),
775 			.ngpio	= S3C64XX_GPIO_Q_NR,
776 			.label	= "GPQ",
777 		},
778 	}, {
779 		.base	= S3C64XX_GPN_BASE,
780 		.irq_base = IRQ_EINT(0),
781 		.config	= &samsung_gpio_cfgs[5],
782 		.chip	= {
783 			.base	= S3C64XX_GPN(0),
784 			.ngpio	= S3C64XX_GPIO_N_NR,
785 			.label	= "GPN",
786 			.to_irq = samsung_gpiolib_to_irq,
787 		},
788 	},
789 };
790 
791 /* TODO: cleanup soc_is_* */
792 static __init int samsung_gpiolib_init(void)
793 {
794 	/*
795 	 * Currently there are two drivers that can provide GPIO support for
796 	 * Samsung SoCs. For device tree enabled platforms, the new
797 	 * pinctrl-samsung driver is used, providing both GPIO and pin control
798 	 * interfaces. For legacy (non-DT) platforms this driver is used.
799 	 */
800 	if (of_have_populated_dt())
801 		return 0;
802 
803 	if (soc_is_s3c64xx()) {
804 		samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
805 				ARRAY_SIZE(samsung_gpio_cfgs));
806 		samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
807 				ARRAY_SIZE(s3c64xx_gpios_2bit),
808 				S3C64XX_VA_GPIO + 0xE0, 0x20);
809 		samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
810 				ARRAY_SIZE(s3c64xx_gpios_4bit),
811 				S3C64XX_VA_GPIO);
812 		samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
813 				ARRAY_SIZE(s3c64xx_gpios_4bit2));
814 	}
815 
816 	return 0;
817 }
818 core_initcall(samsung_gpiolib_init);
819 
820 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
821 {
822 	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
823 	unsigned long flags;
824 	int offset;
825 	int ret;
826 
827 	if (!chip)
828 		return -EINVAL;
829 
830 	offset = pin - chip->chip.base;
831 
832 	samsung_gpio_lock(chip, flags);
833 	ret = samsung_gpio_do_setcfg(chip, offset, config);
834 	samsung_gpio_unlock(chip, flags);
835 
836 	return ret;
837 }
838 EXPORT_SYMBOL(s3c_gpio_cfgpin);
839 
840 int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
841 			  unsigned int cfg)
842 {
843 	int ret;
844 
845 	for (; nr > 0; nr--, start++) {
846 		ret = s3c_gpio_cfgpin(start, cfg);
847 		if (ret != 0)
848 			return ret;
849 	}
850 
851 	return 0;
852 }
853 EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
854 
855 int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
856 			  unsigned int cfg, samsung_gpio_pull_t pull)
857 {
858 	int ret;
859 
860 	for (; nr > 0; nr--, start++) {
861 		s3c_gpio_setpull(start, pull);
862 		ret = s3c_gpio_cfgpin(start, cfg);
863 		if (ret != 0)
864 			return ret;
865 	}
866 
867 	return 0;
868 }
869 EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
870 
871 int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
872 {
873 	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
874 	unsigned long flags;
875 	int offset, ret;
876 
877 	if (!chip)
878 		return -EINVAL;
879 
880 	offset = pin - chip->chip.base;
881 
882 	samsung_gpio_lock(chip, flags);
883 	ret = samsung_gpio_do_setpull(chip, offset, pull);
884 	samsung_gpio_unlock(chip, flags);
885 
886 	return ret;
887 }
888 EXPORT_SYMBOL(s3c_gpio_setpull);
889