From: Sascha Hauer <s.hauer@pengutronix.de>
To: linux-rockchip@lists.infradead.org
Cc: Heiko Stuebner <heiko@sntech.de>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org, kernel@pengutronix.de,
Quentin Schulz <quentin.schulz@theobroma-systems.com>,
Michael Riesch <michael.riesch@wolfvision.net>,
Linus Walleij <linus.walleij@linaro.org>,
Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Conor Dooley <conor+dt@kernel.org>,
Sascha Hauer <s.hauer@pengutronix.de>
Subject: [PATCH 1/3] pinctrl: rockchip: add support for io-domain dependency
Date: Mon, 4 Sep 2023 13:58:14 +0200 [thread overview]
Message-ID: <20230904115816.1237684-2-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20230904115816.1237684-1-s.hauer@pengutronix.de>
On some Rockchip SoCs, some SoC pins are split in what are called IO
domains.
An IO domain is supplied power externally, by regulators from a PMIC for
example. This external power supply is then used by the IO domain as
"supply" for the IO pins if they are outputs.
Each IO domain can configure which voltage the IO pins will be operating
on (1.8V or 3.3V).
There already exists an IO domain driver for Rockchip SoCs[1]. This
driver allows to explicit the relationship between the external power
supplies and IO domains[2]. This makes sure the regulators are enabled
by the Linux kernel so the IO domains are supplied with power and
correctly configured as per the supplied voltage.
This driver is a regulator consumer and does not offer any other
interface for device dependency.
However, IO pins belonging to an IO domain need to have this IO domain
configured correctly before they are being used otherwise they do not
operate correctly.
We currently do not have any knowledge about which pin is on which IO
domain, so we assume that all pins are on some IO domain and defer
probing of the pin consumers until the IO domain driver has been probed.
Some pins however are needed to access the regulators driving an IO
domain. Deferring probe for them as well would introduce a cyclic
dependency. To break out of this dependency a pin group can be supplied
a rockchip,io-domain-boot-on property. Probe won't be deferred for pin
groups with this property. rockchip,io-domain-boot-on should be added
to all pin groups needed to access the PMIC driving the IO domains.
[1] drivers/soc/rockchip/io-domain.c
[2] Documentation/devicetree/bindings/power/rockchip-io-domain.yaml
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/pinctrl/pinctrl-rockchip.c | 64 ++++++++++++++++++++++++++++++
drivers/pinctrl/pinctrl-rockchip.h | 3 ++
2 files changed, 67 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 0276b52f37168..663bd9d6840a5 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -24,6 +24,8 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
@@ -2678,6 +2680,43 @@ static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev,
return 0;
}
+static int rockchip_pmx_check_io_domain(struct rockchip_pinctrl *info, unsigned group)
+{
+ struct platform_device *pdev;
+ int i;
+
+ if (!info->io_domains)
+ return 0;
+
+ if (info->groups[group].io_domain_skip)
+ return 0;
+
+ for (i = 0; i < info->num_io_domains; i++) {
+ if (!info->io_domains[i])
+ continue;
+
+ pdev = of_find_device_by_node(info->io_domains[i]);
+ if (!pdev) {
+ dev_err(info->dev, "couldn't find IO domain device\n");
+ return -ENODEV;
+ }
+
+ if (!platform_get_drvdata(pdev)) {
+ dev_err(info->dev, "IO domain device is not probed yet, deferring...(%s)",
+ info->groups[group].name);
+ return -EPROBE_DEFER;
+ }
+
+ of_node_put(info->io_domains[i]);
+ info->io_domains[i] = NULL;
+ }
+
+ devm_kfree(info->dev, info->io_domains);
+ info->io_domains = NULL;
+
+ return 0;
+}
+
static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
unsigned group)
{
@@ -2691,6 +2730,10 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
dev_dbg(dev, "enable function %s group %s\n",
info->functions[selector].name, info->groups[group].name);
+ ret = rockchip_pmx_check_io_domain(info, group);
+ if (ret)
+ return ret;
+
/*
* for each pin in the pin group selected, program the corresponding
* pin function number in the config register.
@@ -3019,6 +3062,8 @@ static int rockchip_pinctrl_parse_groups(struct device_node *np,
if (!size || size % 4)
return dev_err_probe(dev, -EINVAL, "wrong pins number or pins and configs should be by 4\n");
+ grp->io_domain_skip = of_property_read_bool(np, "rockchip,io-domain-boot-on");
+
grp->npins = size / 4;
grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL);
@@ -3417,6 +3462,22 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
return PTR_ERR(info->regmap_pmu);
}
+ info->num_io_domains = of_property_count_u32_elems(np, "rockchip,io-domains");
+ if (info->num_io_domains) {
+ int i;
+
+ info->io_domains = devm_kmalloc_array(dev, info->num_io_domains,
+ sizeof(*info->io_domains), GFP_KERNEL);
+ if (!info->io_domains)
+ return -ENOMEM;
+
+ for (i = 0; i < info->num_io_domains; i++) {
+ info->io_domains[i] = of_parse_phandle(np, "rockchip,io-domains", 0);
+ if (!info->io_domains[i])
+ return -EINVAL;
+ }
+ }
+
ret = rockchip_pinctrl_register(pdev, info);
if (ret)
return ret;
@@ -3439,6 +3500,9 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev)
of_platform_depopulate(&pdev->dev);
+ for (i = 0; i < info->num_io_domains; i++)
+ of_node_put(info->io_domains[i]);
+
for (i = 0; i < info->ctrl->nr_banks; i++) {
bank = &info->ctrl->pin_banks[i];
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 4759f336941ef..d2ac79b0a7bc4 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -435,6 +435,7 @@ struct rockchip_pin_group {
unsigned int npins;
unsigned int *pins;
struct rockchip_pin_config *data;
+ bool io_domain_skip;
};
/**
@@ -462,6 +463,8 @@ struct rockchip_pinctrl {
unsigned int ngroups;
struct rockchip_pmx_func *functions;
unsigned int nfunctions;
+ struct device_node **io_domains;
+ int num_io_domains;
};
#endif
--
2.39.2
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
next prev parent reply other threads:[~2023-09-04 11:58 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-04 11:58 [PATCH 0/3] Make Rockchip IO domains dependency from other devices explicit Sascha Hauer
2023-09-04 11:58 ` Sascha Hauer [this message]
2023-09-12 8:06 ` [PATCH 1/3] pinctrl: rockchip: add support for io-domain dependency Linus Walleij
2023-09-13 1:37 ` Saravana Kannan
2023-09-13 4:37 ` Chen-Yu Tsai
2023-09-13 6:58 ` Sascha Hauer
2023-09-13 20:48 ` Saravana Kannan
2023-09-15 6:51 ` Sascha Hauer
2023-09-15 16:38 ` Quentin Schulz
2023-09-15 17:24 ` Robin Murphy
2023-09-20 22:00 ` Saravana Kannan
2023-09-21 13:57 ` Sascha Hauer
2023-09-21 20:49 ` Saravana Kannan
2023-09-22 11:04 ` Sascha Hauer
2023-09-16 4:59 ` Samuel Holland
2023-09-15 14:45 ` Rob Herring
2023-09-04 11:58 ` [PATCH 2/3] dt-bindings: pinctrl: rockchip: Add io domain properties Sascha Hauer
2023-09-05 9:03 ` Robin Murphy
2023-09-06 7:21 ` Sascha Hauer
2023-09-07 16:35 ` Robin Murphy
2023-09-08 7:20 ` Sascha Hauer
2023-09-06 8:20 ` Quentin Schulz
2023-09-06 10:19 ` Sascha Hauer
2023-09-07 16:47 ` Robin Murphy
2023-09-05 18:14 ` Rob Herring
2023-09-06 8:27 ` Quentin Schulz
2023-09-04 11:58 ` [PATCH 3/3] arm64: dts: rockchip: rock-3a: add " Sascha Hauer
2023-09-05 11:34 ` [PATCH 0/3] Make Rockchip IO domains dependency from other devices explicit Jonas Karlman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230904115816.1237684-2-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=heiko@sntech.de \
--cc=kernel@pengutronix.de \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=michael.riesch@wolfvision.net \
--cc=quentin.schulz@theobroma-systems.com \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox