Skip to contentSkip to conversation

ARM: meson: Add reset controller

PATCH Superseded Carlo Caione 2 participants 7 messages Oct 14, 2014 – Oct 15, 2014

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover ARM: meson: Add reset controller

Apparently several IPs found in the MesonX SoCs can be reset by programming a specific bit in a register in the so called AO (Always-On) domain. From the documentation released by Amlogic under NDA it is not clear which devices can be reset acting on this register. So far from the sources release by Amlogic it seems that at least two IPs use this register for reset: RTC and UART. Since I need it to reset the RTC, I wrote this small driver.

v2:
* removed useless comment
* added platform_get_drvdata
* removed owner field

Carlo Caione (3):
ARM: meson: reset: Add reset controller for MesonX SoCs
ARM: meson: DTSI: Enable reset controller
ARM: meson: docs: Add docs for MesonX reset controller

 .../bindings/reset/amlogic,meson6-rst-mgr-ao.txt   |  14 ++
 arch/arm/boot/dts/meson.dtsi                       |   6 +
 drivers/reset/Makefile                             |   1 +
 drivers/reset/reset-meson.c                        | 142 +++++++++++++++++++++
 4 files changed, 163 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/amlogic,meson6-rst-mgr-ao.txt
 create mode 100644 drivers/reset/reset-meson.c
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/3 ARM: meson: reset: Add reset controller for MesonX SoCs

This patch adds support for the reset controller found on the Amlogic MesonX SoCs. For several devices in the AO (Always-On) power domain, it is possible to reset them by programming a specific bit in a register.

---
 drivers/reset/Makefile      |   1 +
 drivers/reset/reset-meson.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+)
 create mode 100644 drivers/reset/reset-meson.c
drivers/reset/Makefile +1 -0
index 60fed3d..74f2372 100644
@@ -1,4 +1,5 @@
 obj-$(CONFIG_RESET_CONTROLLER) += core.o
 obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_ARCH_MESON) += reset-meson.o
 obj-$(CONFIG_ARCH_STI) += sti/
drivers/reset/reset-meson.c new file +142 -0

142 lines not on this page · raw message

Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 1/3 ARM: meson: reset: Add reset controller for MesonX SoCs

Hi Carlo,

Quoted 27 lines · Carlo Caione

This patch adds support for the reset controller found on the Amlogic MesonX SoCs. For several devices in the AO (Always-On) power domain, it is possible to reset them by programming a specific bit in a register.

---
 drivers/reset/Makefile      |   1 +
 drivers/reset/reset-meson.c | 142 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+)
 create mode 100644 drivers/reset/reset-meson.c
drivers/reset/Makefile +1 -0
index 60fed3d..74f2372 100644
@@ -1,4 +1,5 @@
 obj-$(CONFIG_RESET_CONTROLLER) += core.o
 obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
+obj-$(CONFIG_ARCH_MESON) += reset-meson.o
 obj-$(CONFIG_ARCH_STI) += sti/
drivers/reset/reset-meson.c new file +0 -0
new file mode 100644
index 0000000..59b58e4

drivers/reset/reset-meson.c line 5

Quoted 5 lines
drivers/reset/reset-meson.c new file +5 -0
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2014 Carlo Caione <[email protected]>
+ *
+ * based on
+ * Steffen Trumtrar Reset Controller driver

That doesn't sound right. Do you mean socfpga-reset?

drivers/reset/reset-meson.c line 9

Quoted 3 lines
drivers/reset/reset-meson.c new file +3 -0
+ * Copyright 2014 Steffen Trumtrar
+ *
+ * Steffen Trumtrar <[email protected]>

Could be combined into a single line.

Quoted 6 lines
drivers/reset/reset-meson.c new file +6 -0
+ * 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.
+ */
+

drivers/reset/reset-meson.c line 26

Quoted 10 lines
drivers/reset/reset-meson.c new file +10 -0
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define MESON_RST_OFFSET	0x00

