Merge tag 'pinctrl-v5.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2022 19:24:04 +0000 (12:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Jul 2022 19:24:04 +0000 (12:24 -0700)
Pull pin control fixes from Linus Walleij:
 "Only driver fixes:

   - NULL check for the ralink and sunplus drivers

   - Add Jacky Bai as maintainer for the Freescale pin controllers

   - Fix pin config ops for the Ocelot LAN966x and SparX5

   - Disallow AMD pin control to be a module: the GPIO lines need to be
     active in early boot, so no can do

   - Fix the Armada 37xx to use raw spinlocks in the interrupt handler
     path to avoid wait context"

* tag 'pinctrl-v5.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: armada-37xx: use raw spinlocks for regmap to avoid invalid wait context
  pinctrl: armada-37xx: make irq_lock a raw spinlock to avoid invalid wait context
  pinctrl: Don't allow PINCTRL_AMD to be a module
  pinctrl: ocelot: Fix pincfg
  pinctrl: ocelot: Fix pincfg for lan966x
  MAINTAINERS: Update freescale pin controllers maintainer
  pinctrl: sunplus: Add check for kcalloc
  pinctrl: ralink: Check for null return of devm_kcalloc

MAINTAINERS
drivers/pinctrl/Kconfig
drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
drivers/pinctrl/pinctrl-ocelot.c
drivers/pinctrl/ralink/pinctrl-ralink.c
drivers/pinctrl/sunplus/sppctl.c

index 651616e..64379c6 100644 (file)
@@ -15849,7 +15849,7 @@ PIN CONTROLLER - FREESCALE
 M:     Dong Aisheng <aisheng.dong@nxp.com>
 M:     Fabio Estevam <festevam@gmail.com>
 M:     Shawn Guo <shawnguo@kernel.org>
-M:     Stefan Agner <stefan@agner.ch>
+M:     Jacky Bai <ping.bai@nxp.com>
 R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 L:     linux-gpio@vger.kernel.org
 S:     Maintained
index f52960d..bff144c 100644 (file)
@@ -32,7 +32,7 @@ config DEBUG_PINCTRL
          Say Y here to add some extra checks and diagnostics to PINCTRL calls.
 
 config PINCTRL_AMD
-       tristate "AMD GPIO pin control"
+       bool "AMD GPIO pin control"
        depends on HAS_IOMEM
        depends on ACPI || COMPILE_TEST
        select GPIOLIB
index a140b6b..bcde042 100644 (file)
@@ -102,7 +102,7 @@ struct armada_37xx_pinctrl {
        struct device                   *dev;
        struct gpio_chip                gpio_chip;
        struct irq_chip                 irq_chip;
-       spinlock_t                      irq_lock;
+       raw_spinlock_t                  irq_lock;
        struct pinctrl_desc             pctl;
        struct pinctrl_dev              *pctl_dev;
        struct armada_37xx_pin_group    *groups;
@@ -523,9 +523,9 @@ static void armada_37xx_irq_ack(struct irq_data *d)
        unsigned long flags;
 
        armada_37xx_irq_update_reg(&reg, d);
-       spin_lock_irqsave(&info->irq_lock, flags);
+       raw_spin_lock_irqsave(&info->irq_lock, flags);
        writel(d->mask, info->base + reg);
-       spin_unlock_irqrestore(&info->irq_lock, flags);
+       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
 }
 
 static void armada_37xx_irq_mask(struct irq_data *d)
@@ -536,10 +536,10 @@ static void armada_37xx_irq_mask(struct irq_data *d)
        unsigned long flags;
 
        armada_37xx_irq_update_reg(&reg, d);
-       spin_lock_irqsave(&info->irq_lock, flags);
+       raw_spin_lock_irqsave(&info->irq_lock, flags);
        val = readl(info->base + reg);
        writel(val & ~d->mask, info->base + reg);
-       spin_unlock_irqrestore(&info->irq_lock, flags);
+       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
 }
 
 static void armada_37xx_irq_unmask(struct irq_data *d)
