linux-renesas-soc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/10] Add RZ/G2L POEG support
@ 2023-03-28 10:10 Biju Das
  2023-03-28 10:10 ` [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property Biju Das
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, Geert Uytterhoeven, Thierry Reding,
	Uwe Kleine-König, linux-renesas-soc, linux-gpio, devicetree,
	Chris Paterson, Biju Das, Prabhakar Mahadev Lad

The output pins of the general PWM timer (GPT) can be disabled by using
the port output enabling function for the GPT (POEG). Specifically, either
of the following ways can be used.

  * Input level detection of the GTETRGA to GTETRGD pins.
  * Output-disable request from the GPT.
  * Register setting(ie, by setting POEGGn.SSF to 1)

This patch series adds support for configuring output disable function using
DT and  handling of user control and events are handled by char device.

Patch #3 to patch #10 are just for testing only.

When dead time error occurs or the GTIOCA pin output value is
the same as the GTIOCB pin output value, output protection is
required. GPT detects this condition and generates output disable
requests to POEG based on the settings in the output disable request
permission bits, such as GTINTAD.GRPDTE, GTINTAD.GRPABH,
GTINTAD.GRPABL. After the POEG receives output disable requests from
each channel and calculates external input using an OR operation, the
POEG generates output disable requests to GPT.

POEG handles output disable request and send an event to userspace.
Userspace clears the fault condition and request poeg to cancel
the output disable request.

REF:
https://lore.kernel.org/linux-renesas-soc/20220510151112.16249-1-biju.das.jz@bp.renesas.com/
https://lore.kernel.org/linux-renesas-soc/20230306090014.128732-1-biju.das.jz@bp.renesas.com/T/#t

logs:
 root@smarc-rzg2l:~# /poeg.sh
Test case 1 user POEG control with renesas,poeg-config = <1>;
[POEG]open
[POEG] user control pin output disable enabled
Read at address  0x10048434 (0xffff97de1434): 0x031B031B
Read at address  0x10048438 (0xffff8353f438): 0x03000000
Read at address  0x10049400 (0xffff99960400): 0x00000008
[POEG] user control pin output disable disabled
[POEG]close
 73:          0          0     GICv3 357 Level     10049400.poeg
Read at address  0x10048434 (0xffffb8252434): 0x031B031B
Read at address  0x10048438 (0xffffbb61a438): 0x03000000
Read at address  0x10049400 (0xffff88783400): 0x00000000
root@smarc-rzg2l:~#

      
root@smarc-rzg2l:~# /poeg.sh
Test case 2 GPT control with renesas,poeg-config = <2>;
[POEG]open
[POEG] GPT control configure IRQ
Read at address  0x10048434 (0xffffa60a2434): 0x031B031B
Read at address  0x10048438 (0xffffa8c2c438): 0x23000000
Read at address  0x10049400 (0xffffbc09f400): 0x00000020
gpt ch:3, irq=2
gpt ch:3, irq=2
gpt ch:3, irq=2
gpt ch:3, irq=2
Read at address  0x10048434 (0xffff82111434): 0x021B031B
Read at address  0x10048438 (0xffff9abfa438): 0x23000000
Read at address  0x10049400 (0xffff872ea400): 0x00000020
 73:          5          0     GICv3 357 Level     10049400.poeg
root@smarc-rzg2l:~# gpt ch:3, irq=2

root@smarc-rzg2l:~# /poeg.sh
Test case 2 GPT control with renesas,poeg-config = <4>;
[POEG]open
[POEG] GPT control configure IRQ
Read at address  0x10048434 (0xffff9bbea434): 0x031B031B
Read at address  0x10048438 (0xffffa33fd438): 0x43000000
Read at address  0x10049400 (0xffffa4bdc400): 0x00000020
gpt ch:3, irq=4
gpt ch:3, irq=4
gpt ch:3, irq=4
gpt ch:3, irq=4
Read at address  0x10048434 (0xffff8e05e434): 0x021B031B
Read at address  0x10048438 (0xffffbc765438): 0x43000000
Read at address  0x10049400 (0xffffa1ed1400): 0x00000020
 73:          5          0     GICv3 357 Level     10049400.poeg
root@smarc-rzg2l:~# gpt ch:3, irq=4

v6->v7:
 * Documented renesas,poeg-config optional property for configuring the
   system for pin output disable.
 * Used DT to handle the system configuration
 * Added poeg char device for user control support to enable/disable
   output from GPT
 * Replaced iowrite32/ioread32-> writel/readl
 * Dropped of_match_ptr from .of_match_table
v5->v6:
 * Dropped binding patch as it is accepted for 6.4.
 * Added sysfs support for configuring pin output disable 
   function in a generic way.
v4->v5:
 * Added Rb tag from Rob.
 * Updated kernel version in sysfs doc.
v3->v4:
 * Replaced companion->renesas,gpt for the phandle to gpt instance
 * Replaced renesas,id->renesas,poeg-id
 * Removed default from renesas,poeg-id as default for a required
   property doesn't make much sense.
 * Updated the example and required properties with above changes
v2->v3:
 * Removed Rb tag from Rob as there are some changes introduced.
 * Added companion property, so that poeg can link with gpt device
 * Documented renesas,id, as identifier for POEGG{A,B,C,D}.
 * Updated the binding example.
 * Added sysfs documentation for output_disable
 * PWM_RZG2L_GPT implies ARCH_RZG2L. So removed ARCH_RZG2L dependency
 * Used dev_get_drvdata to get device data
 * Replaced sprintf->sysfs_emit in show().
v1->v2:
 * Updated binding description.
 * Renamed the file poeg-rzg2l->rzg2l-poeg
 * Removed the macro POEGG as there is only single register and
   updated rzg2l_poeg_write() and rzg2l_poeg_read()
 * Updated error handling in probe()
REF->v1:
 * Modelled as pincontrol as most of its configuration is intended to be
   static and moved driver files from soc to pincontrol directory.
 * Updated reg size in dt binding example.
 * Updated Kconfig


Biju Das (10):
  dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config
    property
  drivers: pinctrl: renesas: Add RZ/G2L POEG driver support
  pwm: rzg2l-gpt: Add support for output disable request from gpt
  pinctrl: renesas: rzg2l-poeg: Add support for GPT Output-Disable
    Request
  pwm: rzg2l-gpt: Add support for output disable when both output low
  pinctrl: renesas: rzg2l-poeg: output-disable request from GPT when
    both outputs are low.
  pwm: rzg2l-gpt: Add support for output disable on dead time error
  pinctrl: renesas: rzg2l-poeg: output-disable request from GPT on dead
    time error
  pinctrl: renesas: rzg2l-poeg: output-disable request by external pin
  tools/poeg: Add test app for poeg

 .../bindings/pinctrl/renesas,rzg2l-poeg.yaml  |  16 +
 drivers/pinctrl/renesas/Kconfig               |   2 +
 drivers/pinctrl/renesas/Makefile              |   2 +
 drivers/pinctrl/renesas/poeg/Kconfig          |  11 +
 drivers/pinctrl/renesas/poeg/Makefile         |   2 +
 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c     | 500 ++++++++++++++++++
 drivers/pwm/pwm-rzg2l-gpt.c                   | 129 +++++
 include/linux/pinctrl/rzg2l-poeg.h            |  28 +
 include/linux/pwm/rzg2l-gpt.h                 |  44 ++
 tools/poeg/Build                              |   1 +
 tools/poeg/Makefile                           |  53 ++
 tools/poeg/poeg_app.c                         | 102 ++++
 12 files changed, 890 insertions(+)
 create mode 100644 drivers/pinctrl/renesas/poeg/Kconfig
 create mode 100644 drivers/pinctrl/renesas/poeg/Makefile
 create mode 100644 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
 create mode 100644 include/linux/pinctrl/rzg2l-poeg.h
 create mode 100644 include/linux/pwm/rzg2l-gpt.h
 create mode 100644 tools/poeg/Build
 create mode 100644 tools/poeg/Makefile
 create mode 100644 tools/poeg/poeg_app.c

-- 
2.25.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-31  9:48   ` Linus Walleij
  2023-04-03 20:39   ` Rob Herring
  2023-03-28 10:10 ` [PATCH v7 02/10] drivers: pinctrl: renesas: Add RZ/G2L POEG driver support Biju Das
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Rob Herring, Krzysztof Kozlowski
  Cc: Biju Das, Geert Uytterhoeven, linux-renesas-soc, linux-gpio,
	devicetree, Prabhakar Mahadev Lad

Document renesas,poeg-config optional property.

The output pins of the general PWM timer (GPT) can be disabled by using
the port output enabling function for the GPT (POEG). The HW supports
following ways to disable the output pins.

1) Pin output disable by input level detection of the GTETRG{A..D} pins
2) Output disable request from the GPT
3) Pin output disable by user control

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v7:
 * New patch
