diff options
Diffstat (limited to 'drivers/clk/samsung/clk-exynos5440.c')
-rw-r--r-- | drivers/clk/samsung/clk-exynos5440.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index 00d1d00a41de..979e81389cdd 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/notifier.h> | ||
19 | #include <linux/reboot.h> | ||
18 | 20 | ||
19 | #include "clk.h" | 21 | #include "clk.h" |
20 | #include "clk-pll.h" | 22 | #include "clk-pll.h" |
@@ -23,6 +25,8 @@ | |||
23 | #define CPU_CLK_STATUS 0xfc | 25 | #define CPU_CLK_STATUS 0xfc |
24 | #define MISC_DOUT1 0x558 | 26 | #define MISC_DOUT1 0x558 |
25 | 27 | ||
28 | static void __iomem *reg_base; | ||
29 | |||
26 | /* parent clock name list */ | 30 | /* parent clock name list */ |
27 | PNAME(mout_armclk_p) = { "cplla", "cpllb" }; | 31 | PNAME(mout_armclk_p) = { "cplla", "cpllb" }; |
28 | PNAME(mout_spi_p) = { "div125", "div200" }; | 32 | PNAME(mout_spi_p) = { "div125", "div200" }; |
@@ -89,10 +93,30 @@ static const struct of_device_id ext_clk_match[] __initconst = { | |||
89 | {}, | 93 | {}, |
90 | }; | 94 | }; |
91 | 95 | ||
96 | static int exynos5440_clk_restart_notify(struct notifier_block *this, | ||
97 | unsigned long code, void *unused) | ||
98 | { | ||
99 | u32 val, status; | ||
100 | |||
101 | status = readl_relaxed(reg_base + 0xbc); | ||
102 | val = readl_relaxed(reg_base + 0xcc); | ||
103 | val = (val & 0xffff0000) | (status & 0xffff); | ||
104 | writel_relaxed(val, reg_base + 0xcc); | ||
105 | |||
106 | return NOTIFY_DONE; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Exynos5440 Clock restart notifier, handles restart functionality | ||
111 | */ | ||
112 | static struct notifier_block exynos5440_clk_restart_handler = { | ||
113 | .notifier_call = exynos5440_clk_restart_notify, | ||
114 | .priority = 128, | ||
115 | }; | ||
116 | |||
92 | /* register exynos5440 clocks */ | 117 | /* register exynos5440 clocks */ |
93 | static void __init exynos5440_clk_init(struct device_node *np) | 118 | static void __init exynos5440_clk_init(struct device_node *np) |
94 | { | 119 | { |
95 | void __iomem *reg_base; | ||
96 | struct samsung_clk_provider *ctx; | 120 | struct samsung_clk_provider *ctx; |
97 | 121 | ||
98 | reg_base = of_iomap(np, 0); | 122 | reg_base = of_iomap(np, 0); |
@@ -125,6 +149,9 @@ static void __init exynos5440_clk_init(struct device_node *np) | |||
125 | 149 | ||
126 | samsung_clk_of_add_provider(np, ctx); | 150 | samsung_clk_of_add_provider(np, ctx); |
127 | 151 | ||
152 | if (register_restart_handler(&exynos5440_clk_restart_handler)) | ||
153 | pr_warn("exynos5440 clock can't register restart handler\n"); | ||
154 | |||
128 | pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); | 155 | pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); |
129 | pr_info("exynos5440 clock initialization complete\n"); | 156 | pr_info("exynos5440 clock initialization complete\n"); |
130 | } | 157 | } |