All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] reset: Basic reset controller
@ 2017-05-26  3:32 ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-26  3:32 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Mark Rutland
  Cc: devicetree, linux-kernel, Benjamin Herrenschmidt, Andrew Jeffery

Hello,

In the Aspeed SoCs we have some reset registers spread out in various parts of
the soc: in the system controller IP, as well as other peripherals. I need to be
able to deassert those resets before other drivers work.

In writing a driver to do this I realised it was very generic. So instead I've
sent a generic driver that can be used by the device tree to clear reset lines
described by single bits in a register.

Let me know what you think of the idea. I've tested this driver on our SoC to
release the UART reset.

Joel Stanley (2):
  dt-bindings: reset: Add bindings for basic reset controller
  reset: Add basic single-register reset driver

 .../devicetree/bindings/reset/reset-basic.txt      |  31 ++++++
 drivers/reset/Kconfig                              |   6 ++
 drivers/reset/Makefile                             |   1 +
 drivers/reset/reset-basic.c                        | 109 +++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt
 create mode 100644 drivers/reset/reset-basic.c

-- 
2.11.0

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

* [PATCH 0/2] reset: Basic reset controller
@ 2017-05-26  3:32 ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-26  3:32 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Mark Rutland
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

Hello,

In the Aspeed SoCs we have some reset registers spread out in various parts of
the soc: in the system controller IP, as well as other peripherals. I need to be
able to deassert those resets before other drivers work.

In writing a driver to do this I realised it was very generic. So instead I've
sent a generic driver that can be used by the device tree to clear reset lines
described by single bits in a register.

Let me know what you think of the idea. I've tested this driver on our SoC to
release the UART reset.

Joel Stanley (2):
  dt-bindings: reset: Add bindings for basic reset controller
  reset: Add basic single-register reset driver

 .../devicetree/bindings/reset/reset-basic.txt      |  31 ++++++
 drivers/reset/Kconfig                              |   6 ++
 drivers/reset/Makefile                             |   1 +
 drivers/reset/reset-basic.c                        | 109 +++++++++++++++++++++
 4 files changed, 147 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt
 create mode 100644 drivers/reset/reset-basic.c

-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/2] dt-bindings: reset: Add bindings for basic reset controller
@ 2017-05-26  3:32   ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-26  3:32 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Mark Rutland
  Cc: devicetree, linux-kernel, Benjamin Herrenschmidt, Andrew Jeffery

This adds the bindings documentation for a basic single-register reset
controller.

The bindings describe a single 32-bit register that contains up to 32
reset lines, each deasserted by clearing the appropriate bit in the
register.

Signed-off-by: Joel Stanley <joel@jms.id.au>
---
 .../devicetree/bindings/reset/reset-basic.txt      | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt

diff --git a/Documentation/devicetree/bindings/reset/reset-basic.txt b/Documentation/devicetree/bindings/reset/reset-basic.txt
new file mode 100644
index 000000000000..7341e04e7904
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/reset-basic.txt
@@ -0,0 +1,31 @@
+Basic single-register reset controller
+======================================
+
+This describes a generic reset controller where the reset lines are controlled
+by single bits within a 32-bit memory location. The memory location is assumed
+to be part of a syscon regmap.
+
+Reset controller required properties:
+ - compatible: should be "reset-basic"
+ - #reset-cells: must be set to 1
+ - reg: reset register location within regmap
+
+Device node required properties:
+ - resets phandle
+ - bit number, counting from zero, for the desired reset line. Max is 31.
+
+Example:
+
+syscon {
+	compatible = "syscon";
+
+	uart_rest: rest@0c {
+		compatible = "reset-basic";
+		#reset-cells = <1>;
+		reg = <0x0c>;
+	};
+}
+
+&uart {
+	resets = <&uart_rest 0x04>;
+}
-- 
2.11.0

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

* [PATCH 1/2] dt-bindings: reset: Add bindings for basic reset controller
@ 2017-05-26  3:32   ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-26  3:32 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Mark Rutland
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

This adds the bindings documentation for a basic single-register reset
controller.

The bindings describe a single 32-bit register that contains up to 32
reset lines, each deasserted by clearing the appropriate bit in the
register.

Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
---
 .../devicetree/bindings/reset/reset-basic.txt      | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt

diff --git a/Documentation/devicetree/bindings/reset/reset-basic.txt b/Documentation/devicetree/bindings/reset/reset-basic.txt
new file mode 100644
index 000000000000..7341e04e7904
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/reset-basic.txt
@@ -0,0 +1,31 @@
+Basic single-register reset controller
+======================================
+
+This describes a generic reset controller where the reset lines are controlled
+by single bits within a 32-bit memory location. The memory location is assumed
+to be part of a syscon regmap.
+
+Reset controller required properties:
+ - compatible: should be "reset-basic"
+ - #reset-cells: must be set to 1
+ - reg: reset register location within regmap
+
+Device node required properties:
+ - resets phandle
+ - bit number, counting from zero, for the desired reset line. Max is 31.
+
+Example:
+
+syscon {
+	compatible = "syscon";
+
+	uart_rest: rest@0c {
+		compatible = "reset-basic";
+		#reset-cells = <1>;
+		reg = <0x0c>;
+	};
+}
+
+&uart {
+	resets = <&uart_rest 0x04>;
+}
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-26  3:32   ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-26  3:32 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Mark Rutland
  Cc: devicetree, linux-kernel, Benjamin Herrenschmidt, Andrew Jeffery

This driver is a basic single-register reset controller driver that
supports clearing a single bit in a register.

Signed-off-by: Joel Stanley <joel@jms.id.au>
---
 drivers/reset/Kconfig       |   6 +++
 drivers/reset/Makefile      |   1 +
 drivers/reset/reset-basic.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 drivers/reset/reset-basic.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index d21c07ccc94e..980cda887dfe 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -28,6 +28,12 @@ config RESET_ATH79
 	  This enables the ATH79 reset controller driver that supports the
 	  AR71xx SoC reset controller.
 