If there is only one register, I see no need for this.

Quoted 72 lines
drivers/reset/reset-meson.c new file +72 -0
+struct meson_reset_data {
+	spinlock_t			lock;
+	void __iomem			*membase;
+	struct reset_controller_dev	rcdev;
+};
+
+static int meson_reset_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct meson_reset_data *data = container_of(rcdev,
+						     struct meson_reset_data,
+						     rcdev);
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	reg = readl(data->membase + MESON_RST_OFFSET);
+	writel(reg | BIT(id), data->membase + MESON_RST_OFFSET);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	return 0;
+}
+
+static int meson_reset_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	struct meson_reset_data *data = container_of(rcdev,
+						     struct meson_reset_data,
+						     rcdev);
+
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	reg = readl(data->membase + MESON_RST_OFFSET);
+	writel(reg & ~BIT(id), data->membase + MESON_RST_OFFSET);
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	return 0;
+}
+
+static int meson_reset_dev(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	int err;
+
+	err = meson_reset_assert(rcdev, id);
+	if (err)
+		return err;
+
+	return meson_reset_deassert(rcdev, id);
+}
+
+static struct reset_control_ops meson_reset_ops = {
+	.assert		= meson_reset_assert,
+	.deassert	= meson_reset_deassert,
+	.reset		= meson_reset_dev,
+};
+
+static int meson_reset_probe(struct platform_device *pdev)
+{
+	struct meson_reset_data *data;
+	struct resource *res;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

drivers/reset/reset-meson.c line 109

Quoted 10 lines
drivers/reset/reset-meson.c new file +10 -0
+	data->membase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->membase))
+		return PTR_ERR(data->membase);
+
+	spin_lock_init(&data->lock);
+
+	platform_set_drvdata(pdev, data);
+
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = BITS_PER_LONG;

Are all bits in this registers reset controls (or rather, are you positive there is no bit in this register used by anything else)?

Quoted 35 lines
drivers/reset/reset-meson.c new file +33 -0
+	data->rcdev.ops = &meson_reset_ops;
+	data->rcdev.of_node = pdev->dev.of_node;
+
+	return reset_controller_register(&data->rcdev);
+}
+
+static int meson_reset_remove(struct platform_device *pdev)
+{
+	struct meson_reset_data *data = platform_get_drvdata(pdev);
+
+	reset_controller_unregister(&data->rcdev);
+
+	return 0;
+}
+
+static const struct of_device_id meson_reset_dt_ids[] = {
+	{ .compatible = "amlogic,meson6-rst-mgr-ao", },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver meson_reset_driver = {
+	.probe	= meson_reset_probe,
+	.remove	= meson_reset_remove,
+	.driver = {
+		.name		= "meson-reset",
+		.of_match_table	= meson_reset_dt_ids,
+	},
+};
+module_platform_driver(meson_reset_driver);
+
+MODULE_AUTHOR("Carlo Caione <[email protected]>");
+MODULE_DESCRIPTION("Meson Reset Controller Driver");
+MODULE_LICENSE("GPL");
Signature · 1 line
1.9.1

Other than that, the driver looks good.

regards
Philipp

#3 lore raw

PATCH v2 1/3 ARM: meson: reset: Add reset controller for MesonX SoCs

Quoted 1 line · Philipp Zabel

Hi Carlo,

Hi Philipp,

Quoted 8 lines

drivers/reset/reset-meson.c line 5

Quoted 6 lines
drivers/reset/reset-meson.c new file +5 -0
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2014 Carlo Caione <[email protected]>
+ *
+ * based on
+ * Steffen Trumtrar Reset Controller driver

That doesn't sound right. Do you mean socfpga-reset?

Yes, I'll change it.

Quoted 5 lines

drivers/reset/reset-meson.c line 9

Quoted 3 lines
drivers/reset/reset-meson.c new file +3 -0
+ * Copyright 2014 Steffen Trumtrar
+ *
+ * Steffen Trumtrar <[email protected]>

Could be combined into a single line.

Ok

Quoted 10 lines
Quoted 10 lines
drivers/reset/reset-meson.c new file +10 -0
+ * 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/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
Quoted 8 lines

drivers/reset/reset-meson.c line 26

Quoted 6 lines
drivers/reset/reset-meson.c new file +6 -0
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define MESON_RST_OFFSET     0x00

If there is only one register, I see no need for this.

Ok

Quoted 6 lines

drivers/reset/reset-meson.c line 109

Quoted 3 lines
drivers/reset/reset-meson.c new file +3 -0
+
+     data->rcdev.owner = THIS_MODULE;
+     data->rcdev.nr_resets = BITS_PER_LONG;

Are all bits in this registers reset controls (or rather, are you positive there is no bit in this register used by anything else)?

I'm not sure to be honest. Probably some other bits is used for power management (I don't have full documentation yet).
I'll submit a v3 with a smaller mask for just the bits I'm going to use.

