| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- From 38a8553b0a22ed54f014d8402fedd268b529175c Mon Sep 17 00:00:00 2001
- From: Sergio Paracuellos <[email protected]>
- 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 <[email protected]>
- Reviewed-by: Philipp Zabel <[email protected]>
- Acked-by: Stephen Boyd <[email protected]>
- Signed-off-by: Sergio Paracuellos <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- Signed-off-by: Greg Kroah-Hartman <[email protected]>
- ---
- 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);
|