From: Al Stone ahs3@redhat.com
This adds another GPIO/pinctrl device to Arndale. In the process, logic errors in the portions of the Samsung pinctrl driver that were using ACPI were weeded out.
Al Stone (2): ACPI: ARM: arndale: move GPIO controller 3 of 4 from FDT to ACPI ACPI: ARM: arndale: Enable pinctrl for configuring many controllers via ACPI
arch/arm/boot/dts/exynos5250-arndale.dts | 26 +++++++++++++++ arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +- arch/arm/boot/dts/exynos5250.dtsi | 6 ++-- drivers/pinctrl/pinctrl-samsung.c | 53 ++++++++++++++++--------------- 4 files changed, 59 insertions(+), 28 deletions(-)
From: Al Stone ahs3@redhat.com
These are the FDT changes only.
Signed-off-by: Al Stone al.stone@linaro.org --- arch/arm/boot/dts/exynos5250-arndale.dts | 26 ++++++++++++++++++++++++++ arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +- arch/arm/boot/dts/exynos5250.dtsi | 6 ++++-- 3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 3937993..95c08e7 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -485,4 +485,30 @@ rtc { status = "okay"; }; + + leds { + compatible = "gpio-leds"; + + user1 { + label = "D12"; + gpios = <&gpy6 5 1 0 0>; + linux,default-trigger = "heartbeat"; + }; + + user2 { + label = "D13"; + gpios = <&gpy6 6 1 0 0>; + }; + + user3 { + label = "D14"; + gpios = <&gpy6 7 1 0 0>; + }; + + user4 { + label = "D15"; + gpios = <&gpy6 4 1 0 0>; + }; + }; + }; diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi index 03f5b89..7e26955 100644 --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi @@ -708,6 +708,7 @@ }; };
+ /* moved to ACPI pinctrl@10d10000 { gpv0: gpv0 { gpio-controller; @@ -770,7 +771,6 @@ }; };
- /* moved to ACPI pinctrl@03860000 { gpz: gpz { gpio-controller; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index f7aa20f..515f79e 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -48,8 +48,10 @@ i2c8 = &i2c_8; pinctrl0 = &pinctrl_0; pinctrl1 = &pinctrl_1; + /* Moved to ACPI pinctrl2 = &pinctrl_2; - /* pinctrl3 = &pinctrl_3; */ + pinctrl3 = &pinctrl_3; + */ };
cpus { @@ -146,13 +148,13 @@ interrupts = <0 45 0>; };
+ /* Moved to ACPI pinctrl_2: pinctrl@10d10000 { compatible = "samsung,exynos5250-pinctrl"; reg = <0x10d10000 0x1000>; interrupts = <0 50 0>; };
- /* pinctrl_3: pinctrl@03860000 { compatible = "samsung,exynos5250-pinctrl"; reg = <0x03860000 0x1000>;
W dniu 30.08.2013 02:07, al.stone@linaro.org pisze:
From: Al Stone ahs3@redhat.com
These are the FDT changes only.
Signed-off-by: Al Stone al.stone@linaro.org
arch/arm/boot/dts/exynos5250-arndale.dts | 26 ++++++++++++++++++++++++++ arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +- arch/arm/boot/dts/exynos5250.dtsi | 6 ++++-- 3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 3937993..95c08e7 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -485,4 +485,30 @@ rtc { status = "okay"; };
- leds {
compatible = "gpio-leds";
user1 {
label = "D12";
gpios = <&gpy6 5 1 0 0>;
linux,default-trigger = "heartbeat";
};
user2 {
label = "D13";
gpios = <&gpy6 6 1 0 0>;
};
user3 {
label = "D14";
gpios = <&gpy6 7 1 0 0>;
};
user4 {
label = "D15";
gpios = <&gpy6 4 1 0 0>;
};
- };
- };
Is it necessary to transform GPIO to ACPI ? Looks weird we add code to DTS files to enable ACPI :)
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi index 03f5b89..7e26955 100644 --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi @@ -708,6 +708,7 @@ }; };
- /* moved to ACPI pinctrl@10d10000 { gpv0: gpv0 { gpio-controller;
@@ -770,7 +771,6 @@ }; };
- /* moved to ACPI pinctrl@03860000 { gpz: gpz { gpio-controller;
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index f7aa20f..515f79e 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -48,8 +48,10 @@ i2c8 = &i2c_8; pinctrl0 = &pinctrl_0; pinctrl1 = &pinctrl_1;
pinctrl2 = &pinctrl_2;/* Moved to ACPI
/* pinctrl3 = &pinctrl_3; */
pinctrl3 = &pinctrl_3;
*/
};
cpus {
@@ -146,13 +148,13 @@ interrupts = <0 45 0>; };
- /* Moved to ACPI pinctrl_2: pinctrl@10d10000 { compatible = "samsung,exynos5250-pinctrl"; reg = <0x10d10000 0x1000>; interrupts = <0 50 0>; };
- /* pinctrl_3: pinctrl@03860000 { compatible = "samsung,exynos5250-pinctrl"; reg = <0x03860000 0x1000>;
On 08/30/2013 03:44 AM, Tomasz Nowicki wrote:
W dniu 30.08.2013 02:07, al.stone@linaro.org pisze:
From: Al Stone ahs3@redhat.com
These are the FDT changes only.
Signed-off-by: Al Stone al.stone@linaro.org
arch/arm/boot/dts/exynos5250-arndale.dts | 26 ++++++++++++++++++++++++++ arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +- arch/arm/boot/dts/exynos5250.dtsi | 6 ++++-- 3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 3937993..95c08e7 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -485,4 +485,30 @@ rtc { status = "okay"; };
- leds {
compatible = "gpio-leds";
user1 {
label = "D12";
gpios = <&gpy6 5 1 0 0>;
linux,default-trigger = "heartbeat";
};
user2 {
label = "D13";
gpios = <&gpy6 6 1 0 0>;
};
user3 {
label = "D14";
gpios = <&gpy6 7 1 0 0>;
};
user4 {
label = "D15";
gpios = <&gpy6 4 1 0 0>;
};
- };
- };
Is it necessary to transform GPIO to ACPI ? Looks weird we add code to DTS files to enable ACPI :)
/me laughs at himself :-)
No, those are not needed. Those were part of some playing I was doing with the LEDs on the board and should not be in the patch. Sorry about that -- on the plus side, I've got some scripts that make nice patterns with the LEDs :).
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);
W dniu 30.08.2013 02:07, al.stone@linaro.org pisze:
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;
Up to here patches are applying fine, later it failed. I was trying to apply it against "[Linaro-acpi] [PATCH 0/6 v2] First of the Arndale GPIO/pinctrl patches" patch set and I can't find the reason why... seem to be because of white spaces...
/* 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) {
ACPI_FREE(buf.pointer); ACPI_FREE(info.pointer); devm_kfree(dev, pname);dev_err(dev, "cannot alloc function name space for %s\n", (char *)name_buffer.pointer);
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) {
ACPI_FREE(buf.pointer); ACPI_FREE(info.pointer); devm_kfree(dev, pname);dev_err(dev, "too many pin functions defined for %s\n", (char *)name_buffer.pointer);
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);
Well done!
Acked-by: Tomasz Nowicki tomasz.nowicki@linaro.org