Quoted 1 line

Other than that, the driver looks good.

Thank you.

Signature · 1 line
Carlo Caione
#4 lore raw

PATCH v2 2/3 ARM: meson: DTSI: Enable reset controller

In reply to Carlo Caione

Add the node for the reset controller in the DTSI.

---
 arch/arm/boot/dts/meson.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/boot/dts/meson.dtsi +6 -0
index e6539ea..1ca864e 100644
@@ -75,6 +75,12 @@
 			reg = <0xc1109900 0x8>;
 		};
 
+		reset_AO: reset at c8100040 {
+			#reset-cells = <1>;
+			compatible = "amlogic,meson6-rst-mgr-ao";
+			reg = <0xc8100040 0x4>;
+		};
+
 		uart_AO: serial at c81004c0 {
 			compatible = "amlogic,meson-uart";
 			reg = <0xc81004c0 0x14>;
Signature · 1 line
1.9.1
#5 lore raw

PATCH v2 2/3 ARM: meson: DTSI: Enable reset controller

Quoted 14 lines · Carlo Caione

Add the node for the reset controller in the DTSI.

---
 arch/arm/boot/dts/meson.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/boot/dts/meson.dtsi +0 -0
index e6539ea..1ca864e 100644
@@ -75,6 +75,12 @@
 			reg = <0xc1109900 0x8>;
 		};

arch/arm/boot/dts/meson.dtsi line 86

Quoted 10 lines
arch/arm/boot/dts/meson.dtsi +6 -0
 
+		reset_AO: reset at c8100040 {
+			#reset-cells = <1>;
+			compatible = "amlogic,meson6-rst-mgr-ao";
+			reg = <0xc8100040 0x4>;
+		};
+
 		uart_AO: serial at c81004c0 {
 			compatible = "amlogic,meson-uart";
 			reg = <0xc81004c0 0x14>;

This needs to go through the same tree as the one meson.dtsi got included in.

regards
Philipp

#6 lore raw

PATCH v2 3/3 ARM: meson: docs: Add docs for MesonX reset controller

In reply to Carlo Caione
---
 .../bindings/reset/amlogic,meson6-rst-mgr-ao.txt           | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/amlogic,meson6-rst-mgr-ao.txt
Documentation/devicetree/bindings/reset/amlogic,meson6-rst-mgr-ao.txt new file +14 -0
new file mode 100644
index 0000000..4a8fd41
@@ -0,0 +1,14 @@
+Amlogic MesonX Reset Manager (AO domain)
+
+Required properties:
+- compatible : "amlogic,meson6-rst-mgr-ao"
+- reg : Should contain 1 register ranges(address and length)
+- #reset-cells: 1
+
+Example:
+
+	reset: reset at c8100040 {
+		#reset-cells = <1>;
+		compatible = "amlogic,meson6-rst-mgr-ao";
+		reg = <0xc8100040 0x4>;
+	};
Signature · 1 line
1.9.1