[PATCH 4/4] pinctrl: rockchip: register gpio driver before pinctrl driver
Jianqun Xu
jay.xu at rock-chips.com
Mon Mar 7 22:19:35 PST 2022
This patch should co-work with the gpio-rockchip driver patch, it
populates the gpio platform first and add gpio_chip after pinctrl
register.
Signed-off-by: Jianqun Xu <jay.xu at rock-chips.com>
---
drivers/pinctrl/pinctrl-rockchip.c | 90 ++++++++++--------------------
drivers/pinctrl/pinctrl-rockchip.h | 2 +-
2 files changed, 29 insertions(+), 63 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index d8dd8415fa81..8e60811b4942 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2095,30 +2095,13 @@ 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)
-{
- struct rockchip_pin_output_deferred *cfg;
-
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
- if (!cfg)
- return -ENOMEM;
-
- cfg->pin = pin;
- cfg->arg = arg;
-
- list_add_tail(&cfg->head, &bank->deferred_output);
-
- return 0;
-}
-
/* set the pin config settings for a specified pin */
static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long *configs, unsigned num_configs)
{
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
- struct gpio_chip *gpio = &bank->gpio_chip;
+ struct gpio_chip *gpio = bank->gpio_chip;
enum pin_config_param param;
u32 arg;
int i;
@@ -2156,22 +2139,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)
@@ -2211,7 +2178,7 @@ static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
{
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
- struct gpio_chip *gpio = &bank->gpio_chip;
+ struct gpio_chip *gpio = bank->gpio_chip;
enum pin_config_param param = pinconf_to_config_param(*config);
u16 arg;
int rc;
@@ -2484,9 +2451,6 @@ static int rockchip_pinctrl_register(struct platform_device *pdev,
pdesc->name = pin_names[pin];
pdesc++;
}
-
- INIT_LIST_HEAD(&pin_bank->deferred_output);
- mutex_init(&pin_bank->deferred_lock);
}
ret = rockchip_pinctrl_parse_dt(pdev, info);
@@ -2525,7 +2489,6 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
int bank_pins = 0;
- raw_spin_lock_init(&bank->slock);
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
@@ -2666,6 +2629,13 @@ static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend,
rockchip_pinctrl_resume);
+static int gpiochip_match_name(struct gpio_chip *gc, void *data)
+{
+ const char *name = data;
+
+ return !strcmp(gc->label, name);
+}
+
static int rockchip_pinctrl_probe(struct platform_device *pdev)
{
struct rockchip_pinctrl *info;
@@ -2674,7 +2644,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
struct rockchip_pin_ctrl *ctrl;
struct resource *res;
void __iomem *base;
- int ret;
+ int ret, i;
if (!dev->of_node)
return dev_err_probe(dev, -ENODEV, "device tree node not found\n");
@@ -2683,6 +2653,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
+ ret = of_platform_populate(np, NULL, NULL, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register gpio device\n");
+
info->dev = dev;
ctrl = rockchip_pinctrl_get_soc_data(info, pdev);
@@ -2733,37 +2707,29 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
if (ret)
return ret;
- platform_set_drvdata(pdev, info);
+ for (i = 0; i < ctrl->nr_banks; i++) {
+ struct gpio_chip *gc;
+ struct rockchip_pin_bank *bank = &ctrl->pin_banks[i];
- ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
- if (ret)
- return dev_err_probe(dev, ret, "failed to register gpio device\n");
+ gc = gpiochip_find((void *)ctrl->pin_banks[i].name, gpiochip_match_name);
+ ret = gpiochip_add_pin_range(gc, dev_name(dev), 0, gc->base, gc->ngpio);
+ if (ret) {
+ dev_err(dev, "fail to add pin range\n");
+ return ret;
+ }
+ bank->gpio_chip = gc;
+ }
+
+ platform_set_drvdata(pdev, info);
+ dev_info(dev, "probed %s\n", dev_name(dev));
return 0;
}
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;
- int i;
-
of_platform_depopulate(&pdev->dev);
- for (i = 0; i < info->ctrl->nr_banks; i++) {
- 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);
- list_del(&cfg->head);
- kfree(cfg);
- }
- mutex_unlock(&bank->deferred_lock);
- }
-
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 91f10279d084..b109750ac294 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -163,7 +163,7 @@ struct rockchip_pin_bank {
struct device_node *of_node;
struct rockchip_pinctrl *drvdata;
struct irq_domain *domain;
- struct gpio_chip gpio_chip;
+ struct gpio_chip *gpio_chip;
struct pinctrl_gpio_range grange;
raw_spinlock_t slock;
const struct rockchip_gpio_regs *gpio_regs;
--
2.25.1
More information about the Linux-rockchip
mailing list