--- zzzz-none-000/linux-3.10.107/drivers/pinctrl/pinmux.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/pinctrl/pinmux.c 2021-02-04 17:41:59.000000000 +0000 @@ -41,7 +41,7 @@ !ops->get_functions_count || !ops->get_function_name || !ops->get_function_groups || - !ops->enable) { + !ops->set_mux) { dev_err(pctldev->dev, "pinmux ops lacks necessary functions\n"); return -EINVAL; } @@ -107,6 +107,13 @@ desc->name, desc->gpio_owner, owner); goto out; } + if (ops->strict && desc->mux_usecount && + strcmp(desc->mux_owner, owner)) { + dev_err(pctldev->dev, + "pin %s already requested by %s; cannot claim for %s\n", + desc->name, desc->mux_owner, owner); + goto out; + } desc->gpio_owner = owner; } else { @@ -116,6 +123,12 @@ desc->name, desc->mux_owner, owner); goto out; } + if (ops->strict && desc->gpio_owner) { + dev_err(pctldev->dev, + "pin %s already requested by %s; cannot claim for %s\n", + desc->name, desc->gpio_owner, owner); + goto out; + } desc->mux_usecount++; if (desc->mux_usecount > 1) @@ -300,8 +313,7 @@ /* See if this pctldev has this function */ while (selector < nfuncs) { - const char *fname = ops->get_function_name(pctldev, - selector); + const char *fname = ops->get_function_name(pctldev, selector); if (!strcmp(function, fname)) return selector; @@ -309,8 +321,7 @@ selector++; } - pr_err("%s does not support function %s\n", - pinctrl_dev_get_name(pctldev), function); + dev_err(pctldev->dev, "function '%s' not supported\n", function); return -EINVAL; } @@ -391,19 +402,25 @@ struct pinctrl_dev *pctldev = setting->pctldev; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; const struct pinmux_ops *ops = pctldev->desc->pmxops; - int ret; - const unsigned *pins; - unsigned num_pins; + int ret = 0; + const unsigned *pins = NULL; + unsigned num_pins = 0; int i; struct pin_desc *desc; - ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, - &pins, &num_pins); + if (pctlops->get_group_pins) + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, + &pins, &num_pins); + if (ret) { + const char *gname; + /* errors only affect debug data, so just warn */ + gname = pctlops->get_group_name(pctldev, + setting->data.mux.group); dev_warn(pctldev->dev, - "could not get pins for group selector %d\n", - setting->data.mux.group); + "could not get pins for group %s\n", + gname); num_pins = 0; } @@ -411,9 +428,18 @@ for (i = 0; i < num_pins; i++) { ret = pin_request(pctldev, pins[i], setting->dev_name, NULL); if (ret) { + const char *gname; + const char *pname; + + desc = pin_desc_get(pctldev, pins[i]); + pname = desc ? desc->name : "non-existing"; + gname = pctlops->get_group_name(pctldev, + setting->data.mux.group); dev_err(pctldev->dev, - "could not request pin %d on device %s\n", - pins[i], pinctrl_dev_get_name(pctldev)); + "could not request pin %d (%s) from group %s " + " on device %s\n", + pins[i], pname, gname, + pinctrl_dev_get_name(pctldev)); goto err_pin_request; } } @@ -430,15 +456,15 @@ desc->mux_setting = &(setting->data.mux); } - ret = ops->enable(pctldev, setting->data.mux.func, - setting->data.mux.group); + ret = ops->set_mux(pctldev, setting->data.mux.func, + setting->data.mux.group); if (ret) - goto err_enable; + goto err_set_mux; return 0; -err_enable: +err_set_mux: for (i = 0; i < num_pins; i++) { desc = pin_desc_get(pctldev, pins[i]); if (desc) @@ -456,20 +482,24 @@ { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const struct pinmux_ops *ops = pctldev->desc->pmxops; - int ret; - const unsigned *pins; - unsigned num_pins; + int ret = 0; + const unsigned *pins = NULL; + unsigned num_pins = 0; int i; struct pin_desc *desc; - ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, - &pins, &num_pins); + if (pctlops->get_group_pins) + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, + &pins, &num_pins); if (ret) { + const char *gname; + /* errors only affect debug data, so just warn */ + gname = pctlops->get_group_name(pctldev, + setting->data.mux.group); dev_warn(pctldev->dev, - "could not get pins for group selector %d\n", - setting->data.mux.group); + "could not get pins for group %s\n", + gname); num_pins = 0; } @@ -482,15 +512,22 @@ pins[i]); continue; } - desc->mux_setting = NULL; - } - - /* And release the pins */ - for (i = 0; i < num_pins; i++) - pin_free(pctldev, pins[i], NULL); + if (desc->mux_setting == &(setting->data.mux)) { + desc->mux_setting = NULL; + /* And release the pin */ + pin_free(pctldev, pins[i], NULL); + } else { + const char *gname; - if (ops->disable) - ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); + gname = pctlops->get_group_name(pctldev, + setting->data.mux.group); + dev_warn(pctldev->dev, + "not freeing pin %d (%s) as part of " + "deactivating group %s - it is already " + "used for some other setting", + pins[i], desc->name, gname); + } + } } #ifdef CONFIG_DEBUG_FS @@ -518,9 +555,12 @@ ret = pmxops->get_function_groups(pctldev, func_selector, &groups, &num_groups); - if (ret) + if (ret) { seq_printf(s, "function %s: COULD NOT GET GROUPS\n", func); + func_selector++; + continue; + } seq_printf(s, "function: %s, groups = [ ", func); for (i = 0; i < num_groups; i++) @@ -546,7 +586,12 @@ return 0; seq_puts(s, "Pinmux settings per pin\n"); - seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n"); + if (pmxops->strict) + seq_puts(s, + "Format: pin (name): mux_owner|gpio_owner (strict) hog?\n"); + else + seq_puts(s, + "Format: pin (name): mux_owner gpio_owner hog?\n"); mutex_lock(&pctldev->mutex); @@ -565,14 +610,34 @@ !strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev))) is_hog = true; - seq_printf(s, "pin %d (%s): %s %s%s", pin, - desc->name ? desc->name : "unnamed", - desc->mux_owner ? desc->mux_owner - : "(MUX UNCLAIMED)", - desc->gpio_owner ? desc->gpio_owner - : "(GPIO UNCLAIMED)", - is_hog ? " (HOG)" : ""); + if (pmxops->strict) { + if (desc->mux_owner) + seq_printf(s, "pin %d (%s): device %s%s", + pin, + desc->name ? desc->name : "unnamed", + desc->mux_owner, + is_hog ? " (HOG)" : ""); + else if (desc->gpio_owner) + seq_printf(s, "pin %d (%s): GPIO %s", + pin, + desc->name ? desc->name : "unnamed", + desc->gpio_owner); + else + seq_printf(s, "pin %d (%s): UNCLAIMED", + pin, + desc->name ? desc->name : "unnamed"); + } else { + /* For non-strict controllers */ + seq_printf(s, "pin %d (%s): %s %s%s", pin, + desc->name ? desc->name : "unnamed", + desc->mux_owner ? desc->mux_owner + : "(MUX UNCLAIMED)", + desc->gpio_owner ? desc->gpio_owner + : "(GPIO UNCLAIMED)", + is_hog ? " (HOG)" : ""); + } + /* If mux: print function+group claiming the pin */ if (desc->mux_setting) seq_printf(s, " function %s group %s\n", pmxops->get_function_name(pctldev,