mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 14:13:16 +00:00
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);
|