]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'pinctrl-v4.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Feb 2017 00:34:22 +0000 (16:34 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Feb 2017 00:34:22 +0000 (16:34 -0800)
Pull pin control updates from Linus Walleij:
 "Pin control bulk changes for the v4.11 kernel cycle.

  Core changes:

   - Switch the generic pin config argument from 16 to 24 bits, only use
     8 bits for the configuration type. We might need to encode more
     information about a certain setting than we need to encode
     different generic settings.

   - Add a cross-talk API to the pin control GPIO back-end, utilizing
     pinctrl_gpio_set_config() from GPIO drivers that want to set up a
     certain pin configuration in the back-end.

     This also includes the .set_config() refactoring of the GPIO chips,
     so that they pass a generic configuration for things like
     debouncing and single ended (typically open drain). This change has
     also been merged in an immutable branch to the GPIO tree.

   - Take hogs with a delayed work, so that we finalize probing a pin
     controller before trying to get any hogs.

   - For pin controllers putting all group and function definitions into
     the device tree, we now have generic code to deal with this and it
     is used in two drivers so far.

   - Simplifications of the pin request conflict check.

   - Make dt_free_map() optional.

  Updates to drivers:

   - pinctrl-single now use the generic helpers to generate dynamic
     group and function tables from the device tree.

   - Texas Instruments IOdelay configuration driver add-on to
     pinctrl-single.

   - i.MX: use radix trees to store groups and functions, use the new
     generic group and function helpers to manage them.

   - Intel: add support for hardware debouncing and 1K pull-down. New
     subdriver for the Gemini Lake SoC.

   - Renesas SH-PFC: drive strength and bias support, CAN bus muxing,
     MSIOF, SDHI, HSCIF for r8a7796. Gyro-ADC supporton r8a7791.

   - Aspeed: use syscon cross-dependencies to set up related bits in the
     LPC host controller and display controller.

   - Aspeed: finalize G4 and G5 support. Fix mux configuration on GPIOs.
     Add banks Y, Z, AA, AB and AC.

   - AMD: support additional GPIO.

   - STM32: set this controller to strict muxing mode. STM32H743 MCU
     support.

   - Allwinner sunxi: deep simplifications on how to support subvariants
     of SoCs without adding to much SoC-specific data for each
     subvariant, especially for sun5i variants. New driver for V3s SoCs.
     New driver for the H5 SoC. Support A31/A31s variants with the new
     variant framework.

   - Mvebu: simplifications to use a MMIO and regmap abstraction. New
     subdrivers for the 98DX3236, 98DX5241 SoCs.

   - Samsung Exynos: delete Exynos4415 support. Add crosstalk to the SoC
     driver to access regmaps. Add infrastructure for pin-bank retention
     control. Clean out the pin retention control from
     arch/arm/mach-exynos and arch/arm/mach-s5p and put it properly in
     the Samsung pin control driver(s).

   - Meson: add HDMI HPD/DDC pins. Add pwm_ao_b pin.

   - Qualcomm: use raw spinlock variants: this makes the qualcomm driver
     realtime-safe"

* tag 'pinctrl-v4.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (111 commits)
  pinctrl: samsung: Fix return value check in samsung_pinctrl_get_soc_data()
  pinctrl: intel: unlock on error in intel_config_set_pull()
  pinctrl: berlin: make bool drivers explicitly non-modular
  pinctrl: spear: make bool drivers explicitly non-modular
  pinctrl: mvebu: make bool drivers explicitly non-modular
  pinctrl: sunxi: make sun5i explicitly non-modular
  pinctrl: sunxi: Remove stray printk call in sun5i driver's probe function
  pinctrl: samsung: mark PM functions as __maybe_unused
  pinctrl: sunxi: Remove redundant A31s pinctrl driver
  pinctrl: sunxi: Support A31/A31s with pinctrl variants
  pinctrl: Amend bindings for STM32 pinctrl
  pinctrl: Add STM32 pinctrl driver DT bindings
  pinctrl: stm32: Add STM32H743 MCU support
  include: dt-bindings: Add STM32H7 pinctrl DT defines
  gpio: aspeed: Remove dependence on GPIOF_* macros
  pinctrl: stm32: fix bad location of gpiochip_lock_as_irq
  drivers: pinctrl: add driver for Allwinner H5 SoC
  pinctrl: intel: Add Intel Gemini Lake pin controller support
  pinctrl: intel: Add support for 1k additional pull-down
  pinctrl: intel: Add support for hardware debouncer
  ...

