aboutsummaryrefslogtreecommitdiff
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorBharat Gooty2021-08-24 15:46:31 +0530
committerTom Rini2021-10-05 08:43:03 -0400
commit62f86c6a01690b473545fd6159c680a50b1bfeea (patch)
tree1394bc07bd97dda548ebf5360bf0ec0ef1cda252 /drivers/pinctrl
parent50c84208ad50a27382c64af911abba4510a8b608 (diff)
pinctrl: single: Parse gpio details from dt
Parse different gpio properties from dt as part of probe function. This detail is required to enable pinctrl pad later when gpio lines are requested. Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com> Signed-off-by: Bharat Gooty <bharat.gooty@broadcom.com> Acked-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-single.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index cf9ad3670f6..0f96cd58702 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
+#include <dm/of_access.h>
#include <dm/pinctrl.h>
#include <linux/libfdt.h>
#include <linux/list.h>
@@ -45,10 +46,26 @@ struct single_func {
};
/**
+ * struct single_gpiofunc_range - pin ranges with same mux value of gpio fun
+ * @offset: offset base of pins
+ * @npins: number pins with the same mux value of gpio function
+ * @gpiofunc: mux value of gpio function
+ * @node: list node
+ */
+struct single_gpiofunc_range {
+ u32 offset;
+ u32 npins;
+ u32 gpiofunc;
+ struct list_head node;
+};
+
+/**
* struct single_priv - private data
* @bits_per_pin: number of bits per pin
* @npins: number of selectable pins
* @pin_name: temporary buffer to store the pin name
+ * @functions: list pin functions
+ * @gpiofuncs: list gpio functions
*/
struct single_priv {
#if (IS_ENABLED(CONFIG_SANDBOX))
@@ -58,6 +75,7 @@ struct single_priv {
unsigned int npins;
char pin_name[PINNAME_SIZE];
struct list_head functions;
+ struct list_head gpiofuncs;
};
/**
@@ -454,6 +472,36 @@ static int single_get_pins_count(struct udevice *dev)
return priv->npins;
}
+static int single_add_gpio_func(struct udevice *dev)
+{
+ struct single_priv *priv = dev_get_priv(dev);
+ const char *propname = "pinctrl-single,gpio-range";
+ const char *cellname = "#pinctrl-single,gpio-range-cells";
+ struct single_gpiofunc_range *range;
+ struct ofnode_phandle_args gpiospec;
+ int ret, i;
+
+ for (i = 0; ; i++) {
+ ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), propname,
+ cellname, 0, i, &gpiospec);
+ /* Do not treat it as error. Only treat it as end condition. */
+ if (ret) {
+ ret = 0;
+ break;
+ }
+ range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
+ if (!range) {
+ ret = -ENOMEM;
+ break;
+ }
+ range->offset = gpiospec.args[0];
+ range->npins = gpiospec.args[1];
+ range->gpiofunc = gpiospec.args[2];
+ list_add_tail(&range->node, &priv->gpiofuncs);
+ }
+ return ret;
+}
+
static int single_probe(struct udevice *dev)
{
struct single_pdata *pdata = dev_get_plat(dev);
@@ -461,6 +509,7 @@ static int single_probe(struct udevice *dev)
u32 size;
INIT_LIST_HEAD(&priv->functions);
+ INIT_LIST_HEAD(&priv->gpiofuncs);
size = pdata->offset + pdata->width / BITS_PER_BYTE;
#if (CONFIG_IS_ENABLED(SANDBOX))
@@ -483,6 +532,9 @@ static int single_probe(struct udevice *dev)
priv->npins *= (pdata->width / priv->bits_per_pin);
}
+ if (single_add_gpio_func(dev))
+ dev_dbg(dev, "gpio functions are not added\n");
+
dev_dbg(dev, "%d pins\n", priv->npins);
return 0;
}