[PATCH] fixup! clk: rockchip: Update to current Linux

Ahmad Fatoum a.fatoum at pengutronix.de
Wed Jun 9 02:23:08 PDT 2021


Linux clock drivers for rockchip SoCs have to convenience functions
that weren't ported:

	rockchip_register_restart_notifier()
	rockchip_register_softrst()

They control system and peripheral reset, respectively. Port both.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
Hello Sascha,

I ported these over for rk3399, but I see, you might need them too,
so sending these out early.

Ported from v5.13.
---
 drivers/clk/rockchip/Makefile  |   1 +
 drivers/clk/rockchip/clk.c     |  26 ++++++++
 drivers/clk/rockchip/clk.h     |  17 +++++
 drivers/clk/rockchip/softrst.c | 110 +++++++++++++++++++++++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 drivers/clk/rockchip/softrst.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 4c387b3a890e..a2461d16c10d 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += clk-cpu.o clk-pll.o clk.o clk-muxgrf.o clk-mmc-phase.o clk-inverter.o
+obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
 obj-$(CONFIG_ARCH_RK3188) += clk-rk3188.o
 obj-$(CONFIG_ARCH_RK3288) += clk-rk3288.o
 obj-$(CONFIG_ARCH_RK3568) += clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index dd542c2e2060..613b168b4d96 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -21,6 +21,7 @@
 #include <mfd/syscon.h>
 #include <linux/spinlock.h>
 #include <linux/rational.h>
+#include <restart.h>
 #include "clk.h"
 
 /*
@@ -545,3 +546,28 @@ void rockchip_clk_protect_critical(const char *const clocks[],
 	}
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical);
+
+static void rockchip_restart(struct restart_handler *this)
+{
+	struct rockchip_clk_provider *ctx =
+		container_of(this, struct rockchip_clk_provider, restart_handler);
+
+	writel(0xfdb9, ctx->reg_base + ctx->reg_restart);
+	mdelay(1000);
+}
+
+void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
+					unsigned int reg)
+{
+	int ret;
+
+	ctx->restart_handler.name = "rockchip-pmu",
+	ctx->restart_handler.restart = rockchip_restart,
+	ctx->restart_handler.priority = RESTART_DEFAULT_PRIORITY,
+
+	ret = restart_handler_register(&ctx->restart_handler);
+	if (ret)
+		pr_err("%s: cannot register restart handler, %d\n",
+		       __func__, ret);
+}
+EXPORT_SYMBOL_GPL(rockchip_register_restart_notifier);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index c17da6e66386..2616277bb049 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -19,6 +19,7 @@
 
 #include <io.h>
 #include <linux/clk.h>
+#include <restart.h>
 
 struct clk;
 #define writel_relaxed	writel
@@ -268,6 +269,8 @@ struct rockchip_clk_provider {
 	struct clk_onecell_data clk_data;
 	struct device_node *cru_node;
 	struct regmap *grf;
+	struct restart_handler restart_handler;
+	unsigned int reg_restart;
 	spinlock_t lock;
 };
 
@@ -806,6 +809,20 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 			const struct rockchip_cpuclk_rate_table *rates,
 			int nrates);
 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
+void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
+					unsigned int reg);
+
+#ifdef CONFIG_RESET_CONTROLLER
+void rockchip_register_softrst(struct device_node *np,
+			       unsigned int num_regs,
+			       void __iomem *base, u8 flags);
+#else
+static inline void rockchip_register_softrst(struct device_node *np,
+			       unsigned int num_regs,
+			       void __iomem *base, u8 flags)
+{
+}
+#endif
 
 #define ROCKCHIP_SOFTRST_HIWORD_MASK	BIT(0)
 
diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c
new file mode 100644
index 000000000000..e3f3937ca019
--- /dev/null
+++ b/drivers/clk/rockchip/softrst.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko at sntech.de>
+ */
+
+#include <common.h>
+#include <io.h>
+#include <linux/bitops.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+#include "clk.h"
+
+struct rockchip_softrst {
+	struct reset_controller_dev	rcdev;
+	void __iomem			*reg_base;
+	int				num_regs;
+	int				num_per_reg;
+	u8				flags;
+	spinlock_t			lock;
+};
+
+static int rockchip_softrst_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct rockchip_softrst *softrst = container_of(rcdev,
+						     struct rockchip_softrst,
+						     rcdev);
+	int bank = id / softrst->num_per_reg;
+	int offset = id % softrst->num_per_reg;
+
+	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
+		writel(BIT(offset) | (BIT(offset) << 16),
+		       softrst->reg_base + (bank * 4));
+	} else {
+		unsigned long flags;
+		u32 reg;
+
+		spin_lock_irqsave(&softrst->lock, flags);
+
+		reg = readl(softrst->reg_base + (bank * 4));
+		writel(reg | BIT(offset), softrst->reg_base + (bank * 4));
+
+		spin_unlock_irqrestore(&softrst->lock, flags);
+	}
+
+	return 0;
+}
+
+static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	struct rockchip_softrst *softrst = container_of(rcdev,
+						     struct rockchip_softrst,
+						     rcdev);
+	int bank = id / softrst->num_per_reg;
+	int offset = id % softrst->num_per_reg;
+
+	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
+		writel((BIT(offset) << 16), softrst->reg_base + (bank * 4));
+	} else {
+		unsigned long flags;
+		u32 reg;
+
+		spin_lock_irqsave(&softrst->lock, flags);
+
+		reg = readl(softrst->reg_base + (bank * 4));
+		writel(reg & ~BIT(offset), softrst->reg_base + (bank * 4));
+
+		spin_unlock_irqrestore(&softrst->lock, flags);
+	}
+
+	return 0;
+}
+
+static const struct reset_control_ops rockchip_softrst_ops = {
+	.assert		= rockchip_softrst_assert,
+	.deassert	= rockchip_softrst_deassert,
+};
+
+void rockchip_register_softrst(struct device_node *np,
+			       unsigned int num_regs,
+			       void __iomem *base, u8 flags)
+{
+	struct rockchip_softrst *softrst;
+	int ret;
+
+	softrst = kzalloc(sizeof(*softrst), GFP_KERNEL);
+	if (!softrst)
+		return;
+
+	spin_lock_init(&softrst->lock);
+
+	softrst->reg_base = base;
+	softrst->flags = flags;
+	softrst->num_regs = num_regs;
+	softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16
+								      : 32;
+
+	softrst->rcdev.nr_resets =  num_regs * softrst->num_per_reg;
+	softrst->rcdev.ops = &rockchip_softrst_ops;
+	softrst->rcdev.of_node = np;
+	ret = reset_controller_register(&softrst->rcdev);
+	if (ret) {
+		pr_err("%s: could not register reset controller, %d\n",
+		       __func__, ret);
+		kfree(softrst);
+	}
+};
+EXPORT_SYMBOL_GPL(rockchip_register_softrst);
-- 
2.29.2




More information about the barebox mailing list