+config RESET_BASIC
+	bool "Basic Reset Driver"
+	help
+	  This enables a basic single-register reset controller driver that
+	  supports clearing a single bit in a register.
+
 config RESET_BERLIN
 	bool "Berlin Reset Driver" if COMPILE_TEST
 	default ARCH_BERLIN
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 02a74db94339..e8e8869e098d 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
 obj-$(CONFIG_ARCH_TEGRA) += tegra/
 obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
 obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
+obj-$(CONFIG_RESET_BASIC) += reset-basic.o
 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
diff --git a/drivers/reset/reset-basic.c b/drivers/reset/reset-basic.c
new file mode 100644
index 000000000000..62a676de9f62
--- /dev/null
+++ b/drivers/reset/reset-basic.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017 IBM Corperation
+ *
+ * Joel Stanley <joel@jms.id.au>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/reset-controller.h>
+
+#define to_basic_reset_priv(p)		\
+	container_of((p), struct basic_reset_priv, rcdev)
+
+struct basic_reset_priv {
+	struct regmap *regmap;
+	struct reset_controller_dev rcdev;
+	u32 reg;
+};
+
+static int basic_reset_assert(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
+	u32 mask = BIT(id);
+
+	regmap_update_bits(priv->regmap, priv->reg, mask, mask);
+
+	return 0;
+}
+
+static int basic_reset_deassert(struct reset_controller_dev *rcdev,
+				 unsigned long id)
+{
+	struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
+	u32 mask = BIT(id);
+
+	regmap_update_bits(priv->regmap, priv->reg, mask, 0);
+
+	return 0;
+}
+
+static int basic_reset_status(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
+	u32 mask = BIT(id);
+	u32 val;
+
+	regmap_read(priv->regmap, priv->reg, &val);
+
+	return !!(val & mask);
+}
+
+static const struct reset_control_ops basic_reset_ops = {
+	.assert = basic_reset_assert,
+	.deassert = basic_reset_deassert,
+	.status = basic_reset_status,
+};
+
+static int basic_reset_probe(struct platform_device *pdev)
+{
+	struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
+	struct basic_reset_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->regmap = syscon_node_to_regmap(parent_np);
+	of_node_put(parent_np);
+	if (IS_ERR(priv->regmap))
+		return PTR_ERR(priv->regmap);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "reg", &priv->reg);
+	if (ret)
+		return ret;
+
+	priv->rcdev.owner = THIS_MODULE;
+	priv->rcdev.ops = &basic_reset_ops;
+	priv->rcdev.of_node = pdev->dev.of_node;
+	priv->rcdev.nr_resets = 32;
+
+	return reset_controller_register(&priv->rcdev);
+}
+
+static const struct of_device_id basic_reset_dt_match[] = {
+	{ .compatible = "reset-basic" },
+	{ },
+};
+
+static struct platform_driver basic_reset_driver = {
+	.probe	= basic_reset_probe,
+	.driver	= {
+		.name = "basic-reset",
+		.of_match_table = basic_reset_dt_match,
+	},
+};
+builtin_platform_driver(basic_reset_driver);
-- 
2.11.0

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

