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