Ref:
 https://lore.kernel.org/linux-renesas-soc/20230306090014.128732-1-biju.das.jz@bp.renesas.com/T/#m07d2c4661d772a705b5a48fd050b7007b830f3eb
---
 .../bindings/pinctrl/renesas,rzg2l-poeg.yaml     | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-poeg.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-poeg.yaml
index ab2d456c93e4..ae027a490206 100644
--- a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-poeg.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-poeg.yaml
@@ -57,6 +57,21 @@ properties:
         <2> : POEG group C
         <3> : POEG group D
 
+  renesas,poeg-config:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [ 1, 2, 4, 6, 8, 10, 12, 14, 16 ]
+    description: |
+      POEG Configuration. Valid values are:
+        <1> :  User control
+        <2> :  GPT both output high
+        <4> :  GPT both output low
+        <6> :  GPT both output high + GPT both output low
+        <8> :  GPT dead time error
+        <10> : GPT both output high + GPT dead time error
+        <12> : GPT both output low + GPT dead time error
+        <14> : GPT both output {high, low} + GPT dead time error
+        <16> : External pin control
+
 required:
   - compatible
   - reg
@@ -83,4 +98,5 @@ examples:
         resets = <&cpg R9A07G044_POEG_D_RST>;
         renesas,poeg-id = <3>;
         renesas,gpt = <&gpt>;