1  2 
drivers/pinctrl/berlin/berlin-bg4ct.c
drivers/pinctrl/intel/pinctrl-baytrail.c
drivers/pinctrl/sunxi/pinctrl-sunxi.c

index c617ec49e9edeeebb1f33b78fa6b7214fb23207c,9367379313204e1d7dcb56e606b1390270a4e141..e6740656ee7c4e3c505356718ca9b412527d2e6e
@@@ -18,7 -18,7 +18,7 @@@
   * this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  
- #include <linux/module.h>
+ #include <linux/init.h>
  #include <linux/of_device.h>
  #include <linux/platform_device.h>
  #include <linux/regmap.h>
@@@ -217,7 -217,7 +217,7 @@@ static const struct berlin_desc_group b
        BERLIN_PINCTRL_GROUP("SCRD0_CRD_PRES", 0xc, 0x3, 0x15,
                        BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO20 */
                        BERLIN_PINCTRL_FUNCTION(0x1, "scrd0"), /* crd pres */
 -                      BERLIN_PINCTRL_FUNCTION(0x1, "sd1a")), /* DAT3 */
 +                      BERLIN_PINCTRL_FUNCTION(0x3, "sd1a")), /* DAT3 */
        BERLIN_PINCTRL_GROUP("SPI1_SS0n", 0xc, 0x3, 0x18,
                        BERLIN_PINCTRL_FUNCTION(0x0, "spi1"), /* SS0n */
                        BERLIN_PINCTRL_FUNCTION(0x1, "gpio"), /* GPIO37 */
@@@ -457,7 -457,6 +457,6 @@@ static const struct of_device_id berlin
        },
        {}
  };
- MODULE_DEVICE_TABLE(of, berlin4ct_pinctrl_match);
  
  static int berlin4ct_pinctrl_probe(struct platform_device *pdev)
  {
@@@ -496,8 -495,4 +495,4 @@@ static struct platform_driver berlin4ct
                .of_match_table = berlin4ct_pinctrl_match,
        },
  };
- module_platform_driver(berlin4ct_pinctrl_driver);
- MODULE_AUTHOR("Jisheng Zhang <jszhang@marvell.com>");
- MODULE_DESCRIPTION("Marvell berlin4ct pinctrl driver");
- MODULE_LICENSE("GPL");
+ builtin_platform_driver(berlin4ct_pinctrl_driver);
index d94aef17348b4b88f3952670886b863b952cfc60,7241435b90fa0737c0b93d5b32d469535ebbcd87..fa3c5758ac6739f3fe07df34bc29fb13cfab21af
@@@ -731,23 -731,16 +731,23 @@@ static void __iomem *byt_gpio_reg(struc
                                  int reg)
  {
        struct byt_community *comm = byt_get_community(vg, offset);
 -      u32 reg_offset = 0;
 +      u32 reg_offset;
  
        if (!comm)
                return NULL;
  
        offset -= comm->pin_base;
 -      if (reg == BYT_INT_STAT_REG)
 +      switch (reg) {
 +      case BYT_INT_STAT_REG:
                reg_offset = (offset / 32) * 4;
 -      else
 +              break;
 +      case BYT_DEBOUNCE_REG:
 +              reg_offset = 0;
 +              break;
 +      default:
                reg_offset = comm->pad_map[offset] * 16;
 +              break;
 +      }
  
        return comm->reg_base + reg_offset + reg;
  }
