summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/renesas/pinctrl-rzv2m.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/renesas/pinctrl-rzv2m.c')
-rw-r--r--drivers/pinctrl/renesas/pinctrl-rzv2m.c76
1 files changed, 38 insertions, 38 deletions
diff --git a/drivers/pinctrl/renesas/pinctrl-rzv2m.c b/drivers/pinctrl/renesas/pinctrl-rzv2m.c
index e5472293bc7f..52aeafaba4b6 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzv2m.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzv2m.c
@@ -14,7 +14,9 @@
#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/pinctrl/consumer.h>
@@ -118,12 +120,12 @@ struct rzv2m_pinctrl {
const struct rzv2m_pinctrl_data *data;
void __iomem *base;
struct device *dev;
- struct clk *clk;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range gpio_range;
- spinlock_t lock;
+ spinlock_t lock; /* lock read/write registers */
+ struct mutex mutex; /* serialize adding groups and functions */
};
static const unsigned int drv_1_8V_group2_uA[] = { 1800, 3800, 7800, 11000 };
@@ -209,6 +211,7 @@ static int rzv2m_map_add_config(struct pinctrl_map *map,
static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
+ struct device_node *parent,
struct pinctrl_map **map,
unsigned int *num_maps,
unsigned int *index)
@@ -226,6 +229,7 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct property *prop;
int ret, gsel, fsel;
const char **pin_fn;
+ const char *name;
const char *pin;
pinmux = of_find_property(np, "pinmux", NULL);
@@ -309,28 +313,42 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
psel_val[i] = MUX_FUNC(value);
}
+ if (parent) {
+ name = devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOFn.%pOFn",
+ parent, np);
+ if (!name) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ } else {
+ name = np->name;
+ }
+
+ mutex_lock(&pctrl->mutex);
+
/* Register a single pin group listing all the pins we read from DT */
- gsel = pinctrl_generic_add_group(pctldev, np->name, pins, num_pinmux, NULL);
+ gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL);
if (gsel < 0) {
ret = gsel;
- goto done;
+ goto unlock;
}
/*
* Register a single group function where the 'data' is an array PSEL
* register values read from DT.
*/
- pin_fn[0] = np->name;
- fsel = pinmux_generic_add_function(pctldev, np->name, pin_fn, 1,
- psel_val);
+ pin_fn[0] = name;
+ fsel = pinmux_generic_add_function(pctldev, name, pin_fn, 1, psel_val);
if (fsel < 0) {
ret = fsel;
goto remove_group;
}
+ mutex_unlock(&pctrl->mutex);
+
maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
- maps[idx].data.mux.group = np->name;
- maps[idx].data.mux.function = np->name;
+ maps[idx].data.mux.group = name;
+ maps[idx].data.mux.function = name;
idx++;
dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux);
@@ -339,6 +357,8 @@ static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev,
remove_group:
pinctrl_generic_remove_group(pctldev, gsel);
+unlock:
+ mutex_unlock(&pctrl->mutex);
done:
*index = idx;
kfree(configs);
@@ -377,7 +397,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev,
index = 0;
for_each_child_of_node(np, child) {
- ret = rzv2m_dt_subnode_to_map(pctldev, child, map,
+ ret = rzv2m_dt_subnode_to_map(pctldev, child, np, map,
num_maps, &index);
if (ret < 0) {
of_node_put(child);
@@ -386,7 +406,7 @@ static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev,
}
if (*num_maps == 0) {
- ret = rzv2m_dt_subnode_to_map(pctldev, np, map,
+ ret = rzv2m_dt_subnode_to_map(pctldev, np, NULL, map,
num_maps, &index);
if (ret < 0)
goto done;
@@ -1027,14 +1047,10 @@ static int rzv2m_pinctrl_register(struct rzv2m_pinctrl *pctrl)
return 0;
}
-static void rzv2m_pinctrl_clk_disable(void *data)
-{
- clk_disable_unprepare(data);
-}
-
static int rzv2m_pinctrl_probe(struct platform_device *pdev)
{
struct rzv2m_pinctrl *pctrl;
+ struct clk *clk;
int ret;
pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
@@ -1051,32 +1067,16 @@ static int rzv2m_pinctrl_probe(struct platform_device *pdev)
if (IS_ERR(pctrl->base))
return PTR_ERR(pctrl->base);
- pctrl->clk = devm_clk_get(pctrl->dev, NULL);
- if (IS_ERR(pctrl->clk)) {
- ret = PTR_ERR(pctrl->clk);
- dev_err(pctrl->dev, "failed to get GPIO clk : %i\n", ret);
- return ret;
- }
+ clk = devm_clk_get_enabled(pctrl->dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(pctrl->dev, PTR_ERR(clk),
+ "failed to enable GPIO clk\n");
spin_lock_init(&pctrl->lock);
+ mutex_init(&pctrl->mutex);
platform_set_drvdata(pdev, pctrl);
- ret = clk_prepare_enable(pctrl->clk);
- if (ret) {
- dev_err(pctrl->dev, "failed to enable GPIO clk: %i\n", ret);
- return ret;
- }
-
- ret = devm_add_action_or_reset(&pdev->dev, rzv2m_pinctrl_clk_disable,
- pctrl->clk);
- if (ret) {
- dev_err(pctrl->dev,
- "failed to register GPIO clk disable action, %i\n",
- ret);
- return ret;
- }
-
ret = rzv2m_pinctrl_register(pctrl);
if (ret)
return ret;