|
@@ -14,6 +14,7 @@
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/of_address.h>
|
|
|
#include <linux/syscore_ops.h>
|
|
|
+#include <linux/reboot.h>
|
|
|
|
|
|
#include <dt-bindings/clock/s3c2412.h>
|
|
|
|
|
@@ -26,6 +27,7 @@
|
|
|
#define CLKCON 0x0c
|
|
|
#define CLKDIVN 0x14
|
|
|
#define CLKSRC 0x1c
|
|
|
+#define SWRST 0x30
|
|
|
|
|
|
/* list of PLLs to be registered */
|
|
|
enum s3c2412_plls {
|
|
@@ -204,6 +206,28 @@ struct samsung_clock_alias s3c2412_aliases[] __initdata = {
|
|
|
ALIAS(MSYSCLK, NULL, "fclk"),
|
|
|
};
|
|
|
|
|
|
+static int s3c2412_restart(struct notifier_block *this,
|
|
|
+ unsigned long mode, void *cmd)
|
|
|
+{
|
|
|
+ /* errata "Watch-dog/Software Reset Problem" specifies that
|
|
|
+ * this reset must be done with the SYSCLK sourced from
|
|
|
+ * EXTCLK instead of FOUT to avoid a glitch in the reset
|
|
|
+ * mechanism.
|
|
|
+ *
|
|
|
+ * See the watchdog section of the S3C2412 manual for more
|
|
|
+ * information on this fix.
|
|
|
+ */
|
|
|
+
|
|
|
+ __raw_writel(0x00, reg_base + CLKSRC);
|
|
|
+ __raw_writel(0x533C2412, reg_base + SWRST);
|
|
|
+ return NOTIFY_DONE;
|
|
|
+}
|
|
|
+
|
|
|
+static struct notifier_block s3c2412_restart_handler = {
|
|
|
+ .notifier_call = s3c2412_restart,
|
|
|
+ .priority = 129,
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* fixed rate clocks generated outside the soc
|
|
|
* Only necessary until the devicetree-move is complete
|
|
@@ -233,6 +257,7 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
|
|
|
unsigned long ext_f, void __iomem *base)
|
|
|
{
|
|
|
struct samsung_clk_provider *ctx;
|
|
|
+ int ret;
|
|
|
reg_base = base;
|
|
|
|
|
|
if (np) {
|
|
@@ -267,6 +292,10 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
|
|
|
s3c2412_clk_sleep_init();
|
|
|
|
|
|
samsung_clk_of_add_provider(np, ctx);
|
|
|
+
|
|
|
+ ret = register_restart_handler(&s3c2412_restart_handler);
|
|
|
+ if (ret)
|
|
|
+ pr_warn("cannot register restart handler, %d\n", ret);
|
|
|
}
|
|
|
|
|
|
static void __init s3c2412_clk_init(struct device_node *np)
|