+        renesas,poeg-config = <1>;
     };
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 02/10] drivers: pinctrl: renesas: Add RZ/G2L POEG driver support
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
  2023-03-28 10:10 ` [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 03/10] pwm: rzg2l-gpt: Add support for output disable request from gpt Biju Das
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Philipp Zabel
  Cc: Biju Das, Geert Uytterhoeven, Thierry Reding,
	Uwe Kleine-König, linux-pwm, linux-renesas-soc, linux-gpio,
	Chris Paterson, Prabhakar Mahadev Lad

The output pins of the RZ/G2L general PWM timer (GPT) can be disabled
by using the port output enabling function for the GPT (POEG).

Add basic user control support to enable/disable output from GPT
by using poeg char device.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v6->v7:
 * Used DT to handle the system configuration
 * Added poeg char device for user control support to enable/disable
   output from GPT
 * Replaced iowrite32/ioread32-> writel/readl
 * Dropped of_match_ptr from .of_match_table
v5->v6:
 * Dropped sysfs and is handled in generic driver.
v4->v5:
 * Updated kernel version in sysfs doc.
v3->v4:
 * Updated commit description.
v2->v3:
 * Added sysfs documentation for output_disable
 * PWM_RZG2L_GPT implies ARCH_RZG2L. So removed ARCH_RZG2L dependency
 * Used dev_get_drvdata to get device data
 * Replaced sprintf->sysfs_emit in show().
v1->v2:
 * Renamed the file poeg-rzg2l->rzg2l-poeg
 * Removed the macro POEGG as there is only single register and
   updated rzg2l_poeg_write() and rzg2l_poeg_read()
 * Updated error handling in probe()
Ref->v1:
 * Moved driver files from soc to pincontrol directory
 * Updated KConfig
---
 drivers/pinctrl/renesas/Kconfig           |   2 +
 drivers/pinctrl/renesas/Makefile          |   2 +
 drivers/pinctrl/renesas/poeg/Kconfig      |  11 +
 drivers/pinctrl/renesas/poeg/Makefile     |   2 +
 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c | 299 ++++++++++++++++++++++
 include/linux/pinctrl/rzg2l-poeg.h        |  15 ++
 6 files changed, 331 insertions(+)
 create mode 100644 drivers/pinctrl/renesas/poeg/Kconfig
 create mode 100644 drivers/pinctrl/renesas/poeg/Makefile
 create mode 100644 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
 create mode 100644 include/linux/pinctrl/rzg2l-poeg.h

diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig
index 77730dc548ed..42e030ae2783 100644
--- a/drivers/pinctrl/renesas/Kconfig
+++ b/drivers/pinctrl/renesas/Kconfig
@@ -303,4 +303,6 @@ config PINCTRL_PFC_SHX3
 	bool "pin control support for SH-X3" if COMPILE_TEST
 	select PINCTRL_SH_FUNC_GPIO
 
+source "drivers/pinctrl/renesas/poeg/Kconfig"
+
 endmenu
diff --git a/drivers/pinctrl/renesas/Makefile b/drivers/pinctrl/renesas/Makefile
index 3e776955bd4b..03338920725e 100644
--- a/drivers/pinctrl/renesas/Makefile
+++ b/drivers/pinctrl/renesas/Makefile
@@ -51,6 +51,8 @@ obj-$(CONFIG_PINCTRL_RZG2L)	+= pinctrl-rzg2l.o
 obj-$(CONFIG_PINCTRL_RZN1)	+= pinctrl-rzn1.o
 obj-$(CONFIG_PINCTRL_RZV2M)	+= pinctrl-rzv2m.o
 
+obj-$(CONFIG_POEG_RZG2L)	+= poeg/
+
 ifeq ($(CONFIG_COMPILE_TEST),y)
 CFLAGS_pfc-sh7203.o	+= -I$(srctree)/arch/sh/include/cpu-sh2a
 CFLAGS_pfc-sh7264.o	+= -I$(srctree)/arch/sh/include/cpu-sh2a
diff --git a/drivers/pinctrl/renesas/poeg/Kconfig b/drivers/pinctrl/renesas/poeg/Kconfig
new file mode 100644
index 000000000000..306e8ae81cb2
--- /dev/null
+++ b/drivers/pinctrl/renesas/poeg/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+config POEG_RZG2L
+	tristate "Renesas RZ/G2L poeg support"
+	depends on PWM_RZG2L_GPT || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This driver exposes the Port Output Enable for GPT(POEG) found
+	  in Renesas RZ/G2L alike SoCs.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called rzg2l-poeg.
diff --git a/drivers/pinctrl/renesas/poeg/Makefile b/drivers/pinctrl/renesas/poeg/Makefile
new file mode 100644
index 000000000000..610bdd6182be
--- /dev/null
+++ b/drivers/pinctrl/renesas/poeg/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_POEG_RZG2L)	+= rzg2l-poeg.o
diff --git a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
new file mode 100644
index 000000000000..30e75954af76
--- /dev/null
+++ b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
@@ -0,0 +1,299 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/G2L Port Output Enable for GPT (POEG) driver
+ *
+ * Copyright (C) 2023 Renesas Electronics Corporation
+ */
+#include <linux/cdev.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/rzg2l-poeg.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#define POEGG_SSF	BIT(3)
+
+#define RZG2L_POEG_MAX_INDEX		3
+
+#define RZG2L_GPT_MAX_HW_CHANNELS	8
+#define RZG2L_GPT_INVALID_CHANNEL	0xff
+
+enum poeg_conf {
+	POEG_USER_CTRL = BIT(0),
+	POEG_GPT_BOTH_HIGH = BIT(1),
+	POEG_GPT_BOTH_LOW = BIT(2),
+	POEG_GPT_DEAD_TIME = BIT(3),
+	POEG_EXT_PIN_CTRL = BIT(4),
+	POEG_GPT_BOTH_HIGH_LOW = BIT(1) | BIT(2),
+	POEG_GPT_BOTH_HIGH_DEAD_TIME = BIT(1) | BIT(3),
+	POEG_GPT_BOTH_LOW_DEAD_TIME = BIT(2) | BIT(3),
+	POEG_GPT_ALL = BIT(1) | BIT(2) | BIT(3)
+};
+
+static struct class *poeg_class;
+static dev_t g_poeg_dev;
+static int minor_n;
+
+struct rzg2l_poeg_chip {
+	struct device *gpt_dev;
+	struct reset_control *rstc;
+	void __iomem *mmio;
+	struct cdev poeg_cdev;
+	u8 gpt_channels[RZG2L_GPT_MAX_HW_CHANNELS];
+	u8 index;
+	u32 cfg;
+	int minor_n;
+};
+
+static void rzg2l_poeg_write(struct rzg2l_poeg_chip *chip, u32 data)
+{
+	writel(data, chip->mmio);
+}
+
+static u32 rzg2l_poeg_read(struct rzg2l_poeg_chip *chip)
+{
+	return readl(chip->mmio);
+}
+
+static int rzg2l_poeg_output_disable_user(struct rzg2l_poeg_chip *chip,
+					  bool enable)
+{
+	u32 reg_val;
+
+	reg_val = rzg2l_poeg_read(chip);
+	if (enable)
+		reg_val |= POEGG_SSF;
+	else
+		reg_val &= ~POEGG_SSF;
+
+	rzg2l_poeg_write(chip, reg_val);
+
+	return 0;
+}
+
+static ssize_t rzg2l_poeg_chrdev_write(struct file *filp,
+				       const char __user *buf,
+				       size_t len, loff_t *f_ps)
+{
+	struct rzg2l_poeg_chip *const chip = filp->private_data;
+	struct poeg_cmd cmd;
+
+	if (copy_from_user(&cmd, buf, sizeof(cmd)))
+		return -EFAULT;
+
+	switch (cmd.val) {
+	case RZG2L_POEG_USR_CTRL_ENABLE_CMD:
+		rzg2l_poeg_output_disable_user(chip, true);
+		break;
+	case RZG2L_POEG_USR_CTRL_DISABLE_CMD:
+		rzg2l_poeg_output_disable_user(chip, false);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return len;
+}
+
+static int rzg2l_poeg_chrdev_open(struct inode *inode, struct file *filp)
+{
+	struct rzg2l_poeg_chip *const chip = container_of(inode->i_cdev,
+							  typeof(*chip),
+							  poeg_cdev);
+
+	filp->private_data = chip;
+
+	return nonseekable_open(inode, filp);
+}
+
+static int rzg2l_poeg_chrdev_release(struct inode *inode, struct file *filp)
+{
+	filp->private_data = NULL;
+
+	return 0;
+}
+
+static const struct file_operations poeg_fops = {
+	.owner = THIS_MODULE,
+	.write = rzg2l_poeg_chrdev_write,
+	.open = rzg2l_poeg_chrdev_open,
+	.release = rzg2l_poeg_chrdev_release,
+};
+
+static const struct of_device_id rzg2l_poeg_of_table[] = {
+	{ .compatible = "renesas,rzg2l-poeg", },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, rzg2l_poeg_of_table);
+
+static void rzg2l_poeg_cleanup(void *data)
+{
+	struct rzg2l_poeg_chip *chip = data;
+
+	put_device(chip->gpt_dev);
+}
+
+static int rzg2l_poeg_probe(struct platform_device *pdev)
+{
+	struct platform_device *gpt_pdev = NULL;
+	struct rzg2l_poeg_chip *chip;
+	struct device_node *np;
+	struct device *cdev;
+	u32 cfg, val;
+	int ret;
+
+	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	if (!of_property_read_u32(pdev->dev.of_node, "renesas,poeg-id", &val))
+		chip->index = val;
+
+	if (chip->index > RZG2L_POEG_MAX_INDEX)
+		return -EINVAL;
+
+	np = of_parse_phandle(pdev->dev.of_node, "renesas,gpt", 0);
+	if (np)
+		gpt_pdev = of_find_device_by_node(np);
+
+	of_node_put(np);
+	if (!gpt_pdev)
+		return -ENODEV;
+
+	chip->gpt_dev = &gpt_pdev->dev;
+	ret = devm_add_action_or_reset(&pdev->dev, rzg2l_poeg_cleanup, chip);
+	if (ret < 0)
+		return ret;
+
+	chip->mmio = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(chip->mmio))
+		return PTR_ERR(chip->mmio);
+
+	chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(chip->rstc))
+		return dev_err_probe(&pdev->dev, PTR_ERR(chip->rstc),
+				     "get reset failed\n");
+
+	ret = reset_control_deassert(chip->rstc);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, chip);
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pm_runtime_resume_get failed: %d\n", ret);
+		goto err_pm_disable;
+	}
+
+	if (!of_property_read_u32(pdev->dev.of_node, "renesas,poeg-config", &cfg)) {
+		switch (cfg) {
+		case POEG_USER_CTRL:
+			rzg2l_poeg_write(chip, POEGG_SSF);
+			break;
+		default:
+			ret = -EINVAL;
+			goto err_pm;
+		}
+
+		chip->cfg = cfg;
+
+		cdev_init(&chip->poeg_cdev, &poeg_fops);
+		chip->poeg_cdev.owner = THIS_MODULE;
+		ret = cdev_add(&chip->poeg_cdev, MKDEV(MAJOR(g_poeg_dev), minor_n), 1);
+		if (ret)
+			goto err_pm;
+
+		cdev = device_create(poeg_class, NULL,
+				     MKDEV(MAJOR(g_poeg_dev), minor_n), NULL,
+				     "poeg%d", minor_n);
+		if (IS_ERR(cdev)) {
+			ret = PTR_ERR(cdev);
+			dev_err(&pdev->dev,
+				"Error %d creating device for port %u\n",
+				ret, minor_n);
+			goto free_cdev;
+		}
+		chip->minor_n = minor_n;
+	}
+
+	minor_n++;
+
+	return ret;
+
+free_cdev:
+	cdev_del(&chip->poeg_cdev);
+err_pm:
+	pm_runtime_put(&pdev->dev);
+err_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+	reset_control_assert(chip->rstc);
+	return ret;
+}
+
+static int rzg2l_poeg_remove(struct platform_device *pdev)
+{
+	struct rzg2l_poeg_chip *chip = platform_get_drvdata(pdev);
+
+	device_destroy(poeg_class, MKDEV(MAJOR(g_poeg_dev), chip->minor_n));
+	cdev_del(&chip->poeg_cdev);
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	reset_control_assert(chip->rstc);
+
+	return 0;
+}
+
+static struct platform_driver rzg2l_poeg_driver = {
+	.driver = {
+		.name = "rzg2l-poeg",
+		.of_match_table = rzg2l_poeg_of_table
+	},
+	.probe = rzg2l_poeg_probe,
+	.remove = rzg2l_poeg_remove
+};
+
+static int rzg2l_poeg_device_init(void)
+{
+	int err;
+
+	err = alloc_chrdev_region(&g_poeg_dev, 0, 1, "poeg");
+	if (err)
+		goto out;
+
+	poeg_class = class_create("poeg");
+	if (IS_ERR(poeg_class)) {
+		err = PTR_ERR(poeg_class);
+		goto err_free_chrdev;
+	}
+
+	err = platform_driver_register(&rzg2l_poeg_driver);
+	if (err)
+		goto err_class_destroy;
+
+	return 0;
+
+err_class_destroy:
+	class_destroy(poeg_class);
+err_free_chrdev:
+	unregister_chrdev_region(g_poeg_dev, 1);
+out:
+	return err;
+}
+
+static void rzg2l_poeg_device_exit(void)
+{
+	platform_driver_unregister(&rzg2l_poeg_driver);
+	class_destroy(poeg_class);
+	unregister_chrdev_region(g_poeg_dev, 1);
+}
+
+module_init(rzg2l_poeg_device_init);
+module_exit(rzg2l_poeg_device_exit);
+
+MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/G2L POEG Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/pinctrl/rzg2l-poeg.h b/include/linux/pinctrl/rzg2l-poeg.h
new file mode 100644
index 000000000000..32e7d07fc00e
--- /dev/null
+++ b/include/linux/pinctrl/rzg2l-poeg.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_POEG_RZG2L_H__
+#define __LINUX_POEG_RZG2L_H__
+
+#include <linux/types.h>
+
+#define RZG2L_POEG_USR_CTRL_ENABLE_CMD	0
+#define RZG2L_POEG_USR_CTRL_DISABLE_CMD	1
+
+struct poeg_cmd {
+	__u32 val;
+	__u8 channel;
+};
+
+#endif /* __LINUX_POEG_RZG2L_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 03/10] pwm: rzg2l-gpt: Add support for output disable request from gpt
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
  2023-03-28 10:10 ` [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property Biju Das
  2023-03-28 10:10 ` [PATCH v7 02/10] drivers: pinctrl: renesas: Add RZ/G2L POEG driver support Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 04/10] pinctrl: renesas: rzg2l-poeg: Add support for GPT Output-Disable Request Biju Das
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

When dead time error occurs or the GTIOCA pin output value is
the same as the GTIOCB pin output value, output protection is
required. GPT detects this condition and generates output disable
requests to POEG based on the settings in the output disable request
permission bits, such as GTINTAD.GRPDTE, GTINTAD.GRPABH,
GTINTAD.GRPABL. After the POEG receives output disable requests from
each channel and calculates external input using an OR operation, the
POEG generates output disable requests to GPT.

This patch adds support for output disable request from gpt,
when same time output level is high.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pwm/pwm-rzg2l-gpt.c   | 111 ++++++++++++++++++++++++++++++++++
 include/linux/pwm/rzg2l-gpt.h |  32 ++++++++++
 2 files changed, 143 insertions(+)
 create mode 100644 include/linux/pwm/rzg2l-gpt.h

diff --git a/drivers/pwm/pwm-rzg2l-gpt.c b/drivers/pwm/pwm-rzg2l-gpt.c
index 9f3e2f7635a8..2f138e95f752 100644
--- a/drivers/pwm/pwm-rzg2l-gpt.c
+++ b/drivers/pwm/pwm-rzg2l-gpt.c
@@ -25,6 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pwm.h>
+#include <linux/pwm/rzg2l-gpt.h>
 #include <linux/reset.h>
 #include <linux/time.h>
 
@@ -32,6 +33,7 @@
 #define RZG2L_GTUDDTYC		0x30
 #define RZG2L_GTIOR		0x34
 #define RZG2L_GTINTAD		0x38
+#define RZG2L_GTST		0x3c
 #define RZG2L_GTBER		0x40
 #define RZG2L_GTCNT		0x48
 #define RZG2L_GTCCRA		0x4c
@@ -72,6 +74,12 @@
 	(FIELD_PREP(RZG2L_GTIOR_GTIOB, RZG2L_INIT_OUT_LO_OUT_LO_END_TOGGLE) | RZG2L_GTIOR_OBE)
 
 #define RZG2L_GTINTAD_GRP_MASK			GENMASK(25, 24)
+#define RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_HIGH	BIT(29)
+
+#define RZG2L_GTST_OABHF			BIT(29)
+#define RZG2L_GTST_OABLF			BIT(30)
+
+#define RZG2L_GTST_POEG_IRQ_MASK		GENMASK(30, 28)
 
 #define RZG2L_GTCCR(i) (0x4c + 4 * (i))
 
@@ -431,6 +439,109 @@ static DEFINE_RUNTIME_DEV_PM_OPS(rzg2l_gpt_pm_ops,
 				 rzg2l_gpt_pm_runtime_suspend,
 				 rzg2l_gpt_pm_runtime_resume, NULL);
 
+u32 rzg2l_gpt_poeg_disable_req_irq_status(void *dev, u8 grp)
+{
+	u8 bitpos = grp * RZG2L_MAX_HW_CHANNELS;
+	struct rzg2l_gpt_chip *rzg2l_gpt;
+	unsigned int i;
+	u32 val = 0;
+	u32 offs;
+	u32 reg;
+
+	rzg2l_gpt = dev_get_drvdata(dev);
+	for (i = 0; i < RZG2L_MAX_HW_CHANNELS; i++) {
+		val <<= 3;
+		if (!test_bit(bitpos + i, rzg2l_gpt->poeg_gpt_link))
+			continue;
+
+		offs = RZG2L_GET_CH_OFFS(i);
+		reg = rzg2l_gpt_read(rzg2l_gpt, offs + RZG2L_GTST);
+		val |= FIELD_GET(RZG2L_GTST_POEG_IRQ_MASK, reg);
+	}
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_irq_status);
+
+int rzg2l_gpt_poeg_disable_req_clr(void *dev, u8 grp)
+{
+	u8 bitpos = grp * RZG2L_MAX_HW_CHANNELS;
+	struct rzg2l_gpt_chip *rzg2l_gpt;
+	unsigned int i;
+	u32 offs;
+	u32 reg;
+
+	rzg2l_gpt = dev_get_drvdata(dev);
+	for (i = 0; i < RZG2L_MAX_HW_CHANNELS; i++) {
+		if (!test_bit(bitpos + i, rzg2l_gpt->poeg_gpt_link))
+			continue;
+
+		offs = RZG2L_GET_CH_OFFS(i);
+		reg = rzg2l_gpt_read(rzg2l_gpt, offs + RZG2L_GTST);
+
+		if (reg & (RZG2L_GTST_OABHF | RZG2L_GTST_OABLF))
+			rzg2l_gpt_modify(rzg2l_gpt, offs + RZG2L_GTIOR,
+					 RZG2L_GTIOR_OBE, 0);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_clr);
+
+int rzg2l_gpt_pin_reenable(void *dev, u8 grp)
+{
+	u8 bitpos = grp * RZG2L_MAX_HW_CHANNELS;
+	struct rzg2l_gpt_chip *rzg2l_gpt;
+	unsigned int i;
+	u32 offs;
+
+	rzg2l_gpt = dev_get_drvdata(dev);
+	for (i = 0; i < RZG2L_MAX_HW_CHANNELS; i++) {
+		if (!test_bit(bitpos + i, rzg2l_gpt->poeg_gpt_link))
+			continue;
+
+		offs = RZG2L_GET_CH_OFFS(i);
+		rzg2l_gpt_modify(rzg2l_gpt, offs + RZG2L_GTIOR,
+				 RZG2L_GTIOR_OBE, RZG2L_GTIOR_OBE);
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rzg2l_gpt_pin_reenable);
+
+static int rzg2l_gpt_poeg_disable_req_endisable(void *dev, u8 grp, int op, bool on)
+{
+	u8 bitpos = grp * RZG2L_MAX_HW_CHANNELS;
+	struct rzg2l_gpt_chip *rzg2l_gpt;
+	unsigned int i;
+	u32 offs;
+
+	rzg2l_gpt = dev_get_drvdata(dev);
+	pm_runtime_get_sync(dev);
+
+	for (i = 0; i < RZG2L_MAX_HW_CHANNELS; i++) {
+		if (!test_bit(bitpos + i, rzg2l_gpt->poeg_gpt_link))
+			continue;
+
+		offs = RZG2L_GET_CH_OFFS(i);
+		if (on)
+			rzg2l_gpt_modify(rzg2l_gpt, offs + RZG2L_GTINTAD, op, op);
+		else
+			rzg2l_gpt_modify(rzg2l_gpt, offs + RZG2L_GTINTAD, op, 0);
+	}
+
+	pm_runtime_put(dev);
+
+	return 0;
+}
+
+int rzg2l_gpt_poeg_disable_req_both_high(void *dev, u8 grp, bool on)
+{
+	int id = RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_HIGH;
+
+	return rzg2l_gpt_poeg_disable_req_endisable(dev, grp, id, on);
+}
+EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_both_high);
+
 static void rzg2l_gpt_reset_assert_pm_disable(void *data)
 {
 	struct rzg2l_gpt_chip *rzg2l_gpt = data;
diff --git a/include/linux/pwm/rzg2l-gpt.h b/include/linux/pwm/rzg2l-gpt.h
new file mode 100644
index 000000000000..0fc13ab57420
--- /dev/null
+++ b/include/linux/pwm/rzg2l-gpt.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PWM_RZG2L_GPT_H__
+#define __LINUX_PWM_RZG2L_GPT_H__
+
+#if IS_ENABLED(CONFIG_PWM_RZG2L_GPT)
+u32 rzg2l_gpt_poeg_disable_req_irq_status(void *dev, u8 grp);
+int rzg2l_gpt_poeg_disable_req_clr(void *gpt_device, u8 grp);
+int rzg2l_gpt_pin_reenable(void *gpt_device, u8 grp);
+int rzg2l_gpt_poeg_disable_req_both_high(void *gpt_device, u8 grp, bool on);
+#else
+static inline u32 rzg2l_gpt_poeg_disable_req_irq_status(void *dev, u8 grp)
+{
+	return -ENODEV;
+}
+
+static inline int rzg2l_gpt_poeg_disable_req_clr(void *gpt_device, u8 grp)
+{
+	return -ENODEV;
+}
+
+static inline int rzg2l_gpt_pin_reenable(void *gpt_device, u8 grp)
+{
+	return -ENODEV;
+}
+
+static inline int rzg2l_gpt_poeg_disable_req_both_high(void *gpt_device, u8 grp, bool on)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif /* __LINUX_PWM_RZG2L_GPT_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 04/10] pinctrl: renesas: rzg2l-poeg: Add support for GPT Output-Disable Request
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (2 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 03/10] pwm: rzg2l-gpt: Add support for output disable request from gpt Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 05/10] pwm: rzg2l-gpt: Add support for output disable when both output low Biju Das
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

This patch supports output-disable requests from GPT.

When both outputs are high, gpt detects the condition and triggers
an interrupt to POEG. POEG handles the interrupt and send notification
to userspace. userspace handles the fault and issue a write call to
cancel the disable output request.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c | 165 +++++++++++++++++++++-
 include/linux/pinctrl/rzg2l-poeg.h        |   9 ++
 2 files changed, 173 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
index 30e75954af76..2683930309ca 100644
--- a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
+++ b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
@@ -5,16 +5,23 @@
  * Copyright (C) 2023 Renesas Electronics Corporation
  */
 #include <linux/cdev.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/kfifo.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/pinctrl/rzg2l-poeg.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/pwm/rzg2l-gpt.h>
+#include <linux/poll.h>
 #include <linux/reset.h>
+#include <linux/wait.h>
 
+#define POEGG_IOCE	BIT(5)
 #define POEGG_SSF	BIT(3)
+#define POEGG_IOCF	BIT(1)
 
 #define RZG2L_POEG_MAX_INDEX		3
 
@@ -41,7 +48,10 @@ struct rzg2l_poeg_chip {
 	struct device *gpt_dev;
 	struct reset_control *rstc;
 	void __iomem *mmio;
+	DECLARE_BITMAP(gpt_irq, 3);
 	struct cdev poeg_cdev;
+	wait_queue_head_t events_wait;
+	DECLARE_KFIFO_PTR(events, struct poeg_event);
 	u8 gpt_channels[RZG2L_GPT_MAX_HW_CHANNELS];
 	u8 index;
 	u32 cfg;
@@ -74,6 +84,76 @@ static int rzg2l_poeg_output_disable_user(struct rzg2l_poeg_chip *chip,
 	return 0;
 }
 
+static void rzg2l_poeg_config_irq(struct rzg2l_poeg_chip *chip)
+{
+	if (test_bit(RZG2L_GPT_OABHF, chip->gpt_irq))
+		rzg2l_gpt_poeg_disable_req_both_high(chip->gpt_dev, chip->index, true);
+}
+
+static irqreturn_t rzg2l_poeg_irq(int irq, void *ptr)
+{
+	struct rzg2l_poeg_chip *chip = ptr;
+	struct poeg_event ev;
+	u32 val;
+
+	val = rzg2l_gpt_poeg_disable_req_irq_status(chip->gpt_dev, chip->index);
+	ev.channel = chip->index;
+	ev.gpt_disable_irq_status = val;
+	kfifo_in(&chip->events, &ev, 1);
+	wake_up_poll(&chip->events_wait, EPOLLIN);
+
+	rzg2l_gpt_poeg_disable_req_clr(chip->gpt_dev, chip->index);
+	val = rzg2l_poeg_read(chip);
+	if (val & POEGG_IOCF)
+		val &= ~POEGG_IOCF;
+
+	rzg2l_poeg_write(chip, val);
+
+	return IRQ_HANDLED;
+}
+
+static __poll_t rzg2l_poeg_chrdev_poll(struct file *filp,
+				       struct poll_table_struct *pollt)
+{
+	struct rzg2l_poeg_chip *const chip = filp->private_data;
+	__poll_t events = 0;
+
+	poll_wait(filp, &chip->events_wait, pollt);
+	if (!kfifo_is_empty(&chip->events))
+		events = EPOLLIN | EPOLLRDNORM;
+
+	return events;
+}
+
+static ssize_t rzg2l_poeg_chrdev_read(struct file *filp, char __user *buf,
+				      size_t len, loff_t *f_ps)
+{
+	struct rzg2l_poeg_chip *const chip = filp->private_data;
+	unsigned int copied;
+	int err;
+
+	if (len < sizeof(struct poeg_event))
+		return -EINVAL;
+
+	do {
+		if (kfifo_is_empty(&chip->events)) {
+			if (filp->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			err = wait_event_interruptible(chip->events_wait,
+						       !kfifo_is_empty(&chip->events));
+			if (err < 0)
+				return err;
+		}
+
+		err = kfifo_to_user(&chip->events, buf, len, &copied);
+		if (err < 0)
+			return err;
+	} while (!copied);
+
+	return copied;
+}
+
 static ssize_t rzg2l_poeg_chrdev_write(struct file *filp,
 				       const char __user *buf,
 				       size_t len, loff_t *f_ps)
@@ -91,6 +171,12 @@ static ssize_t rzg2l_poeg_chrdev_write(struct file *filp,
 	case RZG2L_POEG_USR_CTRL_DISABLE_CMD:
 		rzg2l_poeg_output_disable_user(chip, false);
 		break;
+	case RZG2L_POEG_GPT_CFG_IRQ_CMD:
+		rzg2l_poeg_config_irq(chip);
+		break;
+	case RZG2L_POEG_GPT_FAULT_CLR_CMD:
+		rzg2l_gpt_pin_reenable(chip->gpt_dev, chip->index);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -118,11 +204,63 @@ static int rzg2l_poeg_chrdev_release(struct inode *inode, struct file *filp)
 
 static const struct file_operations poeg_fops = {
 	.owner = THIS_MODULE,
+	.read = rzg2l_poeg_chrdev_read,
 	.write = rzg2l_poeg_chrdev_write,
+	.poll = rzg2l_poeg_chrdev_poll,
 	.open = rzg2l_poeg_chrdev_open,
 	.release = rzg2l_poeg_chrdev_release,
 };
 
+static bool rzg2l_poeg_get_linked_gpt_channels(struct platform_device *pdev,
+					       struct rzg2l_poeg_chip *chip,
+					       struct device_node *gpt_np,
+					       u8 poeg_id)
+{
+	struct of_phandle_args of_args;
+	bool ret = false;
+	unsigned int i;
+	u32 poeg_grp;
+	int cells;
+	int err;
+
+	cells = of_property_count_u32_elems(gpt_np, "renesas,poegs");
+	if (cells == -EINVAL)
+		return ret;
+
+	for (i = 0 ; i < RZG2L_GPT_MAX_HW_CHANNELS; i++)
+		chip->gpt_channels[i] = RZG2L_GPT_INVALID_CHANNEL;
+
+	cells >>= 1;
+	for (i = 0; i < cells; i++) {
+		err = of_parse_phandle_with_fixed_args(gpt_np,
+						       "renesas,poegs", 1, i,
+						       &of_args);
+		if (err) {
+			dev_err(&pdev->dev,
+				"Failed to parse 'renesas,poegs' property\n");
+			break;
+		}
+
+		if (of_args.args[0] >= RZG2L_GPT_MAX_HW_CHANNELS) {
+			dev_err(&pdev->dev, "Invalid channel %d >= %d\n",
+				of_args.args[0], RZG2L_GPT_MAX_HW_CHANNELS);
+			of_node_put(of_args.np);
+			break;
+		}
+
+		if (!of_property_read_u32(of_args.np, "renesas,poeg-id", &poeg_grp)) {
+			if (poeg_grp == poeg_id) {
+				chip->gpt_channels[of_args.args[0]] = poeg_id;
+				ret = true;
+			}
+		}
+
+		of_node_put(of_args.np);
+	}
+
+	return ret;
+}
+
 static const struct of_device_id rzg2l_poeg_of_table[] = {
 	{ .compatible = "renesas,rzg2l-poeg", },
 	{ /* Sentinel */ }
@@ -140,10 +278,11 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 {
 	struct platform_device *gpt_pdev = NULL;
 	struct rzg2l_poeg_chip *chip;
+	bool gpt_linked = false;
 	struct device_node *np;
 	struct device *cdev;
 	u32 cfg, val;
-	int ret;
+	int ret, irq;
 
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
@@ -159,6 +298,8 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 	if (np)
 		gpt_pdev = of_find_device_by_node(np);
 
+	gpt_linked = rzg2l_poeg_get_linked_gpt_channels(pdev, chip, np,
+							chip->index);
 	of_node_put(np);
 	if (!gpt_pdev)
 		return -ENODEV;
@@ -172,6 +313,17 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 	if (IS_ERR(chip->mmio))
 		return PTR_ERR(chip->mmio);
 
+	if (gpt_linked) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
+
+		ret = devm_request_irq(&pdev->dev, irq, rzg2l_poeg_irq, 0,
+				       dev_name(&pdev->dev), chip);
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret, "cannot get irq\n");
+	}
+
 	chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 	if (IS_ERR(chip->rstc))
 		return dev_err_probe(&pdev->dev, PTR_ERR(chip->rstc),
@@ -194,13 +346,20 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 		case POEG_USER_CTRL:
 			rzg2l_poeg_write(chip, POEGG_SSF);
 			break;
+		case POEG_GPT_BOTH_HIGH:
+			assign_bit(RZG2L_GPT_OABHF, chip->gpt_irq, true);
+			break;
 		default:
 			ret = -EINVAL;
 			goto err_pm;
 		}
 
+		if (cfg & POEG_GPT_ALL)
+			rzg2l_poeg_write(chip, POEGG_IOCE);
+
 		chip->cfg = cfg;
 
+		init_waitqueue_head(&chip->events_wait);
 		cdev_init(&chip->poeg_cdev, &poeg_fops);
 		chip->poeg_cdev.owner = THIS_MODULE;
 		ret = cdev_add(&chip->poeg_cdev, MKDEV(MAJOR(g_poeg_dev), minor_n), 1);
@@ -218,6 +377,9 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 			goto free_cdev;
 		}
 		chip->minor_n = minor_n;
+		ret = kfifo_alloc(&chip->events, 64, GFP_KERNEL);
+		if (ret)
+			goto free_cdev;
 	}
 
 	minor_n++;
@@ -238,6 +400,7 @@ static int rzg2l_poeg_remove(struct platform_device *pdev)
 {
 	struct rzg2l_poeg_chip *chip = platform_get_drvdata(pdev);
 
+	kfifo_free(&chip->events);
 	device_destroy(poeg_class, MKDEV(MAJOR(g_poeg_dev), chip->minor_n));
 	cdev_del(&chip->poeg_cdev);
 	pm_runtime_put(&pdev->dev);
diff --git a/include/linux/pinctrl/rzg2l-poeg.h b/include/linux/pinctrl/rzg2l-poeg.h
index 32e7d07fc00e..d21b70c219e6 100644
--- a/include/linux/pinctrl/rzg2l-poeg.h
+++ b/include/linux/pinctrl/rzg2l-poeg.h
@@ -4,8 +4,17 @@
 
 #include <linux/types.h>
 
+#define RZG2L_GPT_OABHF	1
+
 #define RZG2L_POEG_USR_CTRL_ENABLE_CMD	0
 #define RZG2L_POEG_USR_CTRL_DISABLE_CMD	1
+#define RZG2L_POEG_GPT_CFG_IRQ_CMD		2
+#define RZG2L_POEG_GPT_FAULT_CLR_CMD		3
+
+struct poeg_event {
+	__u32 gpt_disable_irq_status;
+	__u8 channel;
+};
 
 struct poeg_cmd {
 	__u32 val;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 05/10] pwm: rzg2l-gpt: Add support for output disable when both output low
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (3 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 04/10] pinctrl: renesas: rzg2l-poeg: Add support for GPT Output-Disable Request Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 06/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT when both outputs are low Biju Das
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

This patch adds support for output disable request from gpt,
when same time output level is low.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pwm/pwm-rzg2l-gpt.c   | 9 +++++++++
 include/linux/pwm/rzg2l-gpt.h | 6 ++++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/pwm/pwm-rzg2l-gpt.c b/drivers/pwm/pwm-rzg2l-gpt.c
index 2f138e95f752..2291cc3cff39 100644
--- a/drivers/pwm/pwm-rzg2l-gpt.c
+++ b/drivers/pwm/pwm-rzg2l-gpt.c
@@ -75,6 +75,7 @@
 
 #define RZG2L_GTINTAD_GRP_MASK			GENMASK(25, 24)
 #define RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_HIGH	BIT(29)
+#define RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_LOW	BIT(30)
 
 #define RZG2L_GTST_OABHF			BIT(29)
 #define RZG2L_GTST_OABLF			BIT(30)
@@ -542,6 +543,14 @@ int rzg2l_gpt_poeg_disable_req_both_high(void *dev, u8 grp, bool on)
 }
 EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_both_high);
 
+int rzg2l_gpt_poeg_disable_req_both_low(void *dev, u8 grp, bool on)
+{
+	int id = RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_LOW;
+
+	return rzg2l_gpt_poeg_disable_req_endisable(dev, grp, id, on);
+}
+EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_both_low);
+
 static void rzg2l_gpt_reset_assert_pm_disable(void *data)
 {
 	struct rzg2l_gpt_chip *rzg2l_gpt = data;
diff --git a/include/linux/pwm/rzg2l-gpt.h b/include/linux/pwm/rzg2l-gpt.h
index 0fc13ab57420..592bc2900c9e 100644
--- a/include/linux/pwm/rzg2l-gpt.h
+++ b/include/linux/pwm/rzg2l-gpt.h
@@ -7,6 +7,7 @@ u32 rzg2l_gpt_poeg_disable_req_irq_status(void *dev, u8 grp);
 int rzg2l_gpt_poeg_disable_req_clr(void *gpt_device, u8 grp);
 int rzg2l_gpt_pin_reenable(void *gpt_device, u8 grp);
 int rzg2l_gpt_poeg_disable_req_both_high(void *gpt_device, u8 grp, bool on);
+int rzg2l_gpt_poeg_disable_req_both_low(void *gpt_device, u8 grp, bool on);
 #else
 static inline u32 rzg2l_gpt_poeg_disable_req_irq_status(void *dev, u8 grp)
 {
@@ -27,6 +28,11 @@ static inline int rzg2l_gpt_poeg_disable_req_both_high(void *gpt_device, u8 grp,
 {
 	return -ENODEV;
 }
+
+static inline int rzg2l_gpt_poeg_disable_req_both_low(void *gpt_device, u8 grp, bool on)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif /* __LINUX_PWM_RZG2L_GPT_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 06/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT when both outputs are low.
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (4 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 05/10] pwm: rzg2l-gpt: Add support for output disable when both output low Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 07/10] pwm: rzg2l-gpt: Add support for output disable on dead time error Biju Das
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

This patch adds support for output-disable requests from GPT, when both
outputs are low.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c | 11 +++++++++++
 include/linux/pinctrl/rzg2l-poeg.h        |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
index 2683930309ca..b66d717d6bf4 100644
--- a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
+++ b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
@@ -88,6 +88,10 @@ static void rzg2l_poeg_config_irq(struct rzg2l_poeg_chip *chip)
 {
 	if (test_bit(RZG2L_GPT_OABHF, chip->gpt_irq))
 		rzg2l_gpt_poeg_disable_req_both_high(chip->gpt_dev, chip->index, true);
+
+	if (test_bit(RZG2L_GPT_OABLF, chip->gpt_irq))
+		rzg2l_gpt_poeg_disable_req_both_low(chip->gpt_dev, chip->index, true);
+
 }
 
 static irqreturn_t rzg2l_poeg_irq(int irq, void *ptr)
@@ -349,6 +353,13 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 		case POEG_GPT_BOTH_HIGH:
 			assign_bit(RZG2L_GPT_OABHF, chip->gpt_irq, true);
 			break;
+		case POEG_GPT_BOTH_LOW:
+			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
+			break;
+		case POEG_GPT_BOTH_HIGH_LOW:
+			assign_bit(RZG2L_GPT_OABHF, chip->gpt_irq, true);
+			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
+			break;
 		default:
 			ret = -EINVAL;
 			goto err_pm;
diff --git a/include/linux/pinctrl/rzg2l-poeg.h b/include/linux/pinctrl/rzg2l-poeg.h
index d21b70c219e6..e1e0ba5b47a1 100644
--- a/include/linux/pinctrl/rzg2l-poeg.h
+++ b/include/linux/pinctrl/rzg2l-poeg.h
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 
 #define RZG2L_GPT_OABHF	1
+#define RZG2L_GPT_OABLF	2
 
 #define RZG2L_POEG_USR_CTRL_ENABLE_CMD	0
 #define RZG2L_POEG_USR_CTRL_DISABLE_CMD	1
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 07/10] pwm: rzg2l-gpt: Add support for output disable on dead time error
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (5 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 06/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT when both outputs are low Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 08/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT " Biju Das
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

This patch adds support for output disable request from gpt,
when dead time error occurred.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pwm/pwm-rzg2l-gpt.c   | 9 +++++++++
 include/linux/pwm/rzg2l-gpt.h | 6 ++++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/pwm/pwm-rzg2l-gpt.c b/drivers/pwm/pwm-rzg2l-gpt.c
index 2291cc3cff39..c88a5bf9e31d 100644
--- a/drivers/pwm/pwm-rzg2l-gpt.c
+++ b/drivers/pwm/pwm-rzg2l-gpt.c
@@ -74,6 +74,7 @@
 	(FIELD_PREP(RZG2L_GTIOR_GTIOB, RZG2L_INIT_OUT_LO_OUT_LO_END_TOGGLE) | RZG2L_GTIOR_OBE)
 
 #define RZG2L_GTINTAD_GRP_MASK			GENMASK(25, 24)
+#define RZG2L_GTINTAD_OUTPUT_DISABLE_DEADTIME_ERROR	BIT(28)
 #define RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_HIGH	BIT(29)
 #define RZG2L_GTINTAD_OUTPUT_DISABLE_SAME_LEVEL_LOW	BIT(30)
 
@@ -551,6 +552,14 @@ int rzg2l_gpt_poeg_disable_req_both_low(void *dev, u8 grp, bool on)
 }
 EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_both_low);
 
+int rzg2l_gpt_poeg_disable_req_deadtime_error(void *dev, u8 grp, bool on)
+{
+	int id = RZG2L_GTINTAD_OUTPUT_DISABLE_DEADTIME_ERROR;
+
+	return rzg2l_gpt_poeg_disable_req_endisable(dev, grp, id, on);
+}
+EXPORT_SYMBOL_GPL(rzg2l_gpt_poeg_disable_req_deadtime_error);
+
 static void rzg2l_gpt_reset_assert_pm_disable(void *data)
 {
 	struct rzg2l_gpt_chip *rzg2l_gpt = data;
diff --git a/include/linux/pwm/rzg2l-gpt.h b/include/linux/pwm/rzg2l-gpt.h
index 592bc2900c9e..8a004c690c2a 100644
--- a/include/linux/pwm/rzg2l-gpt.h
+++ b/include/linux/pwm/rzg2l-gpt.h
@@ -8,6 +8,7 @@ int rzg2l_gpt_poeg_disable_req_clr(void *gpt_device, u8 grp);
 int rzg2l_gpt_pin_reenable(void *gpt_device, u8 grp);
 int rzg2l_gpt_poeg_disable_req_both_high(void *gpt_device, u8 grp, bool on);
 int rzg2l_gpt_poeg_disable_req_both_low(void *gpt_device, u8 grp, bool on);
+int rzg2l_gpt_poeg_disable_req_deadtime_error(void *gpt_device, u8 grp, bool on);
 #else
 static inline u32 rzg2l_gpt_poeg_disable_req_irq_status(void *dev, u8 grp)
 {
@@ -33,6 +34,11 @@ static inline int rzg2l_gpt_poeg_disable_req_both_low(void *gpt_device, u8 grp,
 {
 	return -ENODEV;
 }
+
+static inline int rzg2l_gpt_poeg_disable_req_deadtime_err(void *gpt_device, u8 grp, bool on)
+{
+	return -ENODEV;
+}
 #endif
 
 #endif /* __LINUX_PWM_RZG2L_GPT_H__ */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 08/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT on dead time error
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (6 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 07/10] pwm: rzg2l-gpt: Add support for output disable on dead time error Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 09/10] pinctrl: renesas: rzg2l-poeg: output-disable request by external pin Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 10/10] tools/poeg: Add test app for poeg Biju Das
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

This patch adds support for output-disable requests from GPT,
when dead time error occurs.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c | 18 ++++++++++++++++++
 include/linux/pinctrl/rzg2l-poeg.h        |  1 +
 2 files changed, 19 insertions(+)

diff --git a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
index b66d717d6bf4..7576f756af3c 100644
--- a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
+++ b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
@@ -92,6 +92,8 @@ static void rzg2l_poeg_config_irq(struct rzg2l_poeg_chip *chip)
 	if (test_bit(RZG2L_GPT_OABLF, chip->gpt_irq))
 		rzg2l_gpt_poeg_disable_req_both_low(chip->gpt_dev, chip->index, true);
 
+	if (test_bit(RZG2L_GPT_DTEF, chip->gpt_irq))
+		rzg2l_gpt_poeg_disable_req_deadtime_error(chip->gpt_dev, chip->index, true);
 }
 
 static irqreturn_t rzg2l_poeg_irq(int irq, void *ptr)
@@ -356,10 +358,26 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 		case POEG_GPT_BOTH_LOW:
 			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
 			break;
+		case POEG_GPT_DEAD_TIME:
+			assign_bit(RZG2L_GPT_DTEF, chip->gpt_irq, true);
+			break;
 		case POEG_GPT_BOTH_HIGH_LOW:
 			assign_bit(RZG2L_GPT_OABHF, chip->gpt_irq, true);
 			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
 			break;
+		case POEG_GPT_BOTH_HIGH_DEAD_TIME:
+			assign_bit(RZG2L_GPT_OABHF, chip->gpt_irq, true);
+			assign_bit(RZG2L_GPT_DTEF, chip->gpt_irq, true);
+			break;
+		case POEG_GPT_BOTH_LOW_DEAD_TIME:
+			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
+			assign_bit(RZG2L_GPT_DTEF, chip->gpt_irq, true);
+			break;
+		case POEG_GPT_ALL:
+			assign_bit(RZG2L_GPT_OABHF, chip->gpt_irq, true);
+			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
+			assign_bit(RZG2L_GPT_DTEF, chip->gpt_irq, true);
+			break;
 		default:
 			ret = -EINVAL;
 			goto err_pm;
diff --git a/include/linux/pinctrl/rzg2l-poeg.h b/include/linux/pinctrl/rzg2l-poeg.h
index e1e0ba5b47a1..5441de7f3751 100644
--- a/include/linux/pinctrl/rzg2l-poeg.h
+++ b/include/linux/pinctrl/rzg2l-poeg.h
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 
+#define RZG2L_GPT_DTEF	0
 #define RZG2L_GPT_OABHF	1
 #define RZG2L_GPT_OABLF	2
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 09/10] pinctrl: renesas: rzg2l-poeg: output-disable request by external pin
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (7 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 08/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT " Biju Das
@ 2023-03-28 10:10 ` Biju Das
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 10/10] tools/poeg: Add test app for poeg Biju Das
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