@@@ -1250,12 -1243,10 +1250,12 @@@ static int byt_pin_config_set(struct pi
                        debounce = readl(db_reg);
                        debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
  
 +                      if (arg)
 +                              conf |= BYT_DEBOUNCE_EN;
 +                      else
 +                              conf &= ~BYT_DEBOUNCE_EN;
 +
                        switch (arg) {
 -                      case 0:
 -                              conf &= BYT_DEBOUNCE_EN;
 -                              break;
                        case 375:
                                debounce |= BYT_DEBOUNCE_PULSE_375US;
                                break;
                                debounce |= BYT_DEBOUNCE_PULSE_24MS;
                                break;
                        default:
 -                              ret = -EINVAL;
 +                              if (arg)
 +                                      ret = -EINVAL;
 +                              break;
                        }
  
                        if (!ret)
@@@ -1466,7 -1455,7 +1466,7 @@@ static void byt_gpio_dbg_show(struct se
                           val & BYT_INPUT_EN ? "  " : "in",
                           val & BYT_OUTPUT_EN ? "   " : "out",
                           val & BYT_LEVEL ? "hi" : "lo",
-                          comm->pad_map[i], comm->pad_map[i] * 32,
+                          comm->pad_map[i], comm->pad_map[i] * 16,
                           conf0 & 0x7,
                           conf0 & BYT_TRIG_NEG ? " fall" : "     ",
                           conf0 & BYT_TRIG_POS ? " rise" : "     ",
@@@ -1623,9 -1612,7 +1623,9 @@@ static void byt_gpio_irq_handler(struc
                        continue;
                }
  
 +              raw_spin_lock(&vg->lock);
                pending = readl(reg);
 +              raw_spin_unlock(&vg->lock);
                for_each_set_bit(pin, &pending, 32) {
                        virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
                        generic_handle_irq(virq);
@@@ -1709,7 -1696,7 +1709,7 @@@ static int byt_gpio_probe(struct byt_gp
        vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,
                                       sizeof(*vg->saved_context), GFP_KERNEL);
  #endif
-       ret = gpiochip_add_data(gc, vg);
+       ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg);
        if (ret) {
                dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n");
                return ret;
                                     0, 0, vg->soc_data->npins);
        if (ret) {
                dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n");
-               goto fail;
+               return ret;
        }
  
        /* set up interrupts  */
                                           handle_bad_irq, IRQ_TYPE_NONE);
                if (ret) {
                        dev_err(&vg->pdev->dev, "failed to add irqchip\n");
-                       goto fail;
+                       return ret;
                }
  
                gpiochip_set_chained_irqchip(gc, &byt_irqchip,
                                             byt_gpio_irq_handler);
        }
  
-       return ret;
- fail:
-       gpiochip_remove(&vg->chip);
        return ret;
  }
  
