diff options
| -rw-r--r-- | drivers/clk/samsung/clk-s3c2412.c | 29 | ||||
| -rw-r--r-- | drivers/clk/samsung/clk-s3c2443.c | 19 |
2 files changed, 48 insertions, 0 deletions
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c index 34af09f6a155..2ceedaf8ce18 100644 --- a/drivers/clk/samsung/clk-s3c2412.c +++ b/drivers/clk/samsung/clk-s3c2412.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
| 15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
| 16 | #include <linux/syscore_ops.h> | 16 | #include <linux/syscore_ops.h> |
| 17 | #include <linux/reboot.h> | ||
| 17 | 18 | ||
| 18 | #include <dt-bindings/clock/s3c2412.h> | 19 | #include <dt-bindings/clock/s3c2412.h> |
| 19 | 20 | ||
| @@ -26,6 +27,7 @@ | |||
| 26 | #define CLKCON 0x0c | 27 | #define CLKCON 0x0c |
| 27 | #define CLKDIVN 0x14 | 28 | #define CLKDIVN 0x14 |
| 28 | #define CLKSRC 0x1c | 29 | #define CLKSRC 0x1c |
| 30 | #define SWRST 0x30 | ||
| 29 | 31 | ||
| 30 | /* list of PLLs to be registered */ | 32 | /* list of PLLs to be registered */ |
| 31 | enum s3c2412_plls { | 33 | enum s3c2412_plls { |
| @@ -204,6 +206,28 @@ struct samsung_clock_alias s3c2412_aliases[] __initdata = { | |||
| 204 | ALIAS(MSYSCLK, NULL, "fclk"), | 206 | ALIAS(MSYSCLK, NULL, "fclk"), |
| 205 | }; | 207 | }; |
| 206 | 208 | ||
| 209 | static int s3c2412_restart(struct notifier_block *this, | ||
| 210 | unsigned long mode, void *cmd) | ||
| 211 | { | ||
| 212 | /* errata "Watch-dog/Software Reset Problem" specifies that | ||
| 213 | * this reset must be done with the SYSCLK sourced from | ||
| 214 | * EXTCLK instead of FOUT to avoid a glitch in the reset | ||
| 215 | * mechanism. | ||
| 216 | * | ||
| 217 | * See the watchdog section of the S3C2412 manual for more | ||
| 218 | * information on this fix. | ||
| 219 | */ | ||
| 220 | |||
| 221 | __raw_writel(0x00, reg_base + CLKSRC); | ||
| 222 | __raw_writel(0x533C2412, reg_base + SWRST); | ||
| 223 | return NOTIFY_DONE; | ||
| 224 | } | ||
| 225 | |||
| 226 | static struct notifier_block s3c2412_restart_handler = { | ||
| 227 | .notifier_call = s3c2412_restart, | ||
| 228 | .priority = 129, | ||
| 229 | }; | ||
| 230 | |||
| 207 | /* | 231 | /* |
| 208 | * fixed rate clocks generated outside the soc | 232 | * fixed rate clocks generated outside the soc |
| 209 | * Only necessary until the devicetree-move is complete | 233 | * 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, | |||
| 233 | unsigned long ext_f, void __iomem *base) | 257 | unsigned long ext_f, void __iomem *base) |
| 234 | { | 258 | { |
| 235 | struct samsung_clk_provider *ctx; | 259 | struct samsung_clk_provider *ctx; |
| 260 | int ret; | ||
| 236 | reg_base = base; | 261 | reg_base = base; |
| 237 | 262 | ||
| 238 | if (np) { | 263 | if (np) { |
| @@ -267,6 +292,10 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f, | |||
| 267 | s3c2412_clk_sleep_init(); | 292 | s3c2412_clk_sleep_init(); |
| 268 | 293 | ||
| 269 | samsung_clk_of_add_provider(np, ctx); | 294 | samsung_clk_of_add_provider(np, ctx); |
| 295 | |||
| 296 | ret = register_restart_handler(&s3c2412_restart_handler); | ||
| 297 | if (ret) | ||
| 298 | pr_warn("cannot register restart handler, %d\n", ret); | ||
| 270 | } | 299 | } |
| 271 | 300 | ||
| 272 | static void __init s3c2412_clk_init(struct device_node *np) | 301 | static void __init s3c2412_clk_init(struct device_node *np) |
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c index c92f853fca9f..0c3c182b902a 100644 --- a/drivers/clk/samsung/clk-s3c2443.c +++ b/drivers/clk/samsung/clk-s3c2443.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/of.h> | 14 | #include <linux/of.h> |
| 15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
| 16 | #include <linux/syscore_ops.h> | 16 | #include <linux/syscore_ops.h> |
| 17 | #include <linux/reboot.h> | ||
| 17 | 18 | ||
| 18 | #include <dt-bindings/clock/s3c2443.h> | 19 | #include <dt-bindings/clock/s3c2443.h> |
| 19 | 20 | ||
| @@ -33,6 +34,7 @@ | |||
| 33 | #define HCLKCON 0x30 | 34 | #define HCLKCON 0x30 |
| 34 | #define PCLKCON 0x34 | 35 | #define PCLKCON 0x34 |
| 35 | #define SCLKCON 0x38 | 36 | #define SCLKCON 0x38 |
| 37 | #define SWRST 0x44 | ||
| 36 | 38 | ||
| 37 | /* the soc types */ | 39 | /* the soc types */ |
| 38 | enum supported_socs { | 40 | enum supported_socs { |
| @@ -354,6 +356,18 @@ struct samsung_clock_alias s3c2450_aliases[] __initdata = { | |||
| 354 | ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"), | 356 | ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"), |
| 355 | }; | 357 | }; |
| 356 | 358 | ||
| 359 | static int s3c2443_restart(struct notifier_block *this, | ||
| 360 | unsigned long mode, void *cmd) | ||
| 361 | { | ||
| 362 | __raw_writel(0x533c2443, reg_base + SWRST); | ||
| 363 | return NOTIFY_DONE; | ||
| 364 | } | ||
| 365 | |||
| 366 | static struct notifier_block s3c2443_restart_handler = { | ||
| 367 | .notifier_call = s3c2443_restart, | ||
| 368 | .priority = 129, | ||
| 369 | }; | ||
| 370 | |||
| 357 | /* | 371 | /* |
| 358 | * fixed rate clocks generated outside the soc | 372 | * fixed rate clocks generated outside the soc |
| 359 | * Only necessary until the devicetree-move is complete | 373 | * Only necessary until the devicetree-move is complete |
| @@ -378,6 +392,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, | |||
| 378 | void __iomem *base) | 392 | void __iomem *base) |
| 379 | { | 393 | { |
| 380 | struct samsung_clk_provider *ctx; | 394 | struct samsung_clk_provider *ctx; |
| 395 | int ret; | ||
| 381 | reg_base = base; | 396 | reg_base = base; |
| 382 | 397 | ||
| 383 | if (np) { | 398 | if (np) { |
| @@ -447,6 +462,10 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, | |||
| 447 | s3c2443_clk_sleep_init(); | 462 | s3c2443_clk_sleep_init(); |
| 448 | 463 | ||
| 449 | samsung_clk_of_add_provider(np, ctx); | 464 | samsung_clk_of_add_provider(np, ctx); |
| 465 | |||
| 466 | ret = register_restart_handler(&s3c2443_restart_handler); | ||
| 467 | if (ret) | ||
| 468 | pr_warn("cannot register restart handler, %d\n", ret); | ||
| 450 | } | 469 | } |
| 451 | 470 | ||
| 452 | static void __init s3c2416_clk_init(struct device_node *np) | 471 | static void __init s3c2416_clk_init(struct device_node *np) |
