From: Al Stone ahs3@redhat.com
Correct logic where assumptions had been made when trying to configure a single Samsung pinctrl device via ACPI. Tested via enabling both controllers 3 and 4 of the 4 available.
Signed-off-by: Al Stone al.stone@linaro.org --- drivers/pinctrl/pinctrl-samsung.c | 53 +++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 25 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 5817eb6..c5e3e62 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -830,7 +830,7 @@ static acpi_status samsung_acpi_read_banks(acpi_handle handle, u32 level, devm_kfree(drvdata->dev, bank->type); return status; } - bank->pin_base = (u32)value; + bank->pin_base = (u32)value + ctrl->nr_pins;
status = acpi_evaluate_integer(handle, "NPIN", NULL, &value); if (ACPI_FAILURE(status)) { @@ -842,6 +842,8 @@ static acpi_status samsung_acpi_read_banks(acpi_handle handle, u32 level, } bank->nr_pins = (u32)value; ctrl->nr_pins += bank->nr_pins; + bank->gpio_chip.base = pin_base; + pin_base += bank->nr_pins;
bank->name = tag; bank->acpi_node = &drvdata->dev->acpi_node; @@ -899,7 +901,6 @@ static int samsung_pin_ctrl_acpi_parse( dev_err(dev, "failure walking controller for banks\n"); return -EINVAL; } - pin_base += ctrl->nr_pins;
return 0; } @@ -933,7 +934,7 @@ static acpi_status samsung_acpi_read_group(acpi_handle handle, u32 level, if (grp->num_pins == 0) break; } - if (!grp || ii >= drvdata->nr_groups) { + if (!grp && ii >= drvdata->nr_groups) { dev_err(dev, "too many pin groups defined for %s\n", (char *)name_buffer.pointer); return AE_BAD_PARAMETER; @@ -1025,32 +1026,40 @@ static acpi_status samsung_acpi_read_group(acpi_handle handle, u32 level, grp->pins = pins;
/* set up the functions */ - pmx = (struct samsung_pmx_func *)&drvdata->pmx_functions[0]; - for (ii = 0; ii < drvdata->nr_functions; ii++, pmx++) { - if (!pmx->name) - break; - } - if (!pmx || ii >= drvdata->nr_functions) { - dev_err(dev, "too many pin functions defined for %s\n", + len = strlen((char *)name_buffer.pointer); + pname2 = devm_kzalloc(dev, len + FSUFFIX_LEN + 1, GFP_KERNEL); + if (!pname2) { + dev_err(dev, "cannot alloc function name space for %s\n", (char *)name_buffer.pointer); ACPI_FREE(buf.pointer); ACPI_FREE(info.pointer); devm_kfree(dev, pname); - return AE_BAD_PARAMETER; + return AE_NO_MEMORY; } + memcpy(pname2, (char *)name_buffer.pointer, len); + memcpy(pname2 + len, FUNCTION_SUFFIX, FSUFFIX_LEN);
- len = strlen(grp->name); - pname2 = devm_kzalloc(dev, len + FSUFFIX_LEN + 1, GFP_KERNEL); - if (!pname2) { - dev_err(dev, "cannot alloc function name space for %s \n", + pmx = (struct samsung_pmx_func *)drvdata->pmx_functions; + for (ii = 0; ii < drvdata->nr_functions; ii++, pmx++) { + if (pmx->name) + if (strncmp(pmx->name, pname2, strlen(pname2)) == 0) + break; + } + if (ii >= drvdata->nr_functions) { + pmx = (struct samsung_pmx_func *)drvdata->pmx_functions; + for (ii = 0; ii < drvdata->nr_functions; ii++, pmx++) + if (!pmx->name) + break; + } + if (ii >= drvdata->nr_functions) { + dev_err(dev, "too many pin functions defined for %s\n", (char *)name_buffer.pointer); ACPI_FREE(buf.pointer); ACPI_FREE(info.pointer); devm_kfree(dev, pname); - return AE_NO_MEMORY; + devm_kfree(dev, pname2); + return AE_BAD_PARAMETER; } - memcpy(pname2, grp->name, len); - memcpy(pname2 + len, FUNCTION_SUFFIX, FSUFFIX_LEN); pmx->name = pname2;
ACPI_FREE(info.pointer); @@ -1082,6 +1091,7 @@ static int samsung_pin_group_acpi_parse( return -EINVAL; } gcnt = (int)value; + fcnt = gcnt;
grps = devm_kzalloc(dev, gcnt * sizeof(*grps), GFP_KERNEL); if (!grps) { @@ -1089,13 +1099,6 @@ static int samsung_pin_group_acpi_parse( return -EINVAL; }
- status = acpi_evaluate_integer(dev_handle, "NFUN", NULL, &value); - if (ACPI_FAILURE(status)) { - dev_err(dev, "cannot get NFUN value\n"); - return -EINVAL; - } - fcnt = (int)value; - funcs = devm_kzalloc(dev, fcnt * sizeof(*funcs), GFP_KERNEL); if (!funcs) { devm_kfree(dev, grps);