Add support for output-disable request by external pin.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 drivers/pinctrl/renesas/poeg/rzg2l-poeg.c | 9 +++++++++
 include/linux/pinctrl/rzg2l-poeg.h        | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
index 7576f756af3c..5d93a0be33f3 100644
--- a/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
+++ b/drivers/pinctrl/renesas/poeg/rzg2l-poeg.c
@@ -15,13 +15,16 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pwm/rzg2l-gpt.h>
+#include <linux/pinctrl/rzg2l-poeg.h>
 #include <linux/poll.h>
 #include <linux/reset.h>
 #include <linux/wait.h>
 
 #define POEGG_IOCE	BIT(5)
+#define POEGG_PIDE	BIT(4)
 #define POEGG_SSF	BIT(3)
 #define POEGG_IOCF	BIT(1)
+#define POEGG_PIDF	BIT(0)
 
 #define RZG2L_POEG_MAX_INDEX		3
 
@@ -113,6 +116,9 @@ static irqreturn_t rzg2l_poeg_irq(int irq, void *ptr)
 	if (val & POEGG_IOCF)
 		val &= ~POEGG_IOCF;
 
+	if (val & POEGG_PIDF)
+		val &= ~POEGG_PIDF;
+
 	rzg2l_poeg_write(chip, val);
 
 	return IRQ_HANDLED;
