aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRay Jui <ray.jui@broadcom.com>2016-07-18 13:20:18 -0400
committerLinus Walleij <linus.walleij@linaro.org>2016-07-22 10:47:51 -0400
commitf58de3d96a73e05b5bb67be517e6e87c6234fef0 (patch)
tree797ac1f8c8b0e259386f2d983da940e225101ea1
parent418af4a88ed41cd38aa817b585b857b8bd5f7fd9 (diff)
pinctrl: iproc: Add NSP and Stingray GPIO support
The iProc GPIO controller is shared among multiple iProc based SoCs. In the NSP integration, the drive strength pinctrl function is disabled. In the integration of Stingray, pinctrl is handled by another block and this GPIO controller is solely used as a GPIO controller, and therefore should not be registered to the pinconf framework This patch introduces new SoC specific compatible strings "brcm,iproc-nsp-gpio" for NSP with drive strength feature disabled and "brcm,iproc-stingray-gpio" for Stingray with all PINCONF features disabled This patch is developed based on the initial work from Yendapally Reddy Dhananjaya <yendapally.reddy@broadcom.com> who attempted to disable drive strength configuration for the iProc based NSP chip. In addition, Pramod Kumar <pramod.kumar@broadcom.com> also contributed to make the support more generic across all currently supported PINCONF functions in the iProc GPIO/PINCONF driver Signed-off-by: Pramod Kumar <pramodku@broadcom.com> Signed-off-by: Ray Jui <ray.jui@broadcom.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/bcm/pinctrl-iproc-gpio.c118
1 files changed, 111 insertions, 7 deletions
diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index 3670f5ea7a12..7f7700716398 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -66,6 +66,14 @@
66#define GPIO_DRV_STRENGTH_BITS 3 66#define GPIO_DRV_STRENGTH_BITS 3
67#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1) 67#define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1)
68 68
69enum iproc_pinconf_param {
70 IPROC_PINCONF_DRIVE_STRENGTH = 0,
71 IPROC_PINCONF_BIAS_DISABLE,
72 IPROC_PINCONF_BIAS_PULL_UP,
73 IPROC_PINCONF_BIAS_PULL_DOWN,
74 IPROC_PINCON_MAX,
75};
76
69/* 77/*
70 * Iproc GPIO core 78 * Iproc GPIO core
71 * 79 *
@@ -78,6 +86,10 @@
78 * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs 86 * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs
79 * @pinmux_is_supported: flag to indicate this GPIO controller contains pins 87 * @pinmux_is_supported: flag to indicate this GPIO controller contains pins
80 * that can be individually muxed to GPIO 88 * that can be individually muxed to GPIO
89 * @pinconf_disable: contains a list of PINCONF parameters that need to be
90 * disabled
91 * @nr_pinconf_disable: total number of PINCONF parameters that need to be
92 * disabled
81 * @pctl: pointer to pinctrl_dev 93 * @pctl: pointer to pinctrl_dev
82 * @pctldesc: pinctrl descriptor 94 * @pctldesc: pinctrl descriptor
83 */ 95 */
@@ -94,6 +106,9 @@ struct iproc_gpio {
94 106
95 bool pinmux_is_supported; 107 bool pinmux_is_supported;
96 108
109 enum pin_config_param *pinconf_disable;
110 unsigned int nr_pinconf_disable;
111
97 struct pinctrl_dev *pctl; 112 struct pinctrl_dev *pctl;
98 struct pinctrl_desc pctldesc; 113 struct pinctrl_desc pctldesc;
99}; 114};
@@ -360,6 +375,65 @@ static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio)
360 return !!(readl(chip->base + offset) & BIT(shift)); 375 return !!(readl(chip->base + offset) & BIT(shift));
361} 376}
362 377
378/*
379 * Mapping of the iProc PINCONF parameters to the generic pin configuration
380 * parameters
381 */
382static const enum pin_config_param iproc_pinconf_disable_map[] = {
383 [IPROC_PINCONF_DRIVE_STRENGTH] = PIN_CONFIG_DRIVE_STRENGTH,
384 [IPROC_PINCONF_BIAS_DISABLE] = PIN_CONFIG_BIAS_DISABLE,
385 [IPROC_PINCONF_BIAS_PULL_UP] = PIN_CONFIG_BIAS_PULL_UP,
386 [IPROC_PINCONF_BIAS_PULL_DOWN] = PIN_CONFIG_BIAS_PULL_DOWN,
387};
388
389static bool iproc_pinconf_param_is_disabled(struct iproc_gpio *chip,
390 enum pin_config_param param)
391{
392 unsigned int i;
393
394 if (!chip->nr_pinconf_disable)
395 return false;
396
397 for (i = 0; i < chip->nr_pinconf_disable; i++)
398 if (chip->pinconf_disable[i] == param)
399 return true;
400
401 return false;
402}
403
404static int iproc_pinconf_disable_map_create(struct iproc_gpio *chip,
405 unsigned long disable_mask)
406{
407 unsigned int map_size = ARRAY_SIZE(iproc_pinconf_disable_map);
408 unsigned int bit, nbits = 0;
409
410 /* figure out total number of PINCONF parameters to disable */
411 for_each_set_bit(bit, &disable_mask, map_size)
412 nbits++;
413
414 if (!nbits)
415 return 0;
416
417 /*
418 * Allocate an array to store PINCONF parameters that need to be
419 * disabled
420 */
421 chip->pinconf_disable = devm_kcalloc(chip->dev, nbits,
422 sizeof(*chip->pinconf_disable),
423 GFP_KERNEL);
424 if (!chip->pinconf_disable)
425 return -ENOMEM;
426
427 chip->nr_pinconf_disable = nbits;
428
429 /* now store these parameters */
430 nbits = 0;
431 for_each_set_bit(bit, &disable_mask, map_size)
432 chip->pinconf_disable[nbits++] = iproc_pinconf_disable_map[bit];
433
434 return 0;
435}
436
363static int iproc_get_groups_count(struct pinctrl_dev *pctldev) 437static int iproc_get_groups_count(struct pinctrl_dev *pctldev)
364{ 438{
365 return 1; 439 return 1;
@@ -500,6 +574,9 @@ static int iproc_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
500 bool disable, pull_up; 574 bool disable, pull_up;
501 int ret; 575 int ret;
502 576
577 if (iproc_pinconf_param_is_disabled(chip, param))
578 return -ENOTSUPP;
579
503 switch (param) { 580 switch (param) {
504 case PIN_CONFIG_BIAS_DISABLE: 581 case PIN_CONFIG_BIAS_DISABLE:
505 iproc_gpio_get_pull(chip, gpio, &disable, &pull_up); 582 iproc_gpio_get_pull(chip, gpio, &disable, &pull_up);
@@ -548,6 +625,10 @@ static int iproc_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
548 625
549 for (i = 0; i < num_configs; i++) { 626 for (i = 0; i < num_configs; i++) {
550 param = pinconf_to_config_param(configs[i]); 627 param = pinconf_to_config_param(configs[i]);
628
629 if (iproc_pinconf_param_is_disabled(chip, param))
630 return -ENOTSUPP;
631
551 arg = pinconf_to_config_argument(configs[i]); 632 arg = pinconf_to_config_argument(configs[i]);
552 633
553 switch (param) { 634 switch (param) {
@@ -633,11 +714,13 @@ static int iproc_gpio_register_pinconf(struct iproc_gpio *chip)
633} 714}
634 715
635static const struct of_device_id iproc_gpio_of_match[] = { 716static const struct of_device_id iproc_gpio_of_match[] = {
717 { .compatible = "brcm,iproc-gpio" },
636 { .compatible = "brcm,cygnus-ccm-gpio" }, 718 { .compatible = "brcm,cygnus-ccm-gpio" },
637 { .compatible = "brcm,cygnus-asiu-gpio" }, 719 { .compatible = "brcm,cygnus-asiu-gpio" },
638 { .compatible = "brcm,cygnus-crmu-gpio" }, 720 { .compatible = "brcm,cygnus-crmu-gpio" },
639 { .compatible = "brcm,iproc-gpio" }, 721 { .compatible = "brcm,iproc-nsp-gpio" },
640 { } 722 { .compatible = "brcm,iproc-stingray-gpio" },
723 { /* sentinel */ }
641}; 724};
642 725
643static int iproc_gpio_probe(struct platform_device *pdev) 726static int iproc_gpio_probe(struct platform_device *pdev)
@@ -646,8 +729,17 @@ static int iproc_gpio_probe(struct platform_device *pdev)
646 struct resource *res; 729 struct resource *res;
647 struct iproc_gpio *chip; 730 struct iproc_gpio *chip;
648 struct gpio_chip *gc; 731 struct gpio_chip *gc;
649 u32 ngpios; 732 u32 ngpios, pinconf_disable_mask = 0;
650 int irq, ret; 733 int irq, ret;
734 bool no_pinconf = false;
735
736 /* NSP does not support drive strength config */
737 if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio"))
738 pinconf_disable_mask = BIT(IPROC_PINCONF_DRIVE_STRENGTH);
739 /* Stingray does not support pinconf in this controller */
740 else if (of_device_is_compatible(dev->of_node,
741 "brcm,iproc-stingray-gpio"))
742 no_pinconf = true;
651 743
652 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 744 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
653 if (!chip) 745 if (!chip)
@@ -702,10 +794,22 @@ static int iproc_gpio_probe(struct platform_device *pdev)
702 return ret; 794 return ret;
703 } 795 }
704 796
705 ret = iproc_gpio_register_pinconf(chip); 797 if (!no_pinconf) {
706 if (ret) { 798 ret = iproc_gpio_register_pinconf(chip);
707 dev_err(dev, "unable to register pinconf\n"); 799 if (ret) {
708 goto err_rm_gpiochip; 800 dev_err(dev, "unable to register pinconf\n");
801 goto err_rm_gpiochip;
802 }
803
804 if (pinconf_disable_mask) {
805 ret = iproc_pinconf_disable_map_create(chip,
806 pinconf_disable_mask);
807 if (ret) {
808 dev_err(dev,
809 "unable to create pinconf disable map\n");
810 goto err_rm_gpiochip;
811 }
812 }
709 } 813 }
710 814
711 /* optional GPIO interrupt support */ 815 /* optional GPIO interrupt support */