@@ -550,10 +550,10 @@ static void armada_37xx_irq_unmask(struct irq_data *d)
        unsigned long flags;
 
        armada_37xx_irq_update_reg(&reg, d);
-       spin_lock_irqsave(&info->irq_lock, flags);
+       raw_spin_lock_irqsave(&info->irq_lock, flags);
        val = readl(info->base + reg);
        writel(val | d->mask, info->base + reg);
-       spin_unlock_irqrestore(&info->irq_lock, flags);
+       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
 }
 
 static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
@@ -564,14 +564,14 @@ static int armada_37xx_irq_set_wake(struct irq_data *d, unsigned int on)
        unsigned long flags;
 
        armada_37xx_irq_update_reg(&reg, d);
-       spin_lock_irqsave(&info->irq_lock, flags);
+       raw_spin_lock_irqsave(&info->irq_lock, flags);
        val = readl(info->base + reg);
        if (on)
                val |= (BIT(d->hwirq % GPIO_PER_REG));
        else
                val &= ~(BIT(d->hwirq % GPIO_PER_REG));
        writel(val, info->base + reg);
-       spin_unlock_irqrestore(&info->irq_lock, flags);
+       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
 
        return 0;
 }
@@ -583,7 +583,7 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
        u32 val, reg = IRQ_POL;
        unsigned long flags;
 
-       spin_lock_irqsave(&info->irq_lock, flags);
+       raw_spin_lock_irqsave(&info->irq_lock, flags);
        armada_37xx_irq_update_reg(&reg, d);
        val = readl(info->base + reg);
        switch (type) {
@@ -607,11 +607,11 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
                break;
        }
        default:
-               spin_unlock_irqrestore(&info->irq_lock, flags);
+               raw_spin_unlock_irqrestore(&info->irq_lock, flags);
                return -EINVAL;
        }
        writel(val, info->base + reg);
-       spin_unlock_irqrestore(&info->irq_lock, flags);
+       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
 
        return 0;
 }
@@ -626,7 +626,7 @@ static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
 
        regmap_read(info->regmap, INPUT_VAL + 4*reg_idx, &l);
 