* [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-26  3:32   ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-26  3:32 UTC (permalink / raw)
  To: Philipp Zabel, Rob Herring, Mark Rutland
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

This driver is a basic single-register reset controller driver that
supports clearing a single bit in a register.

Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
---
 drivers/reset/Kconfig       |   6 +++
 drivers/reset/Makefile      |   1 +
 drivers/reset/reset-basic.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 drivers/reset/reset-basic.c

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index d21c07ccc94e..980cda887dfe 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -28,6 +28,12 @@ config RESET_ATH79
 	  This enables the ATH79 reset controller driver that supports the
 	  AR71xx SoC reset controller.
 
+config RESET_BASIC
+	bool "Basic Reset Driver"
+	help
+	  This enables a basic single-register reset controller driver that
+	  supports clearing a single bit in a register.
+
 config RESET_BERLIN
 	bool "Berlin Reset Driver" if COMPILE_TEST
 	default ARCH_BERLIN
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 02a74db94339..e8e8869e098d 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
 obj-$(CONFIG_ARCH_TEGRA) += tegra/
 obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
 obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
+obj-$(CONFIG_RESET_BASIC) += reset-basic.o
 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
diff --git a/drivers/reset/reset-basic.c b/drivers/reset/reset-basic.c
new file mode 100644
index 000000000000..62a676de9f62
--- /dev/null
+++ b/drivers/reset/reset-basic.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2017 IBM Corperation
+ *
+ * Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/reset-controller.h>
+
+#define to_basic_reset_priv(p)		\
+	container_of((p), struct basic_reset_priv, rcdev)
+
+struct basic_reset_priv {
+	struct regmap *regmap;
+	struct reset_controller_dev rcdev;
+	u32 reg;
+};
+
+static int basic_reset_assert(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
+	u32 mask = BIT(id);
+
+	regmap_update_bits(priv->regmap, priv->reg, mask, mask);
+
+	return 0;
+}
+
+static int basic_reset_deassert(struct reset_controller_dev *rcdev,
+				 unsigned long id)
+{
+	struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
+	u32 mask = BIT(id);
+
+	regmap_update_bits(priv->regmap, priv->reg, mask, 0);
+
+	return 0;
+}
+
+static int basic_reset_status(struct reset_controller_dev *rcdev,
+			       unsigned long id)
+{
+	struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
+	u32 mask = BIT(id);
+	u32 val;
+
+	regmap_read(priv->regmap, priv->reg, &val);
+
+	return !!(val & mask);
+}
+
+static const struct reset_control_ops basic_reset_ops = {
+	.assert = basic_reset_assert,
+	.deassert = basic_reset_deassert,
+	.status = basic_reset_status,
+};
+
+static int basic_reset_probe(struct platform_device *pdev)
+{
+	struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
+	struct basic_reset_priv *priv;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->regmap = syscon_node_to_regmap(parent_np);
+	of_node_put(parent_np);
+	if (IS_ERR(priv->regmap))
+		return PTR_ERR(priv->regmap);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "reg", &priv->reg);
+	if (ret)
+		return ret;
+
+	priv->rcdev.owner = THIS_MODULE;
+	priv->rcdev.ops = &basic_reset_ops;
+	priv->rcdev.of_node = pdev->dev.of_node;
+	priv->rcdev.nr_resets = 32;
+
+	return reset_controller_register(&priv->rcdev);
+}
+
+static const struct of_device_id basic_reset_dt_match[] = {
+	{ .compatible = "reset-basic" },
+	{ },
+};
+
+static struct platform_driver basic_reset_driver = {
+	.probe	= basic_reset_probe,
+	.driver	= {
+		.name = "basic-reset",
+		.of_match_table = basic_reset_dt_match,
+	},
+};
+builtin_platform_driver(basic_reset_driver);
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-27 15:11     ` Andy Shevchenko
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Shevchenko @ 2017-05-27 15:11 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Philipp Zabel, Rob Herring, Mark Rutland, devicetree,
	linux-kernel, Benjamin Herrenschmidt, Andrew Jeffery

On Fri, May 26, 2017 at 6:32 AM, Joel Stanley <joel@jms.id.au> wrote:
> This driver is a basic single-register reset controller driver that
> supports clearing a single bit in a register.
>

While this makes sense, I'm wondering if there can be generic
interface for this from which we can derive this one and GPIO-based
one.

> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
>  drivers/reset/Kconfig       |   6 +++
>  drivers/reset/Makefile      |   1 +
>  drivers/reset/reset-basic.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 drivers/reset/reset-basic.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index d21c07ccc94e..980cda887dfe 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -28,6 +28,12 @@ config RESET_ATH79
>           This enables the ATH79 reset controller driver that supports the
>           AR71xx SoC reset controller.
>
> +config RESET_BASIC
> +       bool "Basic Reset Driver"
> +       help
> +         This enables a basic single-register reset controller driver that
> +         supports clearing a single bit in a register.
> +
>  config RESET_BERLIN
>         bool "Berlin Reset Driver" if COMPILE_TEST
>         default ARCH_BERLIN
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 02a74db94339..e8e8869e098d 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
>  obj-$(CONFIG_ARCH_TEGRA) += tegra/
>  obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
>  obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
> +obj-$(CONFIG_RESET_BASIC) += reset-basic.o
>  obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
>  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
>  obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> diff --git a/drivers/reset/reset-basic.c b/drivers/reset/reset-basic.c
> new file mode 100644
> index 000000000000..62a676de9f62
> --- /dev/null
> +++ b/drivers/reset/reset-basic.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright 2017 IBM Corperation
> + *
> + * Joel Stanley <joel@jms.id.au>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/reset-controller.h>
> +
> +#define to_basic_reset_priv(p)         \
> +       container_of((p), struct basic_reset_priv, rcdev)
> +
> +struct basic_reset_priv {
> +       struct regmap *regmap;
> +       struct reset_controller_dev rcdev;
> +       u32 reg;
> +};
> +
> +static int basic_reset_assert(struct reset_controller_dev *rcdev,
> +                              unsigned long id)
> +{
> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
> +       u32 mask = BIT(id);
> +
> +       regmap_update_bits(priv->regmap, priv->reg, mask, mask);
> +
> +       return 0;
> +}
> +
> +static int basic_reset_deassert(struct reset_controller_dev *rcdev,
> +                                unsigned long id)
> +{
> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
> +       u32 mask = BIT(id);
> +
> +       regmap_update_bits(priv->regmap, priv->reg, mask, 0);
> +
> +       return 0;
> +}
> +
> +static int basic_reset_status(struct reset_controller_dev *rcdev,
> +                              unsigned long id)
> +{
> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
> +       u32 mask = BIT(id);
> +       u32 val;
> +
> +       regmap_read(priv->regmap, priv->reg, &val);
> +
> +       return !!(val & mask);
> +}
> +
> +static const struct reset_control_ops basic_reset_ops = {
> +       .assert = basic_reset_assert,
> +       .deassert = basic_reset_deassert,
> +       .status = basic_reset_status,
> +};
> +
> +static int basic_reset_probe(struct platform_device *pdev)
> +{
> +       struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
> +       struct basic_reset_priv *priv;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->regmap = syscon_node_to_regmap(parent_np);
> +       of_node_put(parent_np);
> +       if (IS_ERR(priv->regmap))
> +               return PTR_ERR(priv->regmap);
> +
> +       ret = of_property_read_u32(pdev->dev.of_node, "reg", &priv->reg);
> +       if (ret)
> +               return ret;
> +
> +       priv->rcdev.owner = THIS_MODULE;
> +       priv->rcdev.ops = &basic_reset_ops;
> +       priv->rcdev.of_node = pdev->dev.of_node;
> +       priv->rcdev.nr_resets = 32;
> +
> +       return reset_controller_register(&priv->rcdev);
> +}
> +
> +static const struct of_device_id basic_reset_dt_match[] = {
> +       { .compatible = "reset-basic" },
> +       { },
> +};
> +
> +static struct platform_driver basic_reset_driver = {
> +       .probe  = basic_reset_probe,
> +       .driver = {
> +               .name = "basic-reset",
> +               .of_match_table = basic_reset_dt_match,
> +       },
> +};
> +builtin_platform_driver(basic_reset_driver);
> --
> 2.11.0
>



-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-27 15:11     ` Andy Shevchenko
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Shevchenko @ 2017-05-27 15:11 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Philipp Zabel, Rob Herring, Mark Rutland, devicetree,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

On Fri, May 26, 2017 at 6:32 AM, Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org> wrote:
> This driver is a basic single-register reset controller driver that
> supports clearing a single bit in a register.
>

While this makes sense, I'm wondering if there can be generic
interface for this from which we can derive this one and GPIO-based
one.

> Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
> ---
>  drivers/reset/Kconfig       |   6 +++
>  drivers/reset/Makefile      |   1 +
>  drivers/reset/reset-basic.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 drivers/reset/reset-basic.c
>
> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> index d21c07ccc94e..980cda887dfe 100644
> --- a/drivers/reset/Kconfig
> +++ b/drivers/reset/Kconfig
> @@ -28,6 +28,12 @@ config RESET_ATH79
>           This enables the ATH79 reset controller driver that supports the
>           AR71xx SoC reset controller.
>
> +config RESET_BASIC
> +       bool "Basic Reset Driver"
> +       help
> +         This enables a basic single-register reset controller driver that
> +         supports clearing a single bit in a register.
> +
>  config RESET_BERLIN
>         bool "Berlin Reset Driver" if COMPILE_TEST
>         default ARCH_BERLIN
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index 02a74db94339..e8e8869e098d 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
>  obj-$(CONFIG_ARCH_TEGRA) += tegra/
>  obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
>  obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
> +obj-$(CONFIG_RESET_BASIC) += reset-basic.o
>  obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
>  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
>  obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> diff --git a/drivers/reset/reset-basic.c b/drivers/reset/reset-basic.c
> new file mode 100644
> index 000000000000..62a676de9f62
> --- /dev/null
> +++ b/drivers/reset/reset-basic.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright 2017 IBM Corperation
> + *
> + * Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/reset-controller.h>
> +
> +#define to_basic_reset_priv(p)         \
> +       container_of((p), struct basic_reset_priv, rcdev)
> +
> +struct basic_reset_priv {
> +       struct regmap *regmap;
> +       struct reset_controller_dev rcdev;
> +       u32 reg;
> +};
> +
> +static int basic_reset_assert(struct reset_controller_dev *rcdev,
> +                              unsigned long id)
> +{
> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
> +       u32 mask = BIT(id);
> +
> +       regmap_update_bits(priv->regmap, priv->reg, mask, mask);
> +
> +       return 0;
> +}
> +
> +static int basic_reset_deassert(struct reset_controller_dev *rcdev,
> +                                unsigned long id)
> +{
> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
> +       u32 mask = BIT(id);
> +
> +       regmap_update_bits(priv->regmap, priv->reg, mask, 0);
> +
> +       return 0;
> +}
> +
> +static int basic_reset_status(struct reset_controller_dev *rcdev,
> +                              unsigned long id)
> +{
> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
> +       u32 mask = BIT(id);
> +       u32 val;
> +
> +       regmap_read(priv->regmap, priv->reg, &val);
> +
> +       return !!(val & mask);
> +}
> +
> +static const struct reset_control_ops basic_reset_ops = {
> +       .assert = basic_reset_assert,
> +       .deassert = basic_reset_deassert,
> +       .status = basic_reset_status,
> +};
> +
> +static int basic_reset_probe(struct platform_device *pdev)
> +{
> +       struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
> +       struct basic_reset_priv *priv;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->regmap = syscon_node_to_regmap(parent_np);
> +       of_node_put(parent_np);
> +       if (IS_ERR(priv->regmap))
> +               return PTR_ERR(priv->regmap);
> +
> +       ret = of_property_read_u32(pdev->dev.of_node, "reg", &priv->reg);
> +       if (ret)
> +               return ret;
> +
> +       priv->rcdev.owner = THIS_MODULE;
> +       priv->rcdev.ops = &basic_reset_ops;
> +       priv->rcdev.of_node = pdev->dev.of_node;
> +       priv->rcdev.nr_resets = 32;
> +
> +       return reset_controller_register(&priv->rcdev);
> +}
> +
> +static const struct of_device_id basic_reset_dt_match[] = {
> +       { .compatible = "reset-basic" },
> +       { },
> +};
> +
> +static struct platform_driver basic_reset_driver = {
> +       .probe  = basic_reset_probe,
> +       .driver = {
> +               .name = "basic-reset",
> +               .of_match_table = basic_reset_dt_match,
> +       },
> +};
> +builtin_platform_driver(basic_reset_driver);
> --
> 2.11.0
>



-- 
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/2] dt-bindings: reset: Add bindings for basic reset controller
@ 2017-05-29  9:09     ` Philipp Zabel
  0 siblings, 0 replies; 16+ messages in thread
From: Philipp Zabel @ 2017-05-29  9:09 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Rob Herring, Mark Rutland, devicetree, linux-kernel,
	Benjamin Herrenschmidt, Andrew Jeffery

Hi Joel,

On Fri, 2017-05-26 at 13:32 +1000, Joel Stanley wrote:
> This adds the bindings documentation for a basic single-register reset
> controller.
> 
> The bindings describe a single 32-bit register that contains up to 32
> reset lines, each deasserted by clearing the appropriate bit in the
> register.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
>  .../devicetree/bindings/reset/reset-basic.txt      | 31 ++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt
> 
> diff --git a/Documentation/devicetree/bindings/reset/reset-basic.txt b/Documentation/devicetree/bindings/reset/reset-basic.txt
> new file mode 100644
> index 000000000000..7341e04e7904
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/reset-basic.txt
> @@ -0,0 +1,31 @@
> +Basic single-register reset controller
> +======================================
> +
> +This describes a generic reset controller where the reset lines are controlled
> +by single bits within a 32-bit memory location. The memory location is assumed
> +to be part of a syscon regmap.

There are a few more assumptions. First, that the reset line is asserted
by setting the corresponding bits, and that it is deasserted by clearing
them. Further, that the bits are not auto-clearing. And then, that the
same bit can be read back to provide the current reset line status.

> +Reset controller required properties:
> + - compatible: should be "reset-basic"
> + - #reset-cells: must be set to 1
> + - reg: reset register location within regmap
> +
> +Device node required properties:
> + - resets phandle
> + - bit number, counting from zero, for the desired reset line. Max is 31.
> +
> +Example:
> +
> +syscon {
> +	compatible = "syscon";
> +
> +	uart_rest: rest@0c {

The device node name should be "reset-controller", and leading zeroes
should be dropped from the address part:

	uart_rest: reset-controller@c {

> +		compatible = "reset-basic";

Maybe this is not necessary for the example, but the compatible should
contain a vendor/hardware specific string first.

> +		#reset-cells = <1>;
> +		reg = <0x0c>;
> +	};
> +}
> +
> +&uart {
> +	resets = <&uart_rest 0x04>;

I'd use decimal here.

regards
Philipp

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

* Re: [PATCH 1/2] dt-bindings: reset: Add bindings for basic reset controller
@ 2017-05-29  9:09     ` Philipp Zabel
  0 siblings, 0 replies; 16+ messages in thread