@@ -378,6 +384,9 @@ static int rzg2l_poeg_probe(struct platform_device *pdev)
 			assign_bit(RZG2L_GPT_OABLF, chip->gpt_irq, true);
 			assign_bit(RZG2L_GPT_DTEF, chip->gpt_irq, true);
 			break;
+		case POEG_EXT_PIN_CTRL:
+			rzg2l_poeg_write(chip, POEGG_PIDE);
+			break;
 		default:
 			ret = -EINVAL;
 			goto err_pm;
diff --git a/include/linux/pinctrl/rzg2l-poeg.h b/include/linux/pinctrl/rzg2l-poeg.h
index 5441de7f3751..359849fea6a0 100644
--- a/include/linux/pinctrl/rzg2l-poeg.h
+++ b/include/linux/pinctrl/rzg2l-poeg.h
@@ -7,11 +7,13 @@
 #define RZG2L_GPT_DTEF	0
 #define RZG2L_GPT_OABHF	1
 #define RZG2L_GPT_OABLF	2
+#define RZG2L_POEG_EXT_PIN_CTRL	3
 
 #define RZG2L_POEG_USR_CTRL_ENABLE_CMD	0
 #define RZG2L_POEG_USR_CTRL_DISABLE_CMD	1
 #define RZG2L_POEG_GPT_CFG_IRQ_CMD		2
 #define RZG2L_POEG_GPT_FAULT_CLR_CMD		3