-       spin_lock_irqsave(&info->irq_lock, flags);
+       raw_spin_lock_irqsave(&info->irq_lock, flags);
        p = readl(info->base + IRQ_POL + 4 * reg_idx);
        if ((p ^ l) & (1 << bit_num)) {
                /*
@@ -647,7 +647,7 @@ static int armada_37xx_edge_both_irq_swap_pol(struct armada_37xx_pinctrl *info,
                ret = -1;
        }
 
-       spin_unlock_irqrestore(&info->irq_lock, flags);
+       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
        return ret;
 }
 
@@ -664,11 +664,11 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
                u32 status;
                unsigned long flags;
 
-               spin_lock_irqsave(&info->irq_lock, flags);
+               raw_spin_lock_irqsave(&info->irq_lock, flags);
                status = readl_relaxed(info->base + IRQ_STATUS + 4 * i);
                /* Manage only the interrupt that was enabled */
                status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
-               spin_unlock_irqrestore(&info->irq_lock, flags);
+               raw_spin_unlock_irqrestore(&info->irq_lock, flags);
                while (status) {
                        u32 hwirq = ffs(status) - 1;
                        u32 virq = irq_find_mapping(d, hwirq +
@@ -695,12 +695,12 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
 
 update_status:
                        /* Update status in case a new IRQ appears */
-                       spin_lock_irqsave(&info->irq_lock, flags);
+                       raw_spin_lock_irqsave(&info->irq_lock, flags);
                        status = readl_relaxed(info->base +
                                               IRQ_STATUS + 4 * i);
                        /* Manage only the interrupt that was enabled */
                        status &= readl_relaxed(info->base + IRQ_EN + 4 * i);
-                       spin_unlock_irqrestore(&info->irq_lock, flags);
+                       raw_spin_unlock_irqrestore(&info->irq_lock, flags);
                }
        }
        chained_irq_exit(chip, desc);
@@ -731,7 +731,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev,
        struct device *dev = &pdev->dev;
        unsigned int i, nr_irq_parent;
 
-       spin_lock_init(&info->irq_lock);
+       raw_spin_lock_init(&info->irq_lock);
 
        nr_irq_parent = of_irq_count(np);
        if (!nr_irq_parent) {
@@ -1107,25 +1107,40 @@ static const struct of_device_id armada_37xx_pinctrl_of_match[] = {
        { },
 };
 
+static const struct regmap_config armada_37xx_pinctrl_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .use_raw_spinlock = true,
+};
+
 static int __init armada_37xx_pinctrl_probe(struct platform_device *pdev)
 {
        struct armada_37xx_pinctrl *info;
        struct device *dev = &pdev->dev;
-       struct device_node *np = dev->of_node;
        struct regmap *regmap;
+       void __iomem *base;
        int ret;
 
+       base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+       if (IS_ERR(base)) {
+               dev_err(dev, "failed to ioremap base address: %pe\n", base);
+               return PTR_ERR(base);
+       }
+
+       regmap = devm_regmap_init_mmio(dev, base,
+                                      &armada_37xx_pinctrl_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(dev, "failed to create regmap: %pe\n", regmap);
+               return PTR_ERR(regmap);
+       }
+
        info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
 
        info->dev = dev;
-
-       regmap = syscon_node_to_regmap(np);
-       if (IS_ERR(regmap))
-               return dev_err_probe(dev, PTR_ERR(regmap), "cannot get regmap\n");
        info->regmap = regmap;
-
        info->data = of_device_get_match_data(dev);
 
        ret = armada_37xx_pinctrl_register(pdev, info);
index 5f4a8c5..dfc8ea9 100644 (file)
 #define ocelot_clrsetbits(addr, clear, set) \
        writel((readl(addr) & ~(clear)) | (set), (addr))
 
-/* PINCONFIG bits (sparx5 only) */
 enum {
        PINCONF_BIAS,
        PINCONF_SCHMITT,
        PINCONF_DRIVE_STRENGTH,
 };
 
-#define BIAS_PD_BIT BIT(4)
-#define BIAS_PU_BIT BIT(3)
-#define BIAS_BITS   (BIAS_PD_BIT|BIAS_PU_BIT)
-#define SCHMITT_BIT BIT(2)
-#define DRIVE_BITS  GENMASK(1, 0)
-
 /* GPIO standard registers */
 #define OCELOT_GPIO_OUT_SET    0x0
 #define OCELOT_GPIO_OUT_CLR    0x4
@@ -321,6 +314,13 @@ struct ocelot_pin_caps {
        unsigned char a_functions[OCELOT_FUNC_PER_PIN]; /* Additional functions */
 };
 
+struct ocelot_pincfg_data {
+       u8 pd_bit;
+       u8 pu_bit;
+       u8 drive_bits;
+       u8 schmitt_bit;
+};
+
 struct ocelot_pinctrl {
        struct device *dev;
        struct pinctrl_dev *pctl;
@@ -328,10 +328,16 @@ struct ocelot_pinctrl {
        struct regmap *map;
        struct regmap *pincfg;
        struct pinctrl_desc *desc;
+       const struct ocelot_pincfg_data *pincfg_data;
        struct ocelot_pmx_func func[FUNC_MAX];
        u8 stride;
 };
 
+struct ocelot_match_data {
+       struct pinctrl_desc desc;
+       struct ocelot_pincfg_data pincfg_data;
+};
+
 #define LUTON_P(p, f0, f1)                                             \
 static struct ocelot_pin_caps luton_pin_##p = {                                \
        .pin = p,                                                       \
@@ -1325,24 +1331,27 @@ static int ocelot_hw_get_value(struct ocelot_pinctrl *info,
        int ret = -EOPNOTSUPP;
 
        if (info->pincfg) {
+               const struct ocelot_pincfg_data *opd = info->pincfg_data;
                u32 regcfg;
 
-               ret = regmap_read(info->pincfg, pin, &regcfg);
+               ret = regmap_read(info->pincfg,
+                                 pin * regmap_get_reg_stride(info->pincfg),
+                                 &regcfg);
                if (ret)
                        return ret;
 
                ret = 0;
                switch (reg) {
                case PINCONF_BIAS:
-                       *val = regcfg & BIAS_BITS;
+                       *val = regcfg & (opd->pd_bit | opd->pu_bit);
                        break;
 
                case PINCONF_SCHMITT:
-                       *val = regcfg & SCHMITT_BIT;
+                       *val = regcfg & opd->schmitt_bit;
                        break;
 
                case PINCONF_DRIVE_STRENGTH:
-                       *val = regcfg & DRIVE_BITS;
+                       *val = regcfg & opd->drive_bits;
                        break;
 
                default:
@@ -1359,14 +1368,18 @@ static int ocelot_pincfg_clrsetbits(struct ocelot_pinctrl *info, u32 regaddr,
        u32 val;
        int ret;
 
-       ret = regmap_read(info->pincfg, regaddr, &val);
+       ret = regmap_read(info->pincfg,
+                         regaddr * regmap_get_reg_stride(info->pincfg),
+                         &val);
        if (ret)
                return ret;
 
        val &= ~clrbits;
        val |= setbits;
 
-       ret = regmap_write(info->pincfg, regaddr, val);
+       ret = regmap_write(info->pincfg,
+                          regaddr * regmap_get_reg_stride(info->pincfg),
+                          val);
 
        return ret;
 }
@@ -1379,23 +1392,27 @@ static int ocelot_hw_set_value(struct ocelot_pinctrl *info,
        int ret = -EOPNOTSUPP;
 
        if (info->pincfg) {
+               const struct ocelot_pincfg_data *opd = info->pincfg_data;
 
                ret = 0;
                switch (reg) {
                case PINCONF_BIAS:
-                       ret = ocelot_pincfg_clrsetbits(info, pin, BIAS_BITS,
+                       ret = ocelot_pincfg_clrsetbits(info, pin,
+                                                      opd->pd_bit | opd->pu_bit,
                                                       val);
                        break;
 
                case PINCONF_SCHMITT:
-                       ret = ocelot_pincfg_clrsetbits(info, pin, SCHMITT_BIT,
+                       ret = ocelot_pincfg_clrsetbits(info, pin,
+                                                      opd->schmitt_bit,
                                                       val);
                        break;
 
                case PINCONF_DRIVE_STRENGTH:
                        if (val <= 3)
                                ret = ocelot_pincfg_clrsetbits(info, pin,
-                                                              DRIVE_BITS, val);
+                                                              opd->drive_bits,
+                                                              val);
                        else
                                ret = -EINVAL;
                        break;
@@ -1425,17 +1442,20 @@ static int ocelot_pinconf_get(struct pinctrl_dev *pctldev,
                if (param == PIN_CONFIG_BIAS_DISABLE)
                        val = (val == 0);
                else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
-                       val = (val & BIAS_PD_BIT ? true : false);
+                       val = !!(val & info->pincfg_data->pd_bit);
                else    /* PIN_CONFIG_BIAS_PULL_UP */
-                       val = (val & BIAS_PU_BIT ? true : false);
+                       val = !!(val & info->pincfg_data->pu_bit);
                break;
 
        case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+               if (!info->pincfg_data->schmitt_bit)
+                       return -EOPNOTSUPP;
+
                err = ocelot_hw_get_value(info, pin, PINCONF_SCHMITT, &val);
                if (err)
                        return err;
 
-               val = (val & SCHMITT_BIT ? true : false);
+               val = !!(val & info->pincfg_data->schmitt_bit);
                break;
 
        case PIN_CONFIG_DRIVE_STRENGTH:
@@ -1479,6 +1499,7 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                              unsigned long *configs, unsigned int num_configs)
 {
        struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+       const struct ocelot_pincfg_data *opd = info->pincfg_data;
        u32 param, arg, p;
        int cfg, err = 0;
 
@@ -1491,8 +1512,8 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                case PIN_CONFIG_BIAS_PULL_UP:
                case PIN_CONFIG_BIAS_PULL_DOWN:
                        arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
-                       (param == PIN_CONFIG_BIAS_PULL_UP) ? BIAS_PU_BIT :
-                       BIAS_PD_BIT;
+                             (param == PIN_CONFIG_BIAS_PULL_UP) ?
+                               opd->pu_bit : opd->pd_bit;
 
                        err = ocelot_hw_set_value(info, pin, PINCONF_BIAS, arg);
                        if (err)
@@ -1501,7 +1522,10 @@ static int ocelot_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        break;
 
                case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-                       arg = arg ? SCHMITT_BIT : 0;
+                       if (!opd->schmitt_bit)
+                               return -EOPNOTSUPP;
+
+                       arg = arg ? opd->schmitt_bit : 0;
                        err = ocelot_hw_set_value(info, pin, PINCONF_SCHMITT,
                                                  arg);
                        if (err)
@@ -1562,69 +1586,94 @@ static const struct pinctrl_ops ocelot_pctl_ops = {
        .dt_free_map = pinconf_generic_dt_free_map,
 };
 
-static struct pinctrl_desc luton_desc = {
-       .name = "luton-pinctrl",
-       .pins = luton_pins,
-       .npins = ARRAY_SIZE(luton_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &ocelot_pmx_ops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data luton_desc = {
+       .desc = {
+               .name = "luton-pinctrl",
+               .pins = luton_pins,
+               .npins = ARRAY_SIZE(luton_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &ocelot_pmx_ops,
+               .owner = THIS_MODULE,
+       },
 };
 
-static struct pinctrl_desc serval_desc = {
-       .name = "serval-pinctrl",
-       .pins = serval_pins,
-       .npins = ARRAY_SIZE(serval_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &ocelot_pmx_ops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data serval_desc = {
+       .desc = {
+               .name = "serval-pinctrl",
+               .pins = serval_pins,
+               .npins = ARRAY_SIZE(serval_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &ocelot_pmx_ops,
+               .owner = THIS_MODULE,
+       },
 };
 
-static struct pinctrl_desc ocelot_desc = {
-       .name = "ocelot-pinctrl",
-       .pins = ocelot_pins,
-       .npins = ARRAY_SIZE(ocelot_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &ocelot_pmx_ops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data ocelot_desc = {
+       .desc = {
+               .name = "ocelot-pinctrl",
+               .pins = ocelot_pins,
+               .npins = ARRAY_SIZE(ocelot_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &ocelot_pmx_ops,
+               .owner = THIS_MODULE,
+       },
 };
 
-static struct pinctrl_desc jaguar2_desc = {
-       .name = "jaguar2-pinctrl",
-       .pins = jaguar2_pins,
-       .npins = ARRAY_SIZE(jaguar2_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &ocelot_pmx_ops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data jaguar2_desc = {
+       .desc = {
+               .name = "jaguar2-pinctrl",
+               .pins = jaguar2_pins,
+               .npins = ARRAY_SIZE(jaguar2_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &ocelot_pmx_ops,
+               .owner = THIS_MODULE,
+       },
 };
 
-static struct pinctrl_desc servalt_desc = {
-       .name = "servalt-pinctrl",
-       .pins = servalt_pins,
-       .npins = ARRAY_SIZE(servalt_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &ocelot_pmx_ops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data servalt_desc = {
+       .desc = {
+               .name = "servalt-pinctrl",
+               .pins = servalt_pins,
+               .npins = ARRAY_SIZE(servalt_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &ocelot_pmx_ops,
+               .owner = THIS_MODULE,
+       },
 };
 
-static struct pinctrl_desc sparx5_desc = {
-       .name = "sparx5-pinctrl",
-       .pins = sparx5_pins,
-       .npins = ARRAY_SIZE(sparx5_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &ocelot_pmx_ops,
-       .confops = &ocelot_confops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data sparx5_desc = {
+       .desc = {
+               .name = "sparx5-pinctrl",
+               .pins = sparx5_pins,
+               .npins = ARRAY_SIZE(sparx5_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &ocelot_pmx_ops,
+               .confops = &ocelot_confops,
+               .owner = THIS_MODULE,
+       },
+       .pincfg_data = {
+               .pd_bit = BIT(4),
+               .pu_bit = BIT(3),
+               .drive_bits = GENMASK(1, 0),
+               .schmitt_bit = BIT(2),
+       },
 };
 
-static struct pinctrl_desc lan966x_desc = {
-       .name = "lan966x-pinctrl",
-       .pins = lan966x_pins,
-       .npins = ARRAY_SIZE(lan966x_pins),
-       .pctlops = &ocelot_pctl_ops,
-       .pmxops = &lan966x_pmx_ops,
-       .confops = &ocelot_confops,
-       .owner = THIS_MODULE,
+static struct ocelot_match_data lan966x_desc = {
+       .desc = {
+               .name = "lan966x-pinctrl",
+               .pins = lan966x_pins,
+               .npins = ARRAY_SIZE(lan966x_pins),
+               .pctlops = &ocelot_pctl_ops,
+               .pmxops = &lan966x_pmx_ops,
+               .confops = &ocelot_confops,
+               .owner = THIS_MODULE,
+       },
+       .pincfg_data = {
+               .pd_bit = BIT(3),
+               .pu_bit = BIT(2),
+               .drive_bits = GENMASK(1, 0),
+       },
 };
 
 static int ocelot_create_group_func_map(struct device *dev,
@@ -1890,7 +1939,8 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
        {},
 };
 
-static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
+static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev,
+                                                  const struct ocelot_pinctrl *info)
 {
        void __iomem *base;
 
@@ -1898,7 +1948,7 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
                .reg_bits = 32,
                .val_bits = 32,
                .reg_stride = 4,
-               .max_register = 32,
+               .max_register = info->desc->npins * 4,
                .name = "pincfg",
        };
 
@@ -1913,6 +1963,7 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
 
 static int ocelot_pinctrl_probe(struct platform_device *pdev)
 {
+       const struct ocelot_match_data *data;
        struct device *dev = &pdev->dev;
        struct ocelot_pinctrl *info;
        struct reset_control *reset;
@@ -1929,7 +1980,16 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
        if (!info)
                return -ENOMEM;
 
-       info->desc = (struct pinctrl_desc *)device_get_match_data(dev);
+       data = device_get_match_data(dev);
+       if (!data)
+               return -EINVAL;
+
+       info->desc = devm_kmemdup(dev, &data->desc, sizeof(*info->desc),
+                                 GFP_KERNEL);
+       if (!info->desc)
+               return -ENOMEM;
+
+       info->pincfg_data = &data->pincfg_data;
 
        reset = devm_reset_control_get_optional_shared(dev, "switch");
        if (IS_ERR(reset))
@@ -1956,7 +2016,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 
        /* Pinconf registers */
        if (info->desc->confops) {
-               pincfg = ocelot_pinctrl_create_pincfg(pdev);
+               pincfg = ocelot_pinctrl_create_pincfg(pdev, info);
                if (IS_ERR(pincfg))
                        dev_dbg(dev, "Failed to create pincfg regmap\n");
                else
index 63429a2..770862f 100644 (file)
@@ -266,6 +266,8 @@ static int ralink_pinctrl_pins(struct ralink_priv *p)
                                                p->func[i]->pin_count,
                                                sizeof(int),
                                                GFP_KERNEL);
+               if (!p->func[i]->pins)
+                       return -ENOMEM;
                for (j = 0; j < p->func[i]->pin_count; j++)
                        p->func[i]->pins[j] = p->func[i]->pin_first + j;
 
index 3ba4704..2b3335a 100644 (file)
@@ -871,6 +871,9 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node
        }
 
        *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
+       if (*map == NULL)
+               return -ENOMEM;
+
        for (i = 0; i < (*num_maps); i++) {
                dt_pin = be32_to_cpu(list[i]);
                pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);