From: "Rafał Miłecki" <zajec5@gmail.com>
To: Linus Walleij <linus.walleij@linaro.org>,
Rob Herring <robh+dt@kernel.org>
Cc: "Tony Lindgren" <tony@atomide.com>,
"Andy Shevchenko" <andy.shevchenko@gmail.com>,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
"Florian Fainelli" <f.fainelli@gmail.com>,
bcm-kernel-feedback-list@broadcom.com,
"Rafał Miłecki" <rafal@milecki.pl>
Subject: [PATCH 3/5] pinctrl: add helpers reading pins, groups & functions from DT
Date: Thu, 18 Nov 2021 14:21:50 +0100 [thread overview]
Message-ID: <20211118132152.15722-4-zajec5@gmail.com> (raw)
In-Reply-To: <20211118132152.15722-1-zajec5@gmail.com>
From: Rafał Miłecki <rafal@milecki.pl>
DT binding allows specifying pins, groups & functions now. That allows
storing them in DT instead of hardcoding in drivers.
Introduce helpers based on CONFIG_GENERIC_PINCONF,
CONFIG_GENERIC_PINCTRL_GROUPS and CONFIG_GENERIC_PINMUX_FUNCTIONS for
parsing that info into pinctrl generic structures.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/pinctrl/core.c | 89 ++++++++++++++++++++++++++++++++++++++++
drivers/pinctrl/core.h | 5 +++
drivers/pinctrl/pinmux.c | 43 +++++++++++++++++++
drivers/pinctrl/pinmux.h | 2 +
4 files changed, 139 insertions(+)
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index ffe39336fcac..8f6ed8488313 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -515,8 +515,97 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
}
EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
+int pinctrl_generic_get_dt_pins(struct pinctrl_desc *pctldesc,
+ struct device *dev)
+{
+ struct pinctrl_pin_desc *descs;
+ struct device_node *pins;
+ struct device_node *np;
+ int err = 0;
+ int i = 0;
+
+ pins = of_get_child_by_name(dev->of_node, "pins");
+ if (!pins) {
+ dev_err(dev, "failed to find \"pins\" DT node\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+
+ pctldesc->npins = of_get_available_child_count(pins);
+
+ descs = devm_kcalloc(dev, pctldesc->npins, sizeof(*descs), GFP_KERNEL);
+ if (!descs) {
+ err = -ENOMEM;
+ goto err_put_node;
+ }
+
+ for_each_available_child_of_node(pins, np) {
+ if (of_property_read_u32(np, "reg", &descs[i].number)) {
+ dev_err(dev, "missing \"reg\" property in %pOF\n", np);
+ err = -ENOENT;
+ goto err_put_node;
+ }
+
+ if (of_property_read_string(np, "label", &descs[i].name)) {
+ dev_err(dev, "missing \"label\" property in %pOF\n", np);
+ err = -ENOENT;
+ goto err_put_node;
+ }
+
+ i++;
+ }
+
+ pctldesc->pins = descs;
+
+err_put_node:
+ of_node_put(pins);
+err_out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_dt_pins);
+
#ifdef CONFIG_GENERIC_PINCTRL_GROUPS
+int pinctrl_generic_get_dt_groups(struct pinctrl_dev *pctldev)
+{
+ struct device *dev = pctldev->dev;
+ struct device_node *groups;
+ struct device_node *np;
+ int err = 0;
+
+ groups = of_get_child_by_name(dev->of_node, "groups");
+ if (!groups) {
+ dev_err(dev, "failed to find \"groups\" DT node\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+
+ for_each_available_child_of_node(groups, np) {
+ int num_pins;
+ u32 *pins;
+
+ num_pins = of_property_count_u32_elems(np, "pins");
+ pins = devm_kmalloc_array(dev, num_pins, sizeof(*pins), GFP_KERNEL);
+ if (!pins) {
+ err = -ENOMEM;
+ goto err_put_node;
+ }
+
+ if (of_property_read_u32_array(np, "pins", pins, num_pins)) {
+ err = -EIO;
+ goto err_put_node;
+ }
+
+ pinctrl_generic_add_group(pctldev, np->name, pins, num_pins, np);
+ }
+
+err_put_node:
+ of_node_put(groups);
+err_out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(pinctrl_generic_get_dt_groups);
+
/**
* pinctrl_generic_get_group_count() - returns the number of pin groups
* @pctldev: pin controller device
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 840103c40c14..59661d4d4cc7 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -182,6 +182,9 @@ struct pinctrl_maps {
unsigned num_maps;
};
+int pinctrl_generic_get_dt_pins(struct pinctrl_desc *pctldesc,
+ struct device *dev);
+
#ifdef CONFIG_GENERIC_PINCTRL_GROUPS
/**
@@ -198,6 +201,8 @@ struct group_desc {
void *data;
};
+int pinctrl_generic_get_dt_groups(struct pinctrl_dev *pctldev);
+
int pinctrl_generic_get_group_count(struct pinctrl_dev *pctldev);
const char *pinctrl_generic_get_group_name(struct pinctrl_dev *pctldev,
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 6cdbd9ccf2f0..5e34bd3135f5 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -24,6 +24,7 @@
#include <linux/string.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/of.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h>
#include "core.h"
@@ -788,6 +789,48 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS
+int pinmux_generic_get_dt_functions(struct pinctrl_dev *pctldev)
+{
+ struct device *dev = pctldev->dev;
+ struct device_node *functions;
+ struct device_node *np;
+ int err = 0;
+
+ functions = of_get_child_by_name(dev->of_node, "functions");
+ if (!functions) {
+ dev_err(dev, "failed to find \"functions\" DT node\n");
+ err = -ENOENT;
+ goto err_out;
+ }
+
+ for_each_available_child_of_node(functions, np) {
+ int num_groups = of_count_phandle_with_args(np, "groups", NULL);
+ struct of_phandle_iterator it;
+ const char **groups;
+ int ret;
+ int i;
+
+ groups = devm_kmalloc_array(dev, num_groups, sizeof(*groups), GFP_KERNEL);
+ if (!groups) {
+ err = -ENOMEM;
+ goto err_put_node;
+ }
+
+ i = 0;
+ of_for_each_phandle(&it, ret, np, "groups", NULL, 0) {
+ groups[i++] = it.node->name;
+ }
+
+ pinmux_generic_add_function(pctldev, np->name, groups, num_groups, np);
+ }
+
+err_put_node:
+ of_node_put(functions);
+err_out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(pinmux_generic_get_dt_functions);
+
/**
* pinmux_generic_get_function_count() - returns number of functions
* @pctldev: pin controller device
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
index 78c3a31be882..ca69025fce46 100644
--- a/drivers/pinctrl/pinmux.h
+++ b/drivers/pinctrl/pinmux.h
@@ -134,6 +134,8 @@ struct function_desc {
void *data;
};
+int pinmux_generic_get_dt_functions(struct pinctrl_dev *pctldev);
+
int pinmux_generic_get_function_count(struct pinctrl_dev *pctldev);
const char *
--
2.31.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-11-18 13:24 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-18 13:21 [PATCH 0/5] pinctrl: allow storing pins, groups & functions in DT Rafał Miłecki
2021-11-18 13:21 ` [PATCH 1/5] dt-bindings: pinctrl: support specifying pins, groups & functions Rafał Miłecki
2021-11-18 13:21 ` [PATCH 2/5] dt-bindings: pinctrl: brcm,ns-pinmux: extend example Rafał Miłecki
2021-11-18 22:09 ` Rob Herring
2021-11-19 6:24 ` Rafał Miłecki
2021-11-23 7:38 ` Tony Lindgren
2021-11-23 7:56 ` Rafał Miłecki
2021-11-23 8:01 ` Rafał Miłecki
2021-11-23 9:15 ` Tony Lindgren
2021-11-23 13:51 ` Rafał Miłecki
2021-11-18 13:21 ` Rafał Miłecki [this message]
2021-11-18 13:57 ` [PATCH 3/5] pinctrl: add helpers reading pins, groups & functions from DT Andy Shevchenko
2021-11-18 14:17 ` Rafał Miłecki
2021-11-18 16:22 ` Andy Shevchenko
2021-11-21 23:53 ` Linus Walleij
2021-11-18 13:21 ` [PATCH 4/5] pinctrl: bcm: pinctrl-ns: supoprt DT specified pins, groups & functions Rafał Miłecki
2021-11-18 13:21 ` [PATCH 5/5] ARM: dts: BCM5301X: add pinctrl " Rafał Miłecki
2021-11-18 13:52 ` [PATCH 0/5] pinctrl: allow storing pins, groups & functions in DT Andy Shevchenko
2021-11-18 13:59 ` Rafał Miłecki
2021-11-18 16:30 ` Andy Shevchenko
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=20211118132152.15722-4-zajec5@gmail.com \
--to=zajec5@gmail.com \
--cc=andy.shevchenko@gmail.com \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=devicetree@vger.kernel.org \
--cc=f.fainelli@gmail.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=rafal@milecki.pl \
--cc=robh+dt@kernel.org \
--cc=tony@atomide.com \
/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;
as well as URLs for NNTP newsgroup(s).