struct s3c2410_wdt {
        struct device           *dev;
-       struct clk              *clock;
+       struct clk              *bus_clk; /* for register interface (PCLK) */
+       struct clk              *src_clk; /* for WDT counter */
        void __iomem            *reg_base;
        unsigned int            count;
        spinlock_t              lock;
 
 /* functions */
 
-static inline unsigned int s3c2410wdt_max_timeout(struct clk *clock)
+static inline unsigned long s3c2410wdt_get_freq(struct s3c2410_wdt *wdt)
 {
-       unsigned long freq = clk_get_rate(clock);
+       return clk_get_rate(wdt->src_clk ? wdt->src_clk : wdt->bus_clk);
+}
+
+static inline unsigned int s3c2410wdt_max_timeout(struct s3c2410_wdt *wdt)
+{
+       const unsigned long freq = s3c2410wdt_get_freq(wdt);
 
        return S3C2410_WTCNT_MAXCNT / (freq / (S3C2410_WTCON_PRESCALE_MAX + 1)
                                       / S3C2410_WTCON_MAXDIV);
                                    unsigned int timeout)
 {
        struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd);
-       unsigned long freq = clk_get_rate(wdt->clock);
+       unsigned long freq = s3c2410wdt_get_freq(wdt);
        unsigned int count;
        unsigned int divisor = 1;
        unsigned long wtcon;
                goto err;
        }
 
-       wdt->clock = devm_clk_get(dev, "watchdog");
-       if (IS_ERR(wdt->clock)) {
-               dev_err(dev, "failed to find watchdog clock source\n");
-               ret = PTR_ERR(wdt->clock);
+       wdt->bus_clk = devm_clk_get(dev, "watchdog");
+       if (IS_ERR(wdt->bus_clk)) {
+               dev_err(dev, "failed to find bus clock\n");
+               ret = PTR_ERR(wdt->bus_clk);
                goto err;
        }
 
-       ret = clk_prepare_enable(wdt->clock);
+       ret = clk_prepare_enable(wdt->bus_clk);
        if (ret < 0) {
-               dev_err(dev, "failed to enable clock\n");
+               dev_err(dev, "failed to enable bus clock\n");
                return ret;
        }
 
+       /*
+        * "watchdog_src" clock is optional; if it's not present -- just skip it
+        * and use "watchdog" clock as both bus and source clock.
+        */
+       wdt->src_clk = devm_clk_get(dev, "watchdog_src");
+       if (!IS_ERR(wdt->src_clk)) {
+               ret = clk_prepare_enable(wdt->src_clk);
+               if (ret < 0) {
+                       dev_err(dev, "failed to enable source clock\n");
+                       ret = PTR_ERR(wdt->src_clk);
+                       goto err_bus_clk;
+               }
+       } else {
+               wdt->src_clk = NULL;
+       }
+
        wdt->wdt_device.min_timeout = 1;
-       wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt->clock);
+       wdt->wdt_device.max_timeout = s3c2410wdt_max_timeout(wdt);
 
        ret = s3c2410wdt_cpufreq_register(wdt);
        if (ret < 0) {
                dev_err(dev, "failed to register cpufreq\n");
-               goto err_clk;
+               goto err_src_clk;
        }
 
        watchdog_set_drvdata(&wdt->wdt_device, wdt);
  err_cpufreq:
        s3c2410wdt_cpufreq_deregister(wdt);
 
- err_clk:
-       clk_disable_unprepare(wdt->clock);
+ err_src_clk:
+       clk_disable_unprepare(wdt->src_clk);
+
+ err_bus_clk:
+       clk_disable_unprepare(wdt->bus_clk);
 
  err:
        return ret;
 
        s3c2410wdt_cpufreq_deregister(wdt);
 
-       clk_disable_unprepare(wdt->clock);
+       clk_disable_unprepare(wdt->src_clk);
+       clk_disable_unprepare(wdt->bus_clk);
 
        return 0;
 }