2022-03-28 15:31:23

by Caleb Connolly

[permalink] [raw]
Subject: [PATCH 0/4] rockchip: support configuring pins as input

Add support for configuring pins as input to the rockchip pinctrl
driver. This is required for example for devices which use non-standard
configurations for gpio interrupts, specifically for the light/proximity
sensor on the RK3399 powered PinePhone Pro (which will be coming
upstream in a future patch series).

Due to the complicated layout of the RK pinctrl/gpio drivers, some extra
work is required to handle deferring the GPIO configuration. On RK3399
the pinctrl driver always probes before the GPIO controller driver, so
the PIN_CONFIG_OUTPUT and PIN_CONFIG_INPUT_ENABLE params both have to be
deferred, this series also reworks the deferred pin handling to be
generic and support any param rather than only the PIN_CONFIG_OUTPUT
param.

---
Caleb Connolly (4):
pinctrl/rockchip: support deferring other gpio params
pinctrl/rockchip: support setting input-enable param
gpio/rockchip: handle deferring input-enable pinconfs
arm64: dts: rockchip: rk3399: add an input enable pinconf

arch/arm64/boot/dts/rockchip/rk3399.dtsi | 16 ++++++
drivers/gpio/gpio-rockchip.c | 29 ++++++++---
drivers/pinctrl/pinctrl-rockchip.c | 64 +++++++++++++++---------
drivers/pinctrl/pinctrl-rockchip.h | 7 ++-
4 files changed, 81 insertions(+), 35 deletions(-)

--
2.35.1


2022-03-28 19:49:50

by Caleb Connolly

[permalink] [raw]
Subject: [PATCH 2/4] pinctrl/rockchip: support setting input-enable param

Handle the PIN_CONFIG_INPUT_ENABLE param for configuring GPIOs as input.

Signed-off-by: Caleb Connolly <[email protected]>
---
drivers/pinctrl/pinctrl-rockchip.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index d54fc1cdf609..9d50d9756bb9 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2129,7 +2129,7 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);

- if (param == (PIN_CONFIG_OUTPUT | PIN_CONFIG_INPUT_ENABLE)) {
+ if (param == PIN_CONFIG_OUTPUT || param == PIN_CONFIG_INPUT_ENABLE) {
/*
* Check for gpio driver not being probed yet.
* The lock makes sure that either gpio-probe has completed
@@ -2181,6 +2181,16 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc)
return rc;
break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ rc = rockchip_set_mux(bank, pin - bank->pin_base,
+ RK_FUNC_GPIO);
+ if (rc != RK_FUNC_GPIO)
+ return -EINVAL;
+
+ rc = gpio->direction_input(gpio, pin - bank->pin_base);
+ if (rc)
+ return rc;
+ break;
case PIN_CONFIG_DRIVE_STRENGTH:
/* rk3288 is the first with per-pin drive-strength */
if (!info->ctrl->drv_calc_reg)
--
2.35.1

2022-03-28 22:39:18

by Caleb Connolly

[permalink] [raw]
Subject: [PATCH 1/4] pinctrl/rockchip: support deferring other gpio params

Add support for deferring other params like PIN_CONFIG_INPUT_ENABLE.
This will be used to add support for PIN_CONFIG_INPUT_ENABLE to the
driver.

Fixes: e7165b1d ("pinctrl/rockchip: add a queue for deferred pin output settings on probe")
Fixes: 59dd178e ("gpio/rockchip: fetch deferred output settings on probe")
Signed-off-by: Caleb Connolly <[email protected]>
---
drivers/gpio/gpio-rockchip.c | 24 ++++++++-----
drivers/pinctrl/pinctrl-rockchip.c | 54 ++++++++++++++++--------------
drivers/pinctrl/pinctrl-rockchip.h | 7 ++--
3 files changed, 50 insertions(+), 35 deletions(-)

diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 099e358d2491..bcf5214e3586 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -19,6 +19,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/pinctrl/pinconf-generic.h>
#include <linux/regmap.h>

#include "../pinctrl/core.h"
@@ -706,7 +707,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
struct device_node *pctlnp = of_get_parent(np);
struct pinctrl_dev *pctldev = NULL;
struct rockchip_pin_bank *bank = NULL;
- struct rockchip_pin_output_deferred *cfg;
+ struct rockchip_pin_deferred *cfg;
static int gpio;
int id, ret;

@@ -747,15 +748,22 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
return ret;
}

- while (!list_empty(&bank->deferred_output)) {
- cfg = list_first_entry(&bank->deferred_output,
- struct rockchip_pin_output_deferred, head);
+ while (!list_empty(&bank->deferred_pins)) {
+ cfg = list_first_entry(&bank->deferred_pins,
+ struct rockchip_pin_deferred, head);
list_del(&cfg->head);

- ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg);
- if (ret)
- dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, cfg->arg);
-
+ switch (cfg->param) {
+ case PIN_CONFIG_OUTPUT:
+ ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg);
+ if (ret)
+ dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin,
+ cfg->arg);
+ break;
+ default:
+ dev_warn(dev, "unknown deferred config param %d\n", cfg->param);
+ break;
+ }
kfree(cfg);
}

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index d8dd8415fa81..d54fc1cdf609 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2095,19 +2095,20 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
return false;
}