From: Philipp Zabel @ 2017-05-29  9:09 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Rob Herring, Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

Hi Joel,

On Fri, 2017-05-26 at 13:32 +1000, Joel Stanley wrote:
> This adds the bindings documentation for a basic single-register reset
> controller.
> 
> The bindings describe a single 32-bit register that contains up to 32
> reset lines, each deasserted by clearing the appropriate bit in the
> register.
>
> Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
> ---
>  .../devicetree/bindings/reset/reset-basic.txt      | 31 ++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt
> 
> diff --git a/Documentation/devicetree/bindings/reset/reset-basic.txt b/Documentation/devicetree/bindings/reset/reset-basic.txt
> new file mode 100644
> index 000000000000..7341e04e7904
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/reset-basic.txt
> @@ -0,0 +1,31 @@
> +Basic single-register reset controller
> +======================================
> +
> +This describes a generic reset controller where the reset lines are controlled
> +by single bits within a 32-bit memory location. The memory location is assumed
> +to be part of a syscon regmap.

There are a few more assumptions. First, that the reset line is asserted
by setting the corresponding bits, and that it is deasserted by clearing
them. Further, that the bits are not auto-clearing. And then, that the
same bit can be read back to provide the current reset line status.

> +Reset controller required properties:
> + - compatible: should be "reset-basic"
> + - #reset-cells: must be set to 1
> + - reg: reset register location within regmap
> +
> +Device node required properties:
> + - resets phandle
> + - bit number, counting from zero, for the desired reset line. Max is 31.
> +
> +Example:
> +
> +syscon {
> +	compatible = "syscon";
> +
> +	uart_rest: rest@0c {

The device node name should be "reset-controller", and leading zeroes
should be dropped from the address part:

	uart_rest: reset-controller@c {

> +		compatible = "reset-basic";

Maybe this is not necessary for the example, but the compatible should
contain a vendor/hardware specific string first.

> +		#reset-cells = <1>;
> +		reg = <0x0c>;
> +	};
> +}
> +
> +&uart {
> +	resets = <&uart_rest 0x04>;

I'd use decimal here.

regards
Philipp

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/2] dt-bindings: reset: Add bindings for basic reset controller
@ 2017-05-29 10:16       ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-29 10:16 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Mark Rutland, devicetree, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Andrew Jeffery

On Mon, May 29, 2017 at 6:39 PM, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> Hi Joel,
>
> On Fri, 2017-05-26 at 13:32 +1000, Joel Stanley wrote:
>> This adds the bindings documentation for a basic single-register reset
>> controller.
>>
>> The bindings describe a single 32-bit register that contains up to 32
>> reset lines, each deasserted by clearing the appropriate bit in the
>> register.
>>
>> Signed-off-by: Joel Stanley <joel@jms.id.au>
>> ---
>>  .../devicetree/bindings/reset/reset-basic.txt      | 31 ++++++++++++++++++++++
>>  1 file changed, 31 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt
>>
>> diff --git a/Documentation/devicetree/bindings/reset/reset-basic.txt b/Documentation/devicetree/bindings/reset/reset-basic.txt
>> new file mode 100644
>> index 000000000000..7341e04e7904
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/reset/reset-basic.txt
>> @@ -0,0 +1,31 @@
>> +Basic single-register reset controller
>> +======================================
>> +
>> +This describes a generic reset controller where the reset lines are controlled
>> +by single bits within a 32-bit memory location. The memory location is assumed
>> +to be part of a syscon regmap.
>
> There are a few more assumptions. First, that the reset line is asserted
> by setting the corresponding bits, and that it is deasserted by clearing
> them. Further, that the bits are not auto-clearing. And then, that the
> same bit can be read back to provide the current reset line status.

I'll add a property to indicate set-to-enable in v2. How about:

 - reset-set-assert: Specifies that the bit should be set to assert
the reset. The default is to set the bit to deassert the reset.

I'm sure we can find a better way to write that.

I'll add a note that the bits are not auto-clearing, and therefore
they can be read back. This is in the spirit of trying to describe a
basic reset controller.

>
>> +Reset controller required properties:
>> + - compatible: should be "reset-basic"
>> + - #reset-cells: must be set to 1
>> + - reg: reset register location within regmap
>> +
>> +Device node required properties:
>> + - resets phandle
>> + - bit number, counting from zero, for the desired reset line. Max is 31.
>> +
>> +Example:
>> +
>> +syscon {
>> +     compatible = "syscon";
>> +
>> +     uart_rest: rest@0c {
>
> The device node name should be "reset-controller", and leading zeroes
> should be dropped from the address part:
>
>         uart_rest: reset-controller@c {

Ok.

>
>> +             compatible = "reset-basic";
>
> Maybe this is not necessary for the example, but the compatible should
> contain a vendor/hardware specific string first.

You're suggesting I add a hardware-specific string in addition to the
generic reset-basic? eg:

            compatible = "aspeed,uart-rest", "reset-basic";

I don't think that helps anyone. We don't do that for eg.
timeriomem-rng or gpio-fan. Or perhaps I've misunderstood your
suggestion?

>
>> +             #reset-cells = <1>;
>> +             reg = <0x0c>;
>> +     };
>> +}
>> +
>> +&uart {
>> +     resets = <&uart_rest 0x04>;
>
> I'd use decimal here.

Ok.

Cheers,

Joel

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

* Re: [PATCH 1/2] dt-bindings: reset: Add bindings for basic reset controller
@ 2017-05-29 10:16       ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-29 10:16 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: Rob Herring, Mark Rutland, devicetree, Linux Kernel Mailing List,
	Benjamin Herrenschmidt, Andrew Jeffery

On Mon, May 29, 2017 at 6:39 PM, Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org> wrote:
> Hi Joel,
>
> On Fri, 2017-05-26 at 13:32 +1000, Joel Stanley wrote:
>> This adds the bindings documentation for a basic single-register reset
>> controller.
>>
>> The bindings describe a single 32-bit register that contains up to 32
>> reset lines, each deasserted by clearing the appropriate bit in the
>> register.
>>
>> Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
>> ---
>>  .../devicetree/bindings/reset/reset-basic.txt      | 31 ++++++++++++++++++++++
>>  1 file changed, 31 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/reset/reset-basic.txt
>>
>> diff --git a/Documentation/devicetree/bindings/reset/reset-basic.txt b/Documentation/devicetree/bindings/reset/reset-basic.txt
>> new file mode 100644
>> index 000000000000..7341e04e7904
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/reset/reset-basic.txt
>> @@ -0,0 +1,31 @@
>> +Basic single-register reset controller
>> +======================================
>> +
>> +This describes a generic reset controller where the reset lines are controlled
>> +by single bits within a 32-bit memory location. The memory location is assumed
>> +to be part of a syscon regmap.
>
> There are a few more assumptions. First, that the reset line is asserted
> by setting the corresponding bits, and that it is deasserted by clearing
> them. Further, that the bits are not auto-clearing. And then, that the
> same bit can be read back to provide the current reset line status.

I'll add a property to indicate set-to-enable in v2. How about:

 - reset-set-assert: Specifies that the bit should be set to assert
the reset. The default is to set the bit to deassert the reset.

I'm sure we can find a better way to write that.

I'll add a note that the bits are not auto-clearing, and therefore
they can be read back. This is in the spirit of trying to describe a
basic reset controller.

>
>> +Reset controller required properties:
>> + - compatible: should be "reset-basic"
>> + - #reset-cells: must be set to 1
>> + - reg: reset register location within regmap
>> +
>> +Device node required properties:
>> + - resets phandle
>> + - bit number, counting from zero, for the desired reset line. Max is 31.
>> +
>> +Example:
>> +
>> +syscon {
>> +     compatible = "syscon";
>> +
>> +     uart_rest: rest@0c {
>
> The device node name should be "reset-controller", and leading zeroes
> should be dropped from the address part:
>
>         uart_rest: reset-controller@c {

Ok.

>
>> +             compatible = "reset-basic";
>
> Maybe this is not necessary for the example, but the compatible should
> contain a vendor/hardware specific string first.

You're suggesting I add a hardware-specific string in addition to the
generic reset-basic? eg:

            compatible = "aspeed,uart-rest", "reset-basic";

I don't think that helps anyone. We don't do that for eg.
timeriomem-rng or gpio-fan. Or perhaps I've misunderstood your
suggestion?

>
>> +             #reset-cells = <1>;
>> +             reg = <0x0c>;
>> +     };
>> +}
>> +
>> +&uart {
>> +     resets = <&uart_rest 0x04>;
>
> I'd use decimal here.

Ok.

Cheers,

Joel
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-29 10:24       ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-29 10:24 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Philipp Zabel, Rob Herring, Mark Rutland, devicetree,
	linux-kernel, Benjamin Herrenschmidt, Andrew Jeffery

Hi Andy,

On Sun, May 28, 2017 at 12:41 AM, Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
> On Fri, May 26, 2017 at 6:32 AM, Joel Stanley <joel@jms.id.au> wrote:
>> This driver is a basic single-register reset controller driver that
>> supports clearing a single bit in a register.
>>
>
> While this makes sense, I'm wondering if there can be generic
> interface for this from which we can derive this one and GPIO-based
> one.

Do we have a GPIO based one already? I couldn't find it.

Having a think, it would be a very similar looking driver, but with
little shared code. The context struct would contain a gpio pointer
instead of regmap, probe would request a GPIO instead of a regmap and
the assert/deassert/status callbacks would be gpiod_ calls.

Given this is four of the four functions in this driver, do you think would be
better off with two small drivers?

Cheers,

Joel

>
>> Signed-off-by: Joel Stanley <joel@jms.id.au>
>> ---
>>  drivers/reset/Kconfig       |   6 +++
>>  drivers/reset/Makefile      |   1 +
>>  drivers/reset/reset-basic.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 drivers/reset/reset-basic.c
>>
>> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
>> index d21c07ccc94e..980cda887dfe 100644
>> --- a/drivers/reset/Kconfig
>> +++ b/drivers/reset/Kconfig
>> @@ -28,6 +28,12 @@ config RESET_ATH79
>>           This enables the ATH79 reset controller driver that supports the
>>           AR71xx SoC reset controller.
>>
>> +config RESET_BASIC
>> +       bool "Basic Reset Driver"
>> +       help
>> +         This enables a basic single-register reset controller driver that
>> +         supports clearing a single bit in a register.
>> +
>>  config RESET_BERLIN
>>         bool "Berlin Reset Driver" if COMPILE_TEST
>>         default ARCH_BERLIN
>> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
>> index 02a74db94339..e8e8869e098d 100644
>> --- a/drivers/reset/Makefile
>> +++ b/drivers/reset/Makefile
>> @@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
>>  obj-$(CONFIG_ARCH_TEGRA) += tegra/
>>  obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
>>  obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
>> +obj-$(CONFIG_RESET_BASIC) += reset-basic.o
>>  obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
>>  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
>>  obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
>> diff --git a/drivers/reset/reset-basic.c b/drivers/reset/reset-basic.c
>> new file mode 100644
>> index 000000000000..62a676de9f62
>> --- /dev/null
>> +++ b/drivers/reset/reset-basic.c
>> @@ -0,0 +1,109 @@
>> +/*
>> + * Copyright 2017 IBM Corperation
>> + *
>> + * Joel Stanley <joel@jms.id.au>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version
>> + * 2 of the License, or (at your option) any later version.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/init.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/reset-controller.h>
>> +
>> +#define to_basic_reset_priv(p)         \
>> +       container_of((p), struct basic_reset_priv, rcdev)
>> +
>> +struct basic_reset_priv {
>> +       struct regmap *regmap;
>> +       struct reset_controller_dev rcdev;
>> +       u32 reg;
>> +};
>> +
>> +static int basic_reset_assert(struct reset_controller_dev *rcdev,
>> +                              unsigned long id)
>> +{
>> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
>> +       u32 mask = BIT(id);
>> +
>> +       regmap_update_bits(priv->regmap, priv->reg, mask, mask);
>> +
>> +       return 0;
>> +}
>> +
>> +static int basic_reset_deassert(struct reset_controller_dev *rcdev,
>> +                                unsigned long id)
>> +{
>> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
>> +       u32 mask = BIT(id);
>> +
>> +       regmap_update_bits(priv->regmap, priv->reg, mask, 0);
>> +
>> +       return 0;
>> +}
>> +
>> +static int basic_reset_status(struct reset_controller_dev *rcdev,
>> +                              unsigned long id)
>> +{
>> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
>> +       u32 mask = BIT(id);
>> +       u32 val;
>> +
>> +       regmap_read(priv->regmap, priv->reg, &val);
>> +
>> +       return !!(val & mask);
>> +}
>> +
>> +static const struct reset_control_ops basic_reset_ops = {
>> +       .assert = basic_reset_assert,
>> +       .deassert = basic_reset_deassert,
>> +       .status = basic_reset_status,
>> +};
>> +
>> +static int basic_reset_probe(struct platform_device *pdev)
>> +{
>> +       struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
>> +       struct basic_reset_priv *priv;
>> +       int ret;
>> +
>> +       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> +       if (!priv)
>> +               return -ENOMEM;
>> +
>> +       priv->regmap = syscon_node_to_regmap(parent_np);
>> +       of_node_put(parent_np);
>> +       if (IS_ERR(priv->regmap))
>> +               return PTR_ERR(priv->regmap);
>> +
>> +       ret = of_property_read_u32(pdev->dev.of_node, "reg", &priv->reg);
>> +       if (ret)
>> +               return ret;
>> +
>> +       priv->rcdev.owner = THIS_MODULE;
>> +       priv->rcdev.ops = &basic_reset_ops;
>> +       priv->rcdev.of_node = pdev->dev.of_node;
>> +       priv->rcdev.nr_resets = 32;
>> +
>> +       return reset_controller_register(&priv->rcdev);
>> +}
>> +
>> +static const struct of_device_id basic_reset_dt_match[] = {
>> +       { .compatible = "reset-basic" },
>> +       { },
>> +};
>> +
>> +static struct platform_driver basic_reset_driver = {
>> +       .probe  = basic_reset_probe,
>> +       .driver = {
>> +               .name = "basic-reset",
>> +               .of_match_table = basic_reset_dt_match,
>> +       },
>> +};
>> +builtin_platform_driver(basic_reset_driver);
>> --
>> 2.11.0
>>
>
>
>
> --
> With Best Regards,
> Andy Shevchenko

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

* Re: [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-29 10:24       ` Joel Stanley
  0 siblings, 0 replies; 16+ messages in thread
From: Joel Stanley @ 2017-05-29 10:24 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Philipp Zabel, Rob Herring, Mark Rutland, devicetree,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

Hi Andy,

On Sun, May 28, 2017 at 12:41 AM, Andy Shevchenko
<andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Fri, May 26, 2017 at 6:32 AM, Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org> wrote:
>> This driver is a basic single-register reset controller driver that
>> supports clearing a single bit in a register.
>>
>
> While this makes sense, I'm wondering if there can be generic
> interface for this from which we can derive this one and GPIO-based
> one.

Do we have a GPIO based one already? I couldn't find it.

Having a think, it would be a very similar looking driver, but with
little shared code. The context struct would contain a gpio pointer
instead of regmap, probe would request a GPIO instead of a regmap and
the assert/deassert/status callbacks would be gpiod_ calls.

Given this is four of the four functions in this driver, do you think would be
better off with two small drivers?

Cheers,

Joel

>
>> Signed-off-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
>> ---
>>  drivers/reset/Kconfig       |   6 +++
>>  drivers/reset/Makefile      |   1 +
>>  drivers/reset/reset-basic.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 drivers/reset/reset-basic.c
>>
>> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
>> index d21c07ccc94e..980cda887dfe 100644
>> --- a/drivers/reset/Kconfig
>> +++ b/drivers/reset/Kconfig
>> @@ -28,6 +28,12 @@ config RESET_ATH79
>>           This enables the ATH79 reset controller driver that supports the
>>           AR71xx SoC reset controller.
>>
>> +config RESET_BASIC
>> +       bool "Basic Reset Driver"
>> +       help
>> +         This enables a basic single-register reset controller driver that
>> +         supports clearing a single bit in a register.
>> +
>>  config RESET_BERLIN
>>         bool "Berlin Reset Driver" if COMPILE_TEST
>>         default ARCH_BERLIN
>> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
>> index 02a74db94339..e8e8869e098d 100644
>> --- a/drivers/reset/Makefile
>> +++ b/drivers/reset/Makefile
>> @@ -4,6 +4,7 @@ obj-$(CONFIG_ARCH_STI) += sti/
>>  obj-$(CONFIG_ARCH_TEGRA) += tegra/
>>  obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
>>  obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
>> +obj-$(CONFIG_RESET_BASIC) += reset-basic.o
>>  obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
>>  obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
>>  obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
>> diff --git a/drivers/reset/reset-basic.c b/drivers/reset/reset-basic.c
>> new file mode 100644
>> index 000000000000..62a676de9f62
>> --- /dev/null
>> +++ b/drivers/reset/reset-basic.c
>> @@ -0,0 +1,109 @@
>> +/*
>> + * Copyright 2017 IBM Corperation
>> + *
>> + * Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version
>> + * 2 of the License, or (at your option) any later version.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/init.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/reset-controller.h>
>> +
>> +#define to_basic_reset_priv(p)         \
>> +       container_of((p), struct basic_reset_priv, rcdev)
>> +
>> +struct basic_reset_priv {
>> +       struct regmap *regmap;
>> +       struct reset_controller_dev rcdev;
>> +       u32 reg;
>> +};
>> +
>> +static int basic_reset_assert(struct reset_controller_dev *rcdev,
>> +                              unsigned long id)
>> +{
>> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
>> +       u32 mask = BIT(id);
>> +
>> +       regmap_update_bits(priv->regmap, priv->reg, mask, mask);
>> +
>> +       return 0;
>> +}
>> +
>> +static int basic_reset_deassert(struct reset_controller_dev *rcdev,
>> +                                unsigned long id)
>> +{
>> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
>> +       u32 mask = BIT(id);
>> +
>> +       regmap_update_bits(priv->regmap, priv->reg, mask, 0);
>> +
>> +       return 0;
>> +}
>> +
>> +static int basic_reset_status(struct reset_controller_dev *rcdev,
>> +                              unsigned long id)
>> +{
>> +       struct basic_reset_priv *priv = to_basic_reset_priv(rcdev);
>> +       u32 mask = BIT(id);
>> +       u32 val;
>> +
>> +       regmap_read(priv->regmap, priv->reg, &val);
>> +
>> +       return !!(val & mask);
>> +}
>> +
>> +static const struct reset_control_ops basic_reset_ops = {
>> +       .assert = basic_reset_assert,
>> +       .deassert = basic_reset_deassert,
>> +       .status = basic_reset_status,
>> +};
>> +
>> +static int basic_reset_probe(struct platform_device *pdev)
>> +{
>> +       struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
>> +       struct basic_reset_priv *priv;
>> +       int ret;
>> +
>> +       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>> +       if (!priv)
>> +               return -ENOMEM;
>> +
>> +       priv->regmap = syscon_node_to_regmap(parent_np);
>> +       of_node_put(parent_np);
>> +       if (IS_ERR(priv->regmap))
>> +               return PTR_ERR(priv->regmap);
>> +
>> +       ret = of_property_read_u32(pdev->dev.of_node, "reg", &priv->reg);
>> +       if (ret)
>> +               return ret;
>> +
>> +       priv->rcdev.owner = THIS_MODULE;
>> +       priv->rcdev.ops = &basic_reset_ops;
>> +       priv->rcdev.of_node = pdev->dev.of_node;
>> +       priv->rcdev.nr_resets = 32;
>> +
>> +       return reset_controller_register(&priv->rcdev);
>> +}
>> +
>> +static const struct of_device_id basic_reset_dt_match[] = {
>> +       { .compatible = "reset-basic" },
>> +       { },
>> +};
>> +
>> +static struct platform_driver basic_reset_driver = {
>> +       .probe  = basic_reset_probe,
>> +       .driver = {
>> +               .name = "basic-reset",
>> +               .of_match_table = basic_reset_dt_match,
>> +       },
>> +};
>> +builtin_platform_driver(basic_reset_driver);
>> --
>> 2.11.0
>>
>
>
>
> --
> With Best Regards,
> Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-29 15:41         ` Andy Shevchenko
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Shevchenko @ 2017-05-29 15:41 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Philipp Zabel, Rob Herring, Mark Rutland, devicetree,
	linux-kernel, Benjamin Herrenschmidt, Andrew Jeffery

On Mon, May 29, 2017 at 1:24 PM, Joel Stanley <joel@jms.id.au> wrote:
> On Sun, May 28, 2017 at 12:41 AM, Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
>> On Fri, May 26, 2017 at 6:32 AM, Joel Stanley <joel@jms.id.au> wrote:
>>> This driver is a basic single-register reset controller driver that
>>> supports clearing a single bit in a register.
>>>
>>
>> While this makes sense, I'm wondering if there can be generic
>> interface for this from which we can derive this one and GPIO-based
>> one.
>
> Do we have a GPIO based one already? I couldn't find it.

No, we haven't.

> Having a think, it would be a very similar looking driver, but with
> little shared code. The context struct would contain a gpio pointer
> instead of regmap, probe would request a GPIO instead of a regmap and
> the assert/deassert/status callbacks would be gpiod_ calls.
>
> Given this is four of the four functions in this driver, do you think would be
> better off with two small drivers?

Fair enough.
Sounds like independent drivers for now is a good approach, though
it's up to maintainer.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 2/2] reset: Add basic single-register reset driver
@ 2017-05-29 15:41         ` Andy Shevchenko
  0 siblings, 0 replies; 16+ messages in thread
From: Andy Shevchenko @ 2017-05-29 15:41 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Philipp Zabel, Rob Herring, Mark Rutland, devicetree,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Benjamin Herrenschmidt,
	Andrew Jeffery

On Mon, May 29, 2017 at 1:24 PM, Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org> wrote:
> On Sun, May 28, 2017 at 12:41 AM, Andy Shevchenko
> <andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> On Fri, May 26, 2017 at 6:32 AM, Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org> wrote:
>>> This driver is a basic single-register reset controller driver that
>>> supports clearing a single bit in a register.
>>>
>>
>> While this makes sense, I'm wondering if there can be generic
>> interface for this from which we can derive this one and GPIO-based
>> one.
>
> Do we have a GPIO based one already? I couldn't find it.

No, we haven't.

> Having a think, it would be a very similar looking driver, but with
> little shared code. The context struct would contain a gpio pointer
> instead of regmap, probe would request a GPIO instead of a regmap and
> the assert/deassert/status callbacks would be gpiod_ calls.
>
> Given this is four of the four functions in this driver, do you think would be
> better off with two small drivers?

Fair enough.
Sounds like independent drivers for now is a good approach, though
it's up to maintainer.

-- 
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2017-05-29 15:41 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-26  3:32 [PATCH 0/2] reset: Basic reset controller Joel Stanley
2017-05-26  3:32 ` Joel Stanley
2017-05-26  3:32 ` [PATCH 1/2] dt-bindings: reset: Add bindings for basic " Joel Stanley
2017-05-26  3:32   ` Joel Stanley
2017-05-29  9:09   ` Philipp Zabel
2017-05-29  9:09     ` Philipp Zabel
2017-05-29 10:16     ` Joel Stanley
2017-05-29 10:16       ` Joel Stanley
2017-05-26  3:32 ` [PATCH 2/2] reset: Add basic single-register reset driver Joel Stanley
2017-05-26  3:32   ` Joel Stanley
2017-05-27 15:11   ` Andy Shevchenko
2017-05-27 15:11     ` Andy Shevchenko
2017-05-29 10:24     ` Joel Stanley
2017-05-29 10:24       ` Joel Stanley
2017-05-29 15:41       ` Andy Shevchenko
2017-05-29 15:41         ` Andy Shevchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.