ARM: meson: Add reset controller
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
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
@@ -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
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.
Signed-off-by Carlo Caione <[email protected]>--- drivers/reset/Makefile | 1 + drivers/reset/reset-meson.c | 142 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 drivers/reset/reset-meson.cdrivers/reset/Makefile +1
-0@@ -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
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
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 0x00If 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
PATCH v2 2/3 ARM: meson: DTSI: Enable reset controller
In reply to Carlo CaioneAdd 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
@@ -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
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.
Signed-off-by Carlo Caione <[email protected]>--- arch/arm/boot/dts/meson.dtsi | 6 ++++++ 1 file changed, 6 insertions(+)arch/arm/boot/dts/meson.dtsi +0
-0@@ -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
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
@@ -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