@@@ -1826,7 -1808,7 +1821,7 @@@ static int byt_pinctrl_probe(struct pla
        vg->pctl_desc.pins      = vg->soc_data->pins;
        vg->pctl_desc.npins     = vg->soc_data->npins;
  
-       vg->pctl_dev = pinctrl_register(&vg->pctl_desc, &pdev->dev, vg);
+       vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg);
        if (IS_ERR(vg->pctl_dev)) {
                dev_err(&pdev->dev, "failed to register pinctrl driver\n");
                return PTR_ERR(vg->pctl_dev);
        raw_spin_lock_init(&vg->lock);
  
        ret = byt_gpio_probe(vg);
-       if (ret) {
-               pinctrl_unregister(vg->pctl_dev);
+       if (ret)
                return ret;
-       }
  
        platform_set_drvdata(pdev, vg);
        pm_runtime_enable(&pdev->dev);
index 207a8de4e1ed851cf542aa4af008e8f74102cad3,aaef7f42f1e421165318aa891cbf097bae43878d..60e6e36c4a7e84fb6d70a46c99c1cc13c7fe2d2f
@@@ -540,7 -540,7 +540,7 @@@ static int sunxi_pconf_group_set(struc
                enum pin_config_param param;
                unsigned long flags;
                u32 offset, shift, mask, reg;
-               u16 arg, val;
+               u32 arg, val;
                int ret;
  
                param = pinconf_to_config_param(configs[i]);
                        val = arg / 10 - 1;
                        break;
                case PIN_CONFIG_BIAS_DISABLE:
 -                      val = 0;
 -                      break;
 +                      continue;
                case PIN_CONFIG_BIAS_PULL_UP:
                        if (arg == 0)
                                return -EINVAL;
@@@ -1040,21 -1041,35 +1040,35 @@@ static int sunxi_pinctrl_build_state(st
        struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
        int i;
  
-       pctl->ngroups = pctl->desc->npins;
+       /*
+        * Allocate groups
+        *
+        * We assume that the number of groups is the number of pins
+        * given in the data array.
  
-       /* Allocate groups */
+        * This will not always be true, since some pins might not be
+        * available in the current variant, but fortunately for us,
+        * this means that the number of pins is the maximum group
+        * number we will ever see.
+        */
        pctl->groups = devm_kzalloc(&pdev->dev,
-                                   pctl->ngroups * sizeof(*pctl->groups),
+                                   pctl->desc->npins * sizeof(*pctl->groups),
                                    GFP_KERNEL);
        if (!pctl->groups)
                return -ENOMEM;
  
        for (i = 0; i < pctl->desc->npins; i++) {
                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
-               struct sunxi_pinctrl_group *group = pctl->groups + i;
+               struct sunxi_pinctrl_group *group = pctl->groups + pctl->ngroups;
+               if (pin->variant && !(pctl->variant & pin->variant))
+                       continue;
  
                group->name = pin->pin.name;
                group->pin = pin->pin.number;
+               /* And now we count the actual number of pins / groups */
+               pctl->ngroups++;
        }
  
        /*
         * we'll reallocate that later anyway
         */
        pctl->functions = devm_kzalloc(&pdev->dev,
-                               pctl->desc->npins * sizeof(*pctl->functions),
-                               GFP_KERNEL);
+                                      pctl->ngroups * sizeof(*pctl->functions),
+                                      GFP_KERNEL);
        if (!pctl->functions)
                return -ENOMEM;
  
        /* Count functions and their associated groups */
        for (i = 0; i < pctl->desc->npins; i++) {
                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
-               struct sunxi_desc_function *func = pin->functions;
+               struct sunxi_desc_function *func;
+               if (pin->variant && !(pctl->variant & pin->variant))
+                       continue;
+               for (func = pin->functions; func->name; func++) {
+                       if (func->variant && !(pctl->variant & func->variant))
+                               continue;
  
-               while (func->name) {
                        /* Create interrupt mapping while we're at it */
                        if (!strcmp(func->name, "irq")) {
                                int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
                        }
  
                        sunxi_pinctrl_add_function(pctl, func->name);
-                       func++;
                }
        }
  
+       /* And now allocated and fill the array for real */
        pctl->functions = krealloc(pctl->functions,
-                               pctl->nfunctions * sizeof(*pctl->functions),
-                               GFP_KERNEL);
+                                  pctl->nfunctions * sizeof(*pctl->functions),
+                                  GFP_KERNEL);
+       if (!pctl->functions) {
+               kfree(pctl->functions);
+               return -ENOMEM;
+       }
  
        for (i = 0; i < pctl->desc->npins; i++) {
                const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
-               struct sunxi_desc_function *func = pin->functions;
+               struct sunxi_desc_function *func;
  
-               while (func->name) {
+               if (pin->variant && !(pctl->variant & pin->variant))
+                       continue;
+               for (func = pin->functions; func->name; func++) {
                        struct sunxi_pinctrl_function *func_item;
                        const char **func_grp;
  
+                       if (func->variant && !(pctl->variant & func->variant))
+                               continue;
                        func_item = sunxi_pinctrl_find_function_by_name(pctl,
                                                                        func->name);
                        if (!func_item)
                                func_grp++;
  
                        *func_grp = pin->pin.name;
-                       func++;
                }
        }
  
@@@ -1207,15 -1237,16 +1236,16 @@@ static int sunxi_pinctrl_setup_debounce
        return 0;
  }
  
- int sunxi_pinctrl_init(struct platform_device *pdev,
-                      const struct sunxi_pinctrl_desc *desc)
+ int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
+                                   const struct sunxi_pinctrl_desc *desc,
+                                   unsigned long variant)
  {
        struct device_node *node = pdev->dev.of_node;
        struct pinctrl_desc *pctrl_desc;
        struct pinctrl_pin_desc *pins;
        struct sunxi_pinctrl *pctl;
        struct resource *res;
-       int i, ret, last_pin;
+       int i, ret, last_pin, pin_idx;
        struct clk *clk;
  
        pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
  
        pctl->dev = &pdev->dev;
        pctl->desc = desc;
+       pctl->variant = variant;
  
        pctl->irq_array = devm_kcalloc(&pdev->dev,
                                       IRQ_PER_BANK * pctl->desc->irq_banks,
        if (!pins)
                return -ENOMEM;
  
-       for (i = 0; i < pctl->desc->npins; i++)
-               pins[i] = pctl->desc->pins[i].pin;
+       for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) {
+               const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
+               if (pin->variant && !(pctl->variant & pin->variant))
+                       continue;
+               pins[pin_idx++] = pin->pin;
+       }
  
        pctrl_desc = devm_kzalloc(&pdev->dev,
                                  sizeof(*pctrl_desc),
        pctrl_desc->name = dev_name(&pdev->dev);
        pctrl_desc->owner = THIS_MODULE;
        pctrl_desc->pins = pins;
-       pctrl_desc->npins = pctl->desc->npins;
+       pctrl_desc->npins = pctl->ngroups;
        pctrl_desc->confops = &sunxi_pconf_ops;
        pctrl_desc->pctlops = &sunxi_pctrl_ops;
        pctrl_desc->pmxops =  &sunxi_pmx_ops;