1 /*
2  * Copyright (C) 2014-2015 Broadcom Corporation
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation version 2.
7  *
8  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9  * kind, whether express or implied; without even the implied warranty
10  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * This file contains the Broadcom Cygnus GPIO driver that supports 3
14  * GPIO controllers on Cygnus including the ASIU GPIO controller, the
15  * chipCommonG GPIO controller, and the always-on GPIO controller. Basic
16  * PINCONF such as bias pull up/down, and drive strength are also supported
17  * in this driver.
18  *
19  * Pins from the ASIU GPIO can be individually muxed to GPIO function,
20  * through the interaction with the Cygnus IOMUX controller
21  */
22 
23 #include <linux/kernel.h>
24 #include <linux/slab.h>
25 #include <linux/interrupt.h>
26 #include <linux/io.h>
27 #include <linux/gpio.h>
28 #include <linux/ioport.h>
29 #include <linux/of_device.h>
30 #include <linux/of_irq.h>
31 #include <linux/pinctrl/pinctrl.h>
32 #include <linux/pinctrl/pinconf.h>
33 #include <linux/pinctrl/pinconf-generic.h>
34 
35 #include "../pinctrl-utils.h"
36 
37 #define CYGNUS_GPIO_DATA_IN_OFFSET   0x00
38 #define CYGNUS_GPIO_DATA_OUT_OFFSET  0x04
39 #define CYGNUS_GPIO_OUT_EN_OFFSET    0x08
40 #define CYGNUS_GPIO_INT_TYPE_OFFSET  0x0c
41 #define CYGNUS_GPIO_INT_DE_OFFSET    0x10
42 #define CYGNUS_GPIO_INT_EDGE_OFFSET  0x14
43 #define CYGNUS_GPIO_INT_MSK_OFFSET   0x18
44 #define CYGNUS_GPIO_INT_STAT_OFFSET  0x1c
45 #define CYGNUS_GPIO_INT_MSTAT_OFFSET 0x20
46 #define CYGNUS_GPIO_INT_CLR_OFFSET   0x24
47 #define CYGNUS_GPIO_PAD_RES_OFFSET   0x34
48 #define CYGNUS_GPIO_RES_EN_OFFSET    0x38
49 
50 /* drive strength control for ASIU GPIO */
51 #define CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET 0x58
52 
53 /* drive strength control for CCM/CRMU (AON) GPIO */
54 #define CYGNUS_GPIO_DRV0_CTRL_OFFSET  0x00
55 
56 #define GPIO_BANK_SIZE 0x200
57 #define NGPIOS_PER_BANK 32
58 #define GPIO_BANK(pin) ((pin) / NGPIOS_PER_BANK)
59 
60 #define CYGNUS_GPIO_REG(pin, reg) (GPIO_BANK(pin) * GPIO_BANK_SIZE + (reg))
61 #define CYGNUS_GPIO_SHIFT(pin) ((pin) % NGPIOS_PER_BANK)
62 
63 #define GPIO_DRV_STRENGTH_BIT_SHIFT  20
64 #define GPIO_DRV_STRENGTH_BITS       3
65 #define GPIO_DRV_STRENGTH_BIT_MASK   ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
66 
67 /*
68  * Cygnus GPIO core
69  *
70  * @dev: pointer to device
71  * @base: I/O register base for Cygnus GPIO controller
72  * @io_ctrl: I/O register base for certain type of Cygnus GPIO controller that
73  * has the PINCONF support implemented outside of the GPIO block
74  * @lock: lock to protect access to I/O registers
75  * @gc: GPIO chip
76  * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
77  * @pinmux_is_supported: flag to indicate this GPIO controller contains pins
78  * that can be individually muxed to GPIO
79  * @pctl: pointer to pinctrl_dev
80  * @pctldesc: pinctrl descriptor
81  */
82 struct cygnus_gpio {
83 	struct device *dev;
84 
85 	void __iomem *base;
86 	void __iomem *io_ctrl;
87 
88 	spinlock_t lock;
89 
90 	struct gpio_chip gc;
91 	unsigned num_banks;
92 
93 	bool pinmux_is_supported;
94 
95 	struct pinctrl_dev *pctl;
96 	struct pinctrl_desc pctldesc;
97 };
98 
to_cygnus_gpio(struct gpio_chip * gc)99 static inline struct cygnus_gpio *to_cygnus_gpio(struct gpio_chip *gc)
100 {
101 	return container_of(gc, struct cygnus_gpio, gc);
102 }
103 
104 /*
105  * Mapping from PINCONF pins to GPIO pins is 1-to-1
106  */
cygnus_pin_to_gpio(unsigned pin)107 static inline unsigned cygnus_pin_to_gpio(unsigned pin)
108 {
109 	return pin;
110 }
111 
112 /**
113  *  cygnus_set_bit - set or clear one bit (corresponding to the GPIO pin) in a
114  *  Cygnus GPIO register
115  *
116  *  @cygnus_gpio: Cygnus GPIO device
117  *  @reg: register offset
118  *  @gpio: GPIO pin
119  *  @set: set or clear
120  */
cygnus_set_bit(struct cygnus_gpio * chip,unsigned int reg,unsigned gpio,bool set)121 static inline void cygnus_set_bit(struct cygnus_gpio *chip, unsigned int reg,
122 				  unsigned gpio, bool set)
123 {
124 	unsigned int offset = CYGNUS_GPIO_REG(gpio, reg);
125 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
126 	u32 val;
127 
128 	val = readl(chip->base + offset);
129 	if (set)
130 		val |= BIT(shift);
131 	else
132 		val &= ~BIT(shift);
133 	writel(val, chip->base + offset);
134 }
135 
cygnus_get_bit(struct cygnus_gpio * chip,unsigned int reg,unsigned gpio)136 static inline bool cygnus_get_bit(struct cygnus_gpio *chip, unsigned int reg,
137 				  unsigned gpio)
138 {
139 	unsigned int offset = CYGNUS_GPIO_REG(gpio, reg);
140 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
141 
142 	return !!(readl(chip->base + offset) & BIT(shift));
143 }
144 
cygnus_gpio_irq_handler(struct irq_desc * desc)145 static void cygnus_gpio_irq_handler(struct irq_desc *desc)
146 {
147 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
148 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
149 	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
150 	int i, bit;
151 
152 	chained_irq_enter(irq_chip, desc);
153 
154 	/* go through the entire GPIO banks and handle all interrupts */
155 	for (i = 0; i < chip->num_banks; i++) {
156 		unsigned long val = readl(chip->base + (i * GPIO_BANK_SIZE) +
157 					  CYGNUS_GPIO_INT_MSTAT_OFFSET);
158 
159 		for_each_set_bit(bit, &val, NGPIOS_PER_BANK) {
160 			unsigned pin = NGPIOS_PER_BANK * i + bit;
161 			int child_irq = irq_find_mapping(gc->irqdomain, pin);
162 
163 			/*
164 			 * Clear the interrupt before invoking the
165 			 * handler, so we do not leave any window
166 			 */
167 			writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) +
168 			       CYGNUS_GPIO_INT_CLR_OFFSET);
169 
170 			generic_handle_irq(child_irq);
171 		}
172 	}
173 
174 	chained_irq_exit(irq_chip, desc);
175 }
176 
177 
cygnus_gpio_irq_ack(struct irq_data * d)178 static void cygnus_gpio_irq_ack(struct irq_data *d)
179 {
180 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
181 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
182 	unsigned gpio = d->hwirq;
183 	unsigned int offset = CYGNUS_GPIO_REG(gpio,
184 			CYGNUS_GPIO_INT_CLR_OFFSET);
185 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
186 	u32 val = BIT(shift);
187 
188 	writel(val, chip->base + offset);
189 }
190 
191 /**
192  *  cygnus_gpio_irq_set_mask - mask/unmask a GPIO interrupt
193  *
194  *  @d: IRQ chip data
195  *  @unmask: mask/unmask GPIO interrupt
196  */
cygnus_gpio_irq_set_mask(struct irq_data * d,bool unmask)197 static void cygnus_gpio_irq_set_mask(struct irq_data *d, bool unmask)
198 {
199 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
200 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
201 	unsigned gpio = d->hwirq;
202 
203 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_MSK_OFFSET, gpio, unmask);
204 }
205 
cygnus_gpio_irq_mask(struct irq_data * d)206 static void cygnus_gpio_irq_mask(struct irq_data *d)
207 {
208 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
209 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
210 	unsigned long flags;
211 
212 	spin_lock_irqsave(&chip->lock, flags);
213 	cygnus_gpio_irq_set_mask(d, false);
214 	spin_unlock_irqrestore(&chip->lock, flags);
215 }
216 
cygnus_gpio_irq_unmask(struct irq_data * d)217 static void cygnus_gpio_irq_unmask(struct irq_data *d)
218 {
219 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
220 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
221 	unsigned long flags;
222 
223 	spin_lock_irqsave(&chip->lock, flags);
224 	cygnus_gpio_irq_set_mask(d, true);
225 	spin_unlock_irqrestore(&chip->lock, flags);
226 }
227 
cygnus_gpio_irq_set_type(struct irq_data * d,unsigned int type)228 static int cygnus_gpio_irq_set_type(struct irq_data *d, unsigned int type)
229 {
230 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
231 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
232 	unsigned gpio = d->hwirq;
233 	bool level_triggered = false;
234 	bool dual_edge = false;
235 	bool rising_or_high = false;
236 	unsigned long flags;
237 
238 	switch (type & IRQ_TYPE_SENSE_MASK) {
239 	case IRQ_TYPE_EDGE_RISING:
240 		rising_or_high = true;
241 		break;
242 
243 	case IRQ_TYPE_EDGE_FALLING:
244 		break;
245 
246 	case IRQ_TYPE_EDGE_BOTH:
247 		dual_edge = true;
248 		break;
249 
250 	case IRQ_TYPE_LEVEL_HIGH:
251 		level_triggered = true;
252 		rising_or_high = true;
253 		break;
254 
255 	case IRQ_TYPE_LEVEL_LOW:
256 		level_triggered = true;
257 		break;
258 
259 	default:
260 		dev_err(chip->dev, "invalid GPIO IRQ type 0x%x\n",
261 			type);
262 		return -EINVAL;
263 	}
264 
265 	spin_lock_irqsave(&chip->lock, flags);
266 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_TYPE_OFFSET, gpio,
267 		       level_triggered);
268 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_DE_OFFSET, gpio, dual_edge);
269 	cygnus_set_bit(chip, CYGNUS_GPIO_INT_EDGE_OFFSET, gpio,
270 		       rising_or_high);
271 	spin_unlock_irqrestore(&chip->lock, flags);
272 
273 	dev_dbg(chip->dev,
274 		"gpio:%u level_triggered:%d dual_edge:%d rising_or_high:%d\n",
275 		gpio, level_triggered, dual_edge, rising_or_high);
276 
277 	return 0;
278 }
279 
280 static struct irq_chip cygnus_gpio_irq_chip = {
281 	.name = "bcm-cygnus-gpio",
282 	.irq_ack = cygnus_gpio_irq_ack,
283 	.irq_mask = cygnus_gpio_irq_mask,
284 	.irq_unmask = cygnus_gpio_irq_unmask,
285 	.irq_set_type = cygnus_gpio_irq_set_type,
286 };
287 
288 /*
289  * Request the Cygnus IOMUX pinmux controller to mux individual pins to GPIO
290  */
cygnus_gpio_request(struct gpio_chip * gc,unsigned offset)291 static int cygnus_gpio_request(struct gpio_chip *gc, unsigned offset)
292 {
293 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
294 	unsigned gpio = gc->base + offset;
295 
296 	/* not all Cygnus GPIO pins can be muxed individually */
297 	if (!chip->pinmux_is_supported)
298 		return 0;
299 
300 	return pinctrl_request_gpio(gpio);
301 }
302 
cygnus_gpio_free(struct gpio_chip * gc,unsigned offset)303 static void cygnus_gpio_free(struct gpio_chip *gc, unsigned offset)
304 {
305 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
306 	unsigned gpio = gc->base + offset;
307 
308 	if (!chip->pinmux_is_supported)
309 		return;
310 
311 	pinctrl_free_gpio(gpio);
312 }
313 
cygnus_gpio_direction_input(struct gpio_chip * gc,unsigned gpio)314 static int cygnus_gpio_direction_input(struct gpio_chip *gc, unsigned gpio)
315 {
316 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
317 	unsigned long flags;
318 
319 	spin_lock_irqsave(&chip->lock, flags);
320 	cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, false);
321 	spin_unlock_irqrestore(&chip->lock, flags);
322 
323 	dev_dbg(chip->dev, "gpio:%u set input\n", gpio);
324 
325 	return 0;
326 }
327 
cygnus_gpio_direction_output(struct gpio_chip * gc,unsigned gpio,int val)328 static int cygnus_gpio_direction_output(struct gpio_chip *gc, unsigned gpio,
329 					int val)
330 {
331 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
332 	unsigned long flags;
333 
334 	spin_lock_irqsave(&chip->lock, flags);
335 	cygnus_set_bit(chip, CYGNUS_GPIO_OUT_EN_OFFSET, gpio, true);
336 	cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
337 	spin_unlock_irqrestore(&chip->lock, flags);
338 
339 	dev_dbg(chip->dev, "gpio:%u set output, value:%d\n", gpio, val);
340 
341 	return 0;
342 }
343 
cygnus_gpio_set(struct gpio_chip * gc,unsigned gpio,int val)344 static void cygnus_gpio_set(struct gpio_chip *gc, unsigned gpio, int val)
345 {
346 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
347 	unsigned long flags;
348 
349 	spin_lock_irqsave(&chip->lock, flags);
350 	cygnus_set_bit(chip, CYGNUS_GPIO_DATA_OUT_OFFSET, gpio, !!(val));
351 	spin_unlock_irqrestore(&chip->lock, flags);
352 
353 	dev_dbg(chip->dev, "gpio:%u set, value:%d\n", gpio, val);
354 }
355 
cygnus_gpio_get(struct gpio_chip * gc,unsigned gpio)356 static int cygnus_gpio_get(struct gpio_chip *gc, unsigned gpio)
357 {
358 	struct cygnus_gpio *chip = to_cygnus_gpio(gc);
359 	unsigned int offset = CYGNUS_GPIO_REG(gpio,
360 					      CYGNUS_GPIO_DATA_IN_OFFSET);
361 	unsigned int shift = CYGNUS_GPIO_SHIFT(gpio);
362 
363 	return !!(readl(chip->base + offset) & BIT(shift));
364 }
365 
cygnus_get_groups_count(struct pinctrl_dev * pctldev)366 static int cygnus_get_groups_count(struct pinctrl_dev *pctldev)
367 {
368 	return 1;
369 }
370 
371 /*
372  * Only one group: "gpio_grp", since this local pinctrl device only performs
373  * GPIO specific PINCONF configurations
374  */
cygnus_get_group_name(struct pinctrl_dev * pctldev,unsigned selector)375 static const char *cygnus_get_group_name(struct pinctrl_dev *pctldev,
376 					 unsigned selector)
377 {
378 	return "gpio_grp";
379 }
380 
381 static const struct pinctrl_ops cygnus_pctrl_ops = {
382 	.get_groups_count = cygnus_get_groups_count,
383 	.get_group_name = cygnus_get_group_name,
384 	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
385 	.dt_free_map = pinctrl_utils_dt_free_map,
386 };
387 
cygnus_gpio_set_pull(struct cygnus_gpio * chip,unsigned gpio,bool disable,bool pull_up)388 static int cygnus_gpio_set_pull(struct cygnus_gpio *chip, unsigned gpio,
389 				bool disable, bool pull_up)
390 {
391 	unsigned long flags;
392 
393 	spin_lock_irqsave(&chip->lock, flags);
394 
395 	if (disable) {
396 		cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, false);
397 	} else {
398 		cygnus_set_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio,
399 			       pull_up);
400 		cygnus_set_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio, true);
401 	}
402 
403 	spin_unlock_irqrestore(&chip->lock, flags);
404 
405 	dev_dbg(chip->dev, "gpio:%u set pullup:%d\n", gpio, pull_up);
406 
407 	return 0;
408 }
409 
cygnus_gpio_get_pull(struct cygnus_gpio * chip,unsigned gpio,bool * disable,bool * pull_up)410 static void cygnus_gpio_get_pull(struct cygnus_gpio *chip, unsigned gpio,
411 				 bool *disable, bool *pull_up)
412 {
413 	unsigned long flags;
414 
415 	spin_lock_irqsave(&chip->lock, flags);
416 	*disable = !cygnus_get_bit(chip, CYGNUS_GPIO_RES_EN_OFFSET, gpio);
417 	*pull_up = cygnus_get_bit(chip, CYGNUS_GPIO_PAD_RES_OFFSET, gpio);
418 	spin_unlock_irqrestore(&chip->lock, flags);
419 }
420 
cygnus_gpio_set_strength(struct cygnus_gpio * chip,unsigned gpio,unsigned strength)421 static int cygnus_gpio_set_strength(struct cygnus_gpio *chip, unsigned gpio,
422 				    unsigned strength)
423 {
424 	void __iomem *base;
425 	unsigned int i, offset, shift;
426 	u32 val;
427 	unsigned long flags;
428 
429 	/* make sure drive strength is supported */
430 	if (strength < 2 ||  strength > 16 || (strength % 2))
431 		return -ENOTSUPP;
432 
433 	if (chip->io_ctrl) {
434 		base = chip->io_ctrl;
435 		offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET;
436 	} else {
437 		base = chip->base;
438 		offset = CYGNUS_GPIO_REG(gpio,
439 					 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET);
440 	}
441 
442 	shift = CYGNUS_GPIO_SHIFT(gpio);
443 
444 	dev_dbg(chip->dev, "gpio:%u set drive strength:%d mA\n", gpio,
445 		strength);
446 
447 	spin_lock_irqsave(&chip->lock, flags);
448 	strength = (strength / 2) - 1;
449 	for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
450 		val = readl(base + offset);
451 		val &= ~BIT(shift);
452 		val |= ((strength >> i) & 0x1) << shift;
453 		writel(val, base + offset);
454 		offset += 4;
455 	}
456 	spin_unlock_irqrestore(&chip->lock, flags);
457 
458 	return 0;
459 }
460 
cygnus_gpio_get_strength(struct cygnus_gpio * chip,unsigned gpio,u16 * strength)461 static int cygnus_gpio_get_strength(struct cygnus_gpio *chip, unsigned gpio,
462 				    u16 *strength)
463 {
464 	void __iomem *base;
465 	unsigned int i, offset, shift;
466 	u32 val;
467 	unsigned long flags;
468 
469 	if (chip->io_ctrl) {
470 		base = chip->io_ctrl;
471 		offset = CYGNUS_GPIO_DRV0_CTRL_OFFSET;
472 	} else {
473 		base = chip->base;
474 		offset = CYGNUS_GPIO_REG(gpio,
475 					 CYGNUS_GPIO_ASIU_DRV0_CTRL_OFFSET);
476 	}
477 
478 	shift = CYGNUS_GPIO_SHIFT(gpio);
479 
480 	spin_lock_irqsave(&chip->lock, flags);
481 	*strength = 0;
482 	for (i = 0; i < GPIO_DRV_STRENGTH_BITS; i++) {
483 		val = readl(base + offset) & BIT(shift);
484 		val >>= shift;
485 		*strength += (val << i);
486 		offset += 4;
487 	}
488 
489 	/* convert to mA */
490 	*strength = (*strength + 1) * 2;
491 	spin_unlock_irqrestore(&chip->lock, flags);
492 
493 	return 0;
494 }
495 
cygnus_pin_config_get(struct pinctrl_dev * pctldev,unsigned pin,unsigned long * config)496 static int cygnus_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
497 				 unsigned long *config)
498 {
499 	struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
500 	enum pin_config_param param = pinconf_to_config_param(*config);
501 	unsigned gpio = cygnus_pin_to_gpio(pin);
502 	u16 arg;
503 	bool disable, pull_up;
504 	int ret;
505 
506 	switch (param) {
507 	case PIN_CONFIG_BIAS_DISABLE:
508 		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
509 		if (disable)
510 			return 0;
511 		else
512 			return -EINVAL;
513 
514 	case PIN_CONFIG_BIAS_PULL_UP:
515 		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
516 		if (!disable && pull_up)
517 			return 0;
518 		else
519 			return -EINVAL;
520 
521 	case PIN_CONFIG_BIAS_PULL_DOWN:
522 		cygnus_gpio_get_pull(chip, gpio, &disable, &pull_up);
523 		if (!disable && !pull_up)
524 			return 0;
525 		else
526 			return -EINVAL;
527 
528 	case PIN_CONFIG_DRIVE_STRENGTH:
529 		ret = cygnus_gpio_get_strength(chip, gpio, &arg);
530 		if (ret)
531 			return ret;
532 		else
533 			*config = pinconf_to_config_packed(param, arg);
534 
535 		return 0;
536 
537 	default:
538 		return -ENOTSUPP;
539 	}
540 
541 	return -ENOTSUPP;
542 }
543 
cygnus_pin_config_set(struct pinctrl_dev * pctldev,unsigned pin,unsigned long * configs,unsigned num_configs)544 static int cygnus_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
545 				 unsigned long *configs, unsigned num_configs)
546 {
547 	struct cygnus_gpio *chip = pinctrl_dev_get_drvdata(pctldev);
548 	enum pin_config_param param;
549 	u16 arg;
550 	unsigned i, gpio = cygnus_pin_to_gpio(pin);
551 	int ret = -ENOTSUPP;
552 
553 	for (i = 0; i < num_configs; i++) {
554 		param = pinconf_to_config_param(configs[i]);
555 		arg = pinconf_to_config_argument(configs[i]);
556 
557 		switch (param) {
558 		case PIN_CONFIG_BIAS_DISABLE:
559 			ret = cygnus_gpio_set_pull(chip, gpio, true, false);
560 			if (ret < 0)
561 				goto out;
562 			break;
563 
564 		case PIN_CONFIG_BIAS_PULL_UP:
565 			ret = cygnus_gpio_set_pull(chip, gpio, false, true);
566 			if (ret < 0)
567 				goto out;
568 			break;
569 
570 		case PIN_CONFIG_BIAS_PULL_DOWN:
571 			ret = cygnus_gpio_set_pull(chip, gpio, false, false);
572 			if (ret < 0)
573 				goto out;
574 			break;
575 
576 		case PIN_CONFIG_DRIVE_STRENGTH:
577 			ret = cygnus_gpio_set_strength(chip, gpio, arg);
578 			if (ret < 0)
579 				goto out;
580 			break;
581 
582 		default:
583 			dev_err(chip->dev, "invalid configuration\n");
584 			return -ENOTSUPP;
585 		}
586 	} /* for each config */
587 
588 out:
589 	return ret;
590 }
591 
592 static const struct pinconf_ops cygnus_pconf_ops = {
593 	.is_generic = true,
594 	.pin_config_get = cygnus_pin_config_get,
595 	.pin_config_set = cygnus_pin_config_set,
596 };
597 
598 /*
599  * Cygnus GPIO controller supports some PINCONF related configurations such as
600  * pull up, pull down, and drive strength, when the pin is configured to GPIO
601  *
602  * Here a local pinctrl device is created with simple 1-to-1 pin mapping to the
603  * local GPIO pins
604  */
cygnus_gpio_register_pinconf(struct cygnus_gpio * chip)605 static int cygnus_gpio_register_pinconf(struct cygnus_gpio *chip)
606 {
607 	struct pinctrl_desc *pctldesc = &chip->pctldesc;
608 	struct pinctrl_pin_desc *pins;
609 	struct gpio_chip *gc = &chip->gc;
610 	int i;
611 
612 	pins = devm_kcalloc(chip->dev, gc->ngpio, sizeof(*pins), GFP_KERNEL);
613 	if (!pins)
614 		return -ENOMEM;
615 
616 	for (i = 0; i < gc->ngpio; i++) {
617 		pins[i].number = i;
618 		pins[i].name = devm_kasprintf(chip->dev, GFP_KERNEL,
619 					      "gpio-%d", i);
620 		if (!pins[i].name)
621 			return -ENOMEM;
622 	}
623 
624 	pctldesc->name = dev_name(chip->dev);
625 	pctldesc->pctlops = &cygnus_pctrl_ops;
626 	pctldesc->pins = pins;
627 	pctldesc->npins = gc->ngpio;
628 	pctldesc->confops = &cygnus_pconf_ops;
629 
630 	chip->pctl = pinctrl_register(pctldesc, chip->dev, chip);
631 	if (IS_ERR(chip->pctl)) {
632 		dev_err(chip->dev, "unable to register pinctrl device\n");
633 		return PTR_ERR(chip->pctl);
634 	}
635 
636 	return 0;
637 }
638 
cygnus_gpio_unregister_pinconf(struct cygnus_gpio * chip)639 static void cygnus_gpio_unregister_pinconf(struct cygnus_gpio *chip)
640 {
641 	if (chip->pctl)
642 		pinctrl_unregister(chip->pctl);
643 }
644 
645 struct cygnus_gpio_data {
646 	unsigned num_gpios;
647 };
648 
649 static const struct cygnus_gpio_data cygnus_cmm_gpio_data = {
650 	.num_gpios = 24,
651 };
652 
653 static const struct cygnus_gpio_data cygnus_asiu_gpio_data = {
654 	.num_gpios = 146,
655 };
656 
657 static const struct cygnus_gpio_data cygnus_crmu_gpio_data = {
658 	.num_gpios = 6,
659 };
660 
661 static const struct of_device_id cygnus_gpio_of_match[] = {
662 	{
663 		.compatible = "brcm,cygnus-ccm-gpio",
664 		.data = &cygnus_cmm_gpio_data,
665 	},
666 	{
667 		.compatible = "brcm,cygnus-asiu-gpio",
668 		.data = &cygnus_asiu_gpio_data,
669 	},
670 	{
671 		.compatible = "brcm,cygnus-crmu-gpio",
672 		.data = &cygnus_crmu_gpio_data,
673 	}
674 };
675 
cygnus_gpio_probe(struct platform_device * pdev)676 static int cygnus_gpio_probe(struct platform_device *pdev)
677 {
678 	struct device *dev = &pdev->dev;
679 	struct resource *res;
680 	struct cygnus_gpio *chip;
681 	struct gpio_chip *gc;
682 	u32 ngpios;
683 	int irq, ret;
684 	const struct of_device_id *match;
685 	const struct cygnus_gpio_data *gpio_data;
686 
687 	match = of_match_device(cygnus_gpio_of_match, dev);
688 	if (!match)
689 		return -ENODEV;
690 	gpio_data = match->data;
691 	ngpios = gpio_data->num_gpios;
692 
693 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
694 	if (!chip)
695 		return -ENOMEM;
696 
697 	chip->dev = dev;
698 	platform_set_drvdata(pdev, chip);
699 
700 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
701 	chip->base = devm_ioremap_resource(dev, res);
702 	if (IS_ERR(chip->base)) {
703 		dev_err(dev, "unable to map I/O memory\n");
704 		return PTR_ERR(chip->base);
705 	}
706 
707 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
708 	if (res) {
709 		chip->io_ctrl = devm_ioremap_resource(dev, res);
710 		if (IS_ERR(chip->io_ctrl)) {
711 			dev_err(dev, "unable to map I/O memory\n");
712 			return PTR_ERR(chip->io_ctrl);
713 		}
714 	}
715 
716 	spin_lock_init(&chip->lock);
717 
718 	gc = &chip->gc;
719 	gc->base = -1;
720 	gc->ngpio = ngpios;
721 	chip->num_banks = (ngpios + NGPIOS_PER_BANK - 1) / NGPIOS_PER_BANK;
722 	gc->label = dev_name(dev);
723 	gc->dev = dev;
724 	gc->of_node = dev->of_node;
725 	gc->request = cygnus_gpio_request;
726 	gc->free = cygnus_gpio_free;
727 	gc->direction_input = cygnus_gpio_direction_input;
728 	gc->direction_output = cygnus_gpio_direction_output;
729 	gc->set = cygnus_gpio_set;
730 	gc->get = cygnus_gpio_get;
731 
732 	chip->pinmux_is_supported = of_property_read_bool(dev->of_node,
733 							"gpio-ranges");
734 
735 	ret = gpiochip_add(gc);
736 	if (ret < 0) {
737 		dev_err(dev, "unable to add GPIO chip\n");
738 		return ret;
739 	}
740 
741 	ret = cygnus_gpio_register_pinconf(chip);
742 	if (ret) {
743 		dev_err(dev, "unable to register pinconf\n");
744 		goto err_rm_gpiochip;
745 	}
746 
747 	/* optional GPIO interrupt support */
748 	irq = platform_get_irq(pdev, 0);
749 	if (irq) {
750 		ret = gpiochip_irqchip_add(gc, &cygnus_gpio_irq_chip, 0,
751 					   handle_simple_irq, IRQ_TYPE_NONE);
752 		if (ret) {
753 			dev_err(dev, "no GPIO irqchip\n");
754 			goto err_unregister_pinconf;
755 		}
756 
757 		gpiochip_set_chained_irqchip(gc, &cygnus_gpio_irq_chip, irq,
758 					     cygnus_gpio_irq_handler);
759 	}
760 
761 	return 0;
762 
763 err_unregister_pinconf:
764 	cygnus_gpio_unregister_pinconf(chip);
765 
766 err_rm_gpiochip:
767 	gpiochip_remove(gc);
768 
769 	return ret;
770 }
771 
772 static struct platform_driver cygnus_gpio_driver = {
773 	.driver = {
774 		.name = "cygnus-gpio",
775 		.of_match_table = cygnus_gpio_of_match,
776 	},
777 	.probe = cygnus_gpio_probe,
778 };
779 
cygnus_gpio_init(void)780 static int __init cygnus_gpio_init(void)
781 {
782 	return platform_driver_probe(&cygnus_gpio_driver, cygnus_gpio_probe);
783 }
784 arch_initcall_sync(cygnus_gpio_init);
785