+#define RZG2L_POEG_EXT_PIN_CTRL_FAULT_CLR_CMD	4
 
 struct poeg_event {
 	__u32 gpt_disable_irq_status;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [DO NOT APPLY PATCH v7 10/10] tools/poeg: Add test app for poeg
  2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
                   ` (8 preceding siblings ...)
  2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 09/10] pinctrl: renesas: rzg2l-poeg: output-disable request by external pin Biju Das
@ 2023-03-28 10:10 ` Biju Das
  9 siblings, 0 replies; 14+ messages in thread
From: Biju Das @ 2023-03-28 10:10 UTC (permalink / raw)
  To: Linus Walleij, Thierry Reding
  Cc: Biju Das, Uwe Kleine-König, Geert Uytterhoeven, Magnus Damm,
	linux-pwm, linux-renesas-soc, linux-gpio, Prabhakar Mahadev Lad

Add test app for poeg

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
 tools/poeg/Build      |   1 +
 tools/poeg/Makefile   |  53 ++++++++++++++++++++++
 tools/poeg/poeg_app.c | 102 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 156 insertions(+)
 create mode 100644 tools/poeg/Build
 create mode 100644 tools/poeg/Makefile
 create mode 100644 tools/poeg/poeg_app.c

diff --git a/tools/poeg/Build b/tools/poeg/Build
new file mode 100644
index 000000000000..f960920a4afb
--- /dev/null
+++ b/tools/poeg/Build
@@ -0,0 +1 @@
+poeg_app-y += poeg_app.o
diff --git a/tools/poeg/Makefile b/tools/poeg/Makefile
new file mode 100644
index 000000000000..669c914d9c98
--- /dev/null
+++ b/tools/poeg/Makefile
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: GPL-2.0
+include ../scripts/Makefile.include
+
+bindir ?= /usr/bin
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+endif
+
+# Do not use make's built-in rules
+# (this improves performance and avoids hard-to-debug behaviour);
+MAKEFLAGS += -r
+
+override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
+
+ALL_TARGETS := poeg_app
+ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
+
+all: $(ALL_PROGRAMS)
+
+export srctree OUTPUT CC LD CFLAGS
+include $(srctree)/tools/build/Makefile.include
+
+#
+# We need the following to be outside of kernel tree
+#
+$(OUTPUT)include/linux/poeg.h: ../../include/linux/pinctrl/rzg2l-poeg.h
+	mkdir -p $(OUTPUT)include/linux 2>&1 || true
+	ln -sf $(CURDIR)/../../include/linux/pinctrl/rzg2l-poeg.h $@
+
+prepare: $(OUTPUT)include/linux/poeg.h
+
+POEG_EXAMPLE := $(OUTPUT)poeg_app.o
+$(POEG_EXAMPLE): prepare FORCE
+	$(Q)$(MAKE) $(build)=poeg_app
+$(OUTPUT)poeg_app: $(POEG_EXAMPLE)
+	$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
+clean:
+	rm -f $(ALL_PROGRAMS)
+	rm -rf $(OUTPUT)include/linux/poeg.h
+	find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
+
+install: $(ALL_PROGRAMS)
+	install -d -m 755 $(DESTDIR)$(bindir);		\
+	for program in $(ALL_PROGRAMS); do		\
+		install $$program $(DESTDIR)$(bindir);	\
+	done
+
+FORCE:
+
+.PHONY: all install clean FORCE prepare
diff --git a/tools/poeg/poeg_app.c b/tools/poeg/poeg_app.c
new file mode 100644
index 000000000000..273ae1813e2f
--- /dev/null
+++ b/tools/poeg/poeg_app.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * POEG - example userspace application
+ * Copyright (C) 2023 Biju Das
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <linux/ioctl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <poll.h>
+
+#include <linux/poeg.h>
+
+#define USER_CTRL	1
+#define GPT_CTRL	0
+#define EXT_PIN_CTRL	0
+
+int main(int argc, char *arg[])
+{
+	struct poeg_cmd cmd;
+	int ret, fd;
+#if GPT_CTRL
+	struct poeg_event event_data;
+	unsigned int val;
+	int i;
+#endif
+
+	fd = open("/dev/poeg3", O_RDWR);
+	if (fd < 0)
+		perror("open");
+	else
+		printf("[POEG]open\n");
+
+#if USER_CTRL
+	cmd.val = RZG2L_POEG_USR_CTRL_ENABLE_CMD;
+	cmd.channel = 4;
+	printf("[POEG] user control pin output disable enabled\n");
+	ret = write(fd, &cmd, sizeof(cmd));
+	if (ret == -1) {
+		perror("Failed to write cmd data");
+		return 1;
+	}
+	sleep(3);
+
+	printf("[POEG] user control pin output disable disabled\n");
+	cmd.val = RZG2L_POEG_USR_CTRL_DISABLE_CMD;
+	cmd.channel = 4;
+	ret = write(fd, &cmd, sizeof(cmd));
+	if (ret == -1) {
+		perror("Failed to write cmd data");
+		return 1;
+	}
+#endif
+
+#if GPT_CTRL
+	printf("[POEG] GPT control configure IRQ\n");
+	cmd.val = RZG2L_POEG_GPT_CFG_IRQ_CMD;
+	cmd.channel = 4;
+	ret = write(fd, &cmd, sizeof(cmd));
+	if (ret == -1) {
+		perror("Failed to write cmd data");
+		return 1;
+	}
+
+	for (;;) {
+		ret = read(fd, &event_data, sizeof(event_data));
+		if (ret == -1) {
+			perror("Failed to read event data");
+			return 1;
+		}
+
+		val = event_data.gpt_disable_irq_status;
+		if (val) {
+			/* emulate fault clearing condition by adding delay */
+			sleep(2);
+			for (i = 0; i < 8; i++) {
+				if (val & 7) {
+					printf("gpt ch:%u, irq=%x\n", i, val & 7);
+					cmd.val = RZG2L_POEG_GPT_FAULT_CLR_CMD;
+					cmd.channel = 4;
+					ret = write(fd, &cmd, sizeof(cmd));
+				}
+				val >>= 3;
+			}
+		}
+	}
+#endif
+
+	if (close(fd) != 0)
+		perror("close");
+	else
+		printf("[POEG]close\n");
+
+	return 0;
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property
  2023-03-28 10:10 ` [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property Biju Das
@ 2023-03-31  9:48   ` Linus Walleij
  2023-03-31 12:11     ` Geert Uytterhoeven
  2023-04-03 20:39   ` Rob Herring
  1 sibling, 1 reply; 14+ messages in thread
From: Linus Walleij @ 2023-03-31  9:48 UTC (permalink / raw)
  To: Biju Das
  Cc: Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	linux-renesas-soc, linux-gpio, devicetree, Prabhakar Mahadev Lad

On Tue, Mar 28, 2023 at 12:10 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:

> Document renesas,poeg-config optional property.
>
> The output pins of the general PWM timer (GPT) can be disabled by using
> the port output enabling function for the GPT (POEG). The HW supports
> following ways to disable the output pins.
>
> 1) Pin output disable by input level detection of the GTETRG{A..D} pins
> 2) Output disable request from the GPT
> 3) Pin output disable by user control
>
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>