-static int rockchip_pinconf_defer_output(struct rockchip_pin_bank *bank,
- unsigned int pin, u32 arg)
+static int rockchip_pinconf_defer_pin(struct rockchip_pin_bank *bank,
+ unsigned int pin, u32 param, u32 arg)
{
- struct rockchip_pin_output_deferred *cfg;
+ struct rockchip_pin_deferred *cfg;

cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
if (!cfg)
return -ENOMEM;

cfg->pin = pin;
+ cfg->param = param;
cfg->arg = arg;

- list_add_tail(&cfg->head, &bank->deferred_output);
+ list_add_tail(&cfg->head, &bank->deferred_pins);

return 0;
}
@@ -2128,6 +2129,25 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);

+ if (param == (PIN_CONFIG_OUTPUT | PIN_CONFIG_INPUT_ENABLE)) {
+ /*
+ * Check for gpio driver not being probed yet.
+ * The lock makes sure that either gpio-probe has completed
+ * or the gpio driver hasn't probed yet.
+ */
+ mutex_lock(&bank->deferred_lock);
+ if (!gpio || !gpio->direction_output) {
+ rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param,
+ arg);
+ mutex_unlock(&bank->deferred_lock);
+ if (rc)
+ return rc;
+
+ break;
+ }
+ mutex_unlock(&bank->deferred_lock);
+ }
+
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
rc = rockchip_set_pull(bank, pin - bank->pin_base,
@@ -2156,22 +2176,6 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (rc != RK_FUNC_GPIO)
return -EINVAL;

- /*
- * Check for gpio driver not being probed yet.
- * The lock makes sure that either gpio-probe has completed
- * or the gpio driver hasn't probed yet.
- */
- mutex_lock(&bank->deferred_lock);
- if (!gpio || !gpio->direction_output) {
- rc = rockchip_pinconf_defer_output(bank, pin - bank->pin_base, arg);
- mutex_unlock(&bank->deferred_lock);
- if (rc)
- return rc;
-
- break;
- }
- mutex_unlock(&bank->deferred_lock);
-
rc = gpio->direction_output(gpio, pin - bank->pin_base,
arg);
if (rc)
@@ -2485,7 +2489,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
pdesc++;
}

- INIT_LIST_HEAD(&pin_bank->deferred_output);
+ INIT_LIST_HEAD(&pin_bank->deferred_pins);
mutex_init(&pin_bank->deferred_lock);
}

@@ -2746,7 +2750,7 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev)
{
struct rockchip_pinctrl *info = platform_get_drvdata(pdev);
struct rockchip_pin_bank *bank;
- struct rockchip_pin_output_deferred *cfg;
+ struct rockchip_pin_deferred *cfg;
int i;

of_platform_depopulate(&pdev->dev);
@@ -2755,9 +2759,9 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev)
bank = &info->ctrl->pin_banks[i];

mutex_lock(&bank->deferred_lock);
- while (!list_empty(&bank->deferred_output)) {
- cfg = list_first_entry(&bank->deferred_output,
- struct rockchip_pin_output_deferred, head);
+ while (!list_empty(&bank->deferred_pins)) {
+ cfg = list_first_entry(&bank->deferred_pins,
+ struct rockchip_pin_deferred, head);
list_del(&cfg->head);
kfree(cfg);
}
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 91f10279d084..98a01a616da6 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -171,7 +171,7 @@ struct rockchip_pin_bank {
u32 toggle_edge_mode;
u32 recalced_mask;
u32 route_mask;
- struct list_head deferred_output;
+ struct list_head deferred_pins;
struct mutex deferred_lock;
};

@@ -247,9 +247,12 @@ struct rockchip_pin_config {
unsigned int nconfigs;
};

-struct rockchip_pin_output_deferred {
+enum pin_config_param;
+
+struct rockchip_pin_deferred {
struct list_head head;
unsigned int pin;
+ enum pin_config_param param;
u32 arg;
};

--
2.35.1

2022-04-20 13:44:21

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 0/4] rockchip: support configuring pins as input

Hi Caleb,

On Mon, Mar 28, 2022 at 2:50 AM Caleb Connolly <[email protected]> wrote:

Caleb Connolly (4):
> pinctrl/rockchip: support deferring other gpio params
> pinctrl/rockchip: support setting input-enable param
> gpio/rockchip: handle deferring input-enable pinconfs

Those three applied to the pinctrl tree.

> arm64: dts: rockchip: rk3399: add an input enable pinconf

Please submit this through the SoC tree.

Yours,
Linus Walleij

2022-05-03 01:18:05

by Heiko Stuebner

[permalink] [raw]
Subject: Re: (subset) [PATCH 0/4] rockchip: support configuring pins as input

On Mon, 28 Mar 2022 01:50:01 +0100, Caleb Connolly wrote:
> Add support for configuring pins as input to the rockchip pinctrl
> driver. This is required for example for devices which use non-standard
> configurations for gpio interrupts, specifically for the light/proximity
> sensor on the RK3399 powered PinePhone Pro (which will be coming
> upstream in a future patch series).
>
> Due to the complicated layout of the RK pinctrl/gpio drivers, some extra
> work is required to handle deferring the GPIO configuration. On RK3399
> the pinctrl driver always probes before the GPIO controller driver, so
> the PIN_CONFIG_OUTPUT and PIN_CONFIG_INPUT_ENABLE params both have to be
> deferred, this series also reworks the deferred pin handling to be
> generic and support any param rather than only the PIN_CONFIG_OUTPUT
> param.

Applied, thanks!

[4/4] arm64: dts: rockchip: rk3399: add an input enable pinconf
commit: ec48c3e82ca36a66ae37ba8b1fdb9a7561dcab14

Best regards,
--
Heiko Stuebner <[email protected]>