diff mbox series

[v6,04/13] pinctrl: renesas: rzg2l: Add pin output disable support

Message ID 20230306090014.128732-5-biju.das.jz@bp.renesas.com (mailing list archive)
State Superseded
Delegated to: Geert Uytterhoeven
Headers show
Series Add pinctrl sysfs and RZ/G2L POEG support | expand

Commit Message

Biju Das March 6, 2023, 9 a.m. UTC
Add pin output disable support for RZ/G2L alike SoCs by registering with
pincontrol core and provide callback mechanism for configuring pin output
disable device by matching with device registered with callback against
the device found by the core framework for a given function name and device
name.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v6:
 * New patch
Ref:
 https://lore.kernel.org/linux-renesas-soc/OS0PR01MB5922F5494D3C0862E15F3F8486B39@OS0PR01MB5922.jpnprd01.prod.outlook.com/T/#t
---
 drivers/pinctrl/renesas/pinctrl-rzg2l.c | 44 +++++++++++++++++++++++++
 include/linux/pinctrl/pinctrl-rzg2l.h   | 26 +++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 include/linux/pinctrl/pinctrl-rzg2l.h
diff mbox series

Patch

diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
index 04b31f0c6b34..137d085077d8 100644
--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c
+++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c
@@ -17,9 +17,11 @@ 
 #include <linux/spinlock.h>
 
 #include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/output-disable.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinctrl-rzg2l.h>
 #include <linux/pinctrl/pinmux.h>
 
 #include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
@@ -136,6 +138,10 @@  struct rzg2l_pinctrl_data {
 	unsigned int n_dedicated_pins;
 };
 
+static struct device *rzg2l_poeg_dev;
+static output_disable_cb rzg2l_poeg_cb;
+static void *rzg2l_poeg_context;
+
 struct rzg2l_pinctrl {
 	struct pinctrl_dev		*pctl;
 	struct pinctrl_desc		desc;
@@ -747,6 +753,28 @@  static int rzg2l_pinctrl_pinconf_group_get(struct pinctrl_dev *pctldev,
 	return 0;
 };
 
+static int rzg2l_pinctrl_output_disable_set(struct pinctrl_dev *pctldev,
+					    struct device *dev,
+					    const char *fname,
+					    const char *gname,
+					    enum pin_output_disable_conf conf,
+					    unsigned int conf_val)
+{
+	struct rzg2l_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	if (!rzg2l_poeg_cb || !rzg2l_poeg_context) {
+		dev_err(pctrl->dev, "No callback function registered\n");
+		return -EINVAL;
+	}
+
+	if (!rzg2l_poeg_dev || rzg2l_poeg_dev != dev) {
+		dev_err(pctrl->dev, "Device match failed\n");
+		return -EINVAL;
+	}
+
+	return rzg2l_poeg_cb(rzg2l_poeg_context, fname, gname, conf, conf_val);
+}
+
 static const struct pinctrl_ops rzg2l_pinctrl_pctlops = {
 	.get_groups_count = pinctrl_generic_get_group_count,
 	.get_group_name = pinctrl_generic_get_group_name,
@@ -772,6 +800,10 @@  static const struct pinconf_ops rzg2l_pinctrl_confops = {
 	.pin_config_config_dbg_show = pinconf_generic_dump_config,
 };
 
+static const struct pin_output_disable_ops rzg2l_pinctrl_output_disable_fops = {
+	.pin_output_disable_config_set = rzg2l_pinctrl_output_disable_set,
+};
+
 static int rzg2l_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
 	struct rzg2l_pinctrl *pctrl = gpiochip_get_data(chip);
@@ -1320,6 +1352,17 @@  static void rzg2l_init_irq_valid_mask(struct gpio_chip *gc,
 	}
 }
 
+int rzg2l_output_disable_cb_register(struct device *dev, output_disable_cb cb,
+				     void *cb_context)
+{
+	rzg2l_poeg_dev = dev;
+	rzg2l_poeg_cb = cb;
+	rzg2l_poeg_context = cb_context;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rzg2l_output_disable_cb_register);
+
 static int rzg2l_gpio_register(struct rzg2l_pinctrl *pctrl)
 {
 	struct device_node *np = pctrl->dev->of_node;
@@ -1404,6 +1447,7 @@  static int rzg2l_pinctrl_register(struct rzg2l_pinctrl *pctrl)
 	pctrl->desc.pctlops = &rzg2l_pinctrl_pctlops;
 	pctrl->desc.pmxops = &rzg2l_pinctrl_pmxops;
 	pctrl->desc.confops = &rzg2l_pinctrl_confops;
+	pctrl->desc.poutdisops = &rzg2l_pinctrl_output_disable_fops;
 	pctrl->desc.owner = THIS_MODULE;
 
 	pins = devm_kcalloc(pctrl->dev, pctrl->desc.npins, sizeof(*pins), GFP_KERNEL);
diff --git a/include/linux/pinctrl/pinctrl-rzg2l.h b/include/linux/pinctrl/pinctrl-rzg2l.h
new file mode 100644
index 000000000000..a49b4c5f8908
--- /dev/null
+++ b/include/linux/pinctrl/pinctrl-rzg2l.h
@@ -0,0 +1,26 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PINCTRL_RZG2L_H__
+#define __LINUX_PINCTRL_RZG2L_H__
+
+#include <linux/pinctrl/output-disable.h>
+
+typedef int (*output_disable_cb) (void *context,
+				  const char *fname,
+				  const char *gname,
+				  enum pin_output_disable_conf conf,
+				  unsigned int conf_val);
+
+#if IS_ENABLED(CONFIG_PINCTRL_RZG2L)
+int rzg2l_output_disable_cb_register(struct device *dev,
+				     output_disable_cb cb,
+				     void *cb_context);
+#else
+static inline int rzg2l_output_disable_cb_register(struct device *dev,
+						   output_disable_cb cb,
+						   void *cb_context)
+{
+	return -EINVAL;
+}
+#endif
+
+#endif /* __LINUX_PINCTRL_RZG2L_H__ */