[U-Boot] [PATCH 3/3] pinctrl: pinctrl-single: Parse gpio details from dt
Vladimir Olovyannikov
vladimir.olovyannikov at broadcom.com
Fri Nov 22 22:44:43 UTC 2019
From: Rayagonda Kokatanur <rayagonda.kokatanur at broadcom.com>
Parse different gpio properties from dt as part of probe
function. This detail is required to enable pinctrl pad.
Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur at broadcom.com>
Signed-off-by: Vladimir Olovyannikov <vladimir.olovyannikov at broadcom.com>
---
drivers/pinctrl/pinctrl-single.c | 61 +++++++++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 2dcc131513..449e8a2bfe 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -5,18 +5,35 @@
#include <common.h>
#include <dm.h>
+#include <dm/of_access.h>
#include <dm/pinctrl.h>
#include <linux/libfdt.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
+/**
+ * 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_pdata - pinctrl device instance
* @base first configuration register
* @offset index of last configuration register
* @mask configuration-value mask bits
* @width configuration register bit width
+ * @mutex mutex protecting the list
+ * @gpiofuncs list of gpio functions
* @read register read function to use
* @write register write function to use
*/
@@ -26,6 +43,8 @@ struct single_pdata {
u32 mask;
int width;
bool bits_per_mux;
+ struct mutex mutex;
+ struct list_head gpiofuncs;
u32 (*read)(void __iomem *reg);
void (*write)(u32 val, void __iomem *reg);
};
@@ -204,9 +223,42 @@ static int single_set_state(struct udevice *dev,
return len;
}
+static int single_add_gpio_func(struct udevice *dev,
+ struct single_pdata *pdata)
+{
+ 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->node, 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];
+ mutex_lock(&pdata->mutex);
+ list_add_tail(&range->node, &pdata->gpiofuncs);
+ mutex_unlock(&pdata->mutex);
+ }
+ return ret;
+}
+
static int single_probe(struct udevice *dev)
{
struct single_pdata *pdata = dev->platdata;
+ int ret;
switch (pdata->width) {
case 8:
@@ -227,7 +279,14 @@ static int single_probe(struct udevice *dev)
return -EINVAL;
}
- return 0;
+ mutex_init(&pdata->mutex);
+ INIT_LIST_HEAD(&pdata->gpiofuncs);
+
+ ret = single_add_gpio_func(dev, pdata);
+ if (ret < 0)
+ dev_err(dev, "%s: Failed to add gpio functions\n", __func__);
+
+ return ret;
}
static int single_ofdata_to_platdata(struct udevice *dev)
--
2.17.1
More information about the U-Boot
mailing list