This looks good to me, Geert will know the details.
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property
  2023-03-31  9:48   ` Linus Walleij
@ 2023-03-31 12:11     ` Geert Uytterhoeven
  0 siblings, 0 replies; 14+ messages in thread
From: Geert Uytterhoeven @ 2023-03-31 12:11 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Biju Das, Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	linux-renesas-soc, linux-gpio, devicetree, Prabhakar Mahadev Lad

Hi Linus,

On Fri, Mar 31, 2023 at 11:49 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> On Tue, Mar 28, 2023 at 12:10 PM Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > Document renesas,poeg-config optional property.
> >
> > The output pins of the general PWM timer (GPT) can be disabled by using
> > the port output enabling function for the GPT (POEG). The HW supports
> > following ways to disable the output pins.
> >
> > 1) Pin output disable by input level detection of the GTETRG{A..D} pins
> > 2) Output disable request from the GPT
> > 3) Pin output disable by user control
> >
> > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
>
> This looks good to me, Geert will know the details.

TBH, I do not ;-)

> Acked-by: Linus Walleij <linus.walleij@linaro.org>

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property
  2023-03-28 10:10 ` [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property Biju Das
  2023-03-31  9:48   ` Linus Walleij
@ 2023-04-03 20:39   ` Rob Herring
  1 sibling, 0 replies; 14+ messages in thread
From: Rob Herring @ 2023-04-03 20:39 UTC (permalink / raw)
  To: Biju Das
  Cc: linux-gpio, Krzysztof Kozlowski, Linus Walleij, devicetree,
	Rob Herring, Prabhakar Mahadev Lad, linux-renesas-soc,
	Geert Uytterhoeven


On Tue, 28 Mar 2023 11:10:02 +0100, Biju Das wrote:
> Document renesas,poeg-config optional property.
> 
> The output pins of the general PWM timer (GPT) can be disabled by using
> the port output enabling function for the GPT (POEG). The HW supports
> following ways to disable the output pins.
> 
> 1) Pin output disable by input level detection of the GTETRG{A..D} pins
> 2) Output disable request from the GPT
> 3) Pin output disable by user control
> 
> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
> ---
> v7:
>  * New patch
> Ref:
>  https://lore.kernel.org/linux-renesas-soc/20230306090014.128732-1-biju.das.jz@bp.renesas.com/T/#m07d2c4661d772a705b5a48fd050b7007b830f3eb
> ---
>  .../bindings/pinctrl/renesas,rzg2l-poeg.yaml     | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-04-03 20:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-28 10:10 [PATCH v7 00/10] Add RZ/G2L POEG support Biju Das
2023-03-28 10:10 ` [PATCH v7 01/10] dt-bindings: pinctrl: rzg2l-poeg: Document renesas,poeg-config property Biju Das
2023-03-31  9:48   ` Linus Walleij
2023-03-31 12:11     ` Geert Uytterhoeven
2023-04-03 20:39   ` Rob Herring
2023-03-28 10:10 ` [PATCH v7 02/10] drivers: pinctrl: renesas: Add RZ/G2L POEG driver support Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 03/10] pwm: rzg2l-gpt: Add support for output disable request from gpt Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 04/10] pinctrl: renesas: rzg2l-poeg: Add support for GPT Output-Disable Request Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 05/10] pwm: rzg2l-gpt: Add support for output disable when both output low Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 06/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT when both outputs are low Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 07/10] pwm: rzg2l-gpt: Add support for output disable on dead time error Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 08/10] pinctrl: renesas: rzg2l-poeg: output-disable request from GPT " Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 09/10] pinctrl: renesas: rzg2l-poeg: output-disable request by external pin Biju Das
2023-03-28 10:10 ` [DO NOT APPLY PATCH v7 10/10] tools/poeg: Add test app for poeg Biju Das

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).