mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 18:19:02 +00:00
8cacf2bda8
This series of upstream patches makes the system controller node as a reset provider[1][2], and it also includes some clock and reset driver fixes[3][4]. Meanwhile, all clocks and resets properties in the SoC device tree have been updated to be compatible with the new driver. [1] https://lore.kernel.org/r/20220110114930.1406665-2-sergio.paracuellos@gmail.com [2] https://lore.kernel.org/r/20220210094859.927868-2-sergio.paracuellos@gmail.com [3] https://lore.kernel.org/r/20221217074806.3225150-1-sergio.paracuellos@gmail.com [4] https://lore.kernel.org/r/20230206083305.147582-1-sergio.paracuellos@gmail.com Tested on RAISECOM MSG1500 X.00 Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au> Signed-off-by: Shiji Yang <yangshiji66@qq.com>
149 lines
4.4 KiB
Diff
149 lines
4.4 KiB
Diff
From 38a8553b0a22ed54f014d8402fedd268b529175c Mon Sep 17 00:00:00 2001
|
|
From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
|
Date: Thu, 10 Feb 2022 10:48:59 +0100
|
|
Subject: [PATCH 2/2] clk: ralink: make system controller node a reset provider
|
|
|
|
MT7621 system controller node is already providing the clocks for the whole
|
|
system but must also serve as a reset provider. Hence, add reset controller
|
|
related code to the clock driver itself. To get resets properly ready for
|
|
the rest of the world we need to move platform driver initialization process
|
|
to 'arch_initcall'.
|
|
|
|
CC: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Acked-by: Stephen Boyd <sboyd@kernel.org>
|
|
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
|
Link: https://lore.kernel.org/r/20220210094859.927868-3-sergio.paracuellos@gmail.com
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/clk/ralink/clk-mt7621.c | 92 ++++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 91 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/clk/ralink/clk-mt7621.c
|
|
+++ b/drivers/clk/ralink/clk-mt7621.c
|
|
@@ -11,14 +11,17 @@
|
|
#include <linux/mfd/syscon.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regmap.h>
|
|
+#include <linux/reset-controller.h>
|
|
#include <linux/slab.h>
|
|
#include <dt-bindings/clock/mt7621-clk.h>
|
|
+#include <dt-bindings/reset/mt7621-reset.h>
|
|
|
|
/* Configuration registers */
|
|
#define SYSC_REG_SYSTEM_CONFIG0 0x10
|
|
#define SYSC_REG_SYSTEM_CONFIG1 0x14
|
|
#define SYSC_REG_CLKCFG0 0x2c
|
|
#define SYSC_REG_CLKCFG1 0x30
|
|
+#define SYSC_REG_RESET_CTRL 0x34
|
|
#define SYSC_REG_CUR_CLK_STS 0x44
|
|
#define MEMC_REG_CPU_PLL 0x648
|
|
|
|
@@ -398,6 +401,82 @@ free_clk_priv:
|
|
}
|
|
CLK_OF_DECLARE_DRIVER(mt7621_clk, "mediatek,mt7621-sysc", mt7621_clk_init);
|
|
|
|
+struct mt7621_rst {
|
|
+ struct reset_controller_dev rcdev;
|
|
+ struct regmap *sysc;
|
|
+};
|
|
+
|
|
+static struct mt7621_rst *to_mt7621_rst(struct reset_controller_dev *dev)
|
|
+{
|
|
+ return container_of(dev, struct mt7621_rst, rcdev);
|
|
+}
|
|
+
|
|
+static int mt7621_assert_device(struct reset_controller_dev *rcdev,
|
|
+ unsigned long id)
|
|
+{
|
|
+ struct mt7621_rst *data = to_mt7621_rst(rcdev);
|
|
+ struct regmap *sysc = data->sysc;
|
|
+
|
|
+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id));
|
|
+}
|
|
+
|
|
+static int mt7621_deassert_device(struct reset_controller_dev *rcdev,
|
|
+ unsigned long id)
|
|
+{
|
|
+ struct mt7621_rst *data = to_mt7621_rst(rcdev);
|
|
+ struct regmap *sysc = data->sysc;
|
|
+
|
|
+ return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0);
|
|
+}
|
|
+
|
|
+static int mt7621_reset_device(struct reset_controller_dev *rcdev,
|
|
+ unsigned long id)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = mt7621_assert_device(rcdev, id);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ return mt7621_deassert_device(rcdev, id);
|
|
+}
|
|
+
|
|
+static int mt7621_rst_xlate(struct reset_controller_dev *rcdev,
|
|
+ const struct of_phandle_args *reset_spec)
|
|
+{
|
|
+ unsigned long id = reset_spec->args[0];
|
|
+
|
|
+ if (id == MT7621_RST_SYS || id >= rcdev->nr_resets)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return id;
|
|
+}
|
|
+
|
|
+static const struct reset_control_ops reset_ops = {
|
|
+ .reset = mt7621_reset_device,
|
|
+ .assert = mt7621_assert_device,
|
|
+ .deassert = mt7621_deassert_device
|
|
+};
|
|
+
|
|
+static int mt7621_reset_init(struct device *dev, struct regmap *sysc)
|
|
+{
|
|
+ struct mt7621_rst *rst_data;
|
|
+
|
|
+ rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
|
|
+ if (!rst_data)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ rst_data->sysc = sysc;
|
|
+ rst_data->rcdev.ops = &reset_ops;
|
|
+ rst_data->rcdev.owner = THIS_MODULE;
|
|
+ rst_data->rcdev.nr_resets = 32;
|
|
+ rst_data->rcdev.of_reset_n_cells = 1;
|
|
+ rst_data->rcdev.of_xlate = mt7621_rst_xlate;
|
|
+ rst_data->rcdev.of_node = dev_of_node(dev);
|
|
+
|
|
+ return devm_reset_controller_register(dev, &rst_data->rcdev);
|
|
+}
|
|
+
|
|
static int mt7621_clk_probe(struct platform_device *pdev)
|
|
{
|
|
struct device_node *np = pdev->dev.of_node;
|
|
@@ -424,6 +503,12 @@ static int mt7621_clk_probe(struct platf
|
|
return ret;
|
|
}
|
|
|
|
+ ret = mt7621_reset_init(dev, priv->sysc);
|
|
+ if (ret) {
|
|
+ dev_err(dev, "Could not init reset controller\n");
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
count = ARRAY_SIZE(mt7621_clks_base) +
|
|
ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates);
|
|
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
|
|
@@ -485,4 +570,9 @@ static struct platform_driver mt7621_clk
|
|
.of_match_table = mt7621_clk_of_match,
|
|
},
|
|
};
|
|
-builtin_platform_driver(mt7621_clk_driver);
|
|
+
|
|
+static int __init mt7621_clk_reset_init(void)
|
|
+{
|
|
+ return platform_driver_register(&mt7621_clk_driver);
|
|
+}
|
|
+arch_initcall(mt7621_clk_reset_init);
|