root/drivers/watchdog/orion_wdt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. orion_wdt_clock_init
  2. armada370_wdt_clock_init
  3. armada375_wdt_clock_init
  4. armadaxp_wdt_clock_init
  5. orion_wdt_ping
  6. armada375_start
  7. armada370_start
  8. orion_start
  9. orion_wdt_start
  10. orion_stop
  11. armada375_stop
  12. armada370_stop
  13. orion_wdt_stop
  14. orion_enabled
  15. armada375_enabled
  16. orion_wdt_enabled
  17. orion_wdt_get_timeleft
  18. orion_wdt_irq
  19. orion_wdt_pre_irq
  20. orion_wdt_ioremap_rstout
  21. orion_wdt_get_regs
  22. orion_wdt_probe
  23. orion_wdt_remove
  24. orion_wdt_shutdown

   1 /*
   2  * drivers/watchdog/orion_wdt.c
   3  *
   4  * Watchdog driver for Orion/Kirkwood processors
   5  *
   6  * Author: Sylver Bruneau <sylver.bruneau@googlemail.com>
   7  *
   8  * This file is licensed under  the terms of the GNU General Public
   9  * License version 2. This program is licensed "as is" without any
  10  * warranty of any kind, whether express or implied.
  11  */
  12 
  13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  14 
  15 #include <linux/module.h>
  16 #include <linux/moduleparam.h>
  17 #include <linux/types.h>
  18 #include <linux/kernel.h>
  19 #include <linux/platform_device.h>
  20 #include <linux/watchdog.h>
  21 #include <linux/interrupt.h>
  22 #include <linux/io.h>
  23 #include <linux/clk.h>
  24 #include <linux/err.h>
  25 #include <linux/of.h>
  26 #include <linux/of_device.h>
  27 
  28 /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */
  29 #define ORION_RSTOUT_MASK_OFFSET        0x20108
  30 
  31 /* Internal registers can be configured at any 1 MiB aligned address */
  32 #define INTERNAL_REGS_MASK              ~(SZ_1M - 1)
  33 
  34 /*
  35  * Watchdog timer block registers.
  36  */
  37 #define TIMER_CTRL              0x0000
  38 #define TIMER1_FIXED_ENABLE_BIT BIT(12)
  39 #define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
  40 #define TIMER1_ENABLE_BIT       BIT(2)
  41 
  42 #define TIMER_A370_STATUS       0x0004
  43 #define WDT_A370_EXPIRED        BIT(31)
  44 #define TIMER1_STATUS_BIT       BIT(8)
  45 
  46 #define TIMER1_VAL_OFF          0x001c
  47 
  48 #define WDT_MAX_CYCLE_COUNT     0xffffffff
  49 
  50 #define WDT_A370_RATIO_MASK(v)  ((v) << 16)
  51 #define WDT_A370_RATIO_SHIFT    5
  52 #define WDT_A370_RATIO          (1 << WDT_A370_RATIO_SHIFT)
  53 
  54 static bool nowayout = WATCHDOG_NOWAYOUT;
  55 static int heartbeat = -1;              /* module parameter (seconds) */
  56 
  57 struct orion_watchdog;
  58 
  59 struct orion_watchdog_data {
  60         int wdt_counter_offset;
  61         int wdt_enable_bit;
  62         int rstout_enable_bit;
  63         int rstout_mask_bit;
  64         int (*clock_init)(struct platform_device *,
  65                           struct orion_watchdog *);
  66         int (*enabled)(struct orion_watchdog *);
  67         int (*start)(struct watchdog_device *);
  68         int (*stop)(struct watchdog_device *);
  69 };
  70 
  71 struct orion_watchdog {
  72         struct watchdog_device wdt;
  73         void __iomem *reg;
  74         void __iomem *rstout;
  75         void __iomem *rstout_mask;
  76         unsigned long clk_rate;
  77         struct clk *clk;
  78         const struct orion_watchdog_data *data;
  79 };
  80 
  81 static int orion_wdt_clock_init(struct platform_device *pdev,
  82                                 struct orion_watchdog *dev)
  83 {
  84         int ret;
  85 
  86         dev->clk = clk_get(&pdev->dev, NULL);
  87         if (IS_ERR(dev->clk))
  88                 return PTR_ERR(dev->clk);
  89         ret = clk_prepare_enable(dev->clk);
  90         if (ret) {
  91                 clk_put(dev->clk);
  92                 return ret;
  93         }
  94 
  95         dev->clk_rate = clk_get_rate(dev->clk);
  96         return 0;
  97 }
  98 
  99 static int armada370_wdt_clock_init(struct platform_device *pdev,
 100                                     struct orion_watchdog *dev)
 101 {
 102         int ret;
 103 
 104         dev->clk = clk_get(&pdev->dev, NULL);
 105         if (IS_ERR(dev->clk))
 106                 return PTR_ERR(dev->clk);
 107         ret = clk_prepare_enable(dev->clk);
 108         if (ret) {
 109                 clk_put(dev->clk);
 110                 return ret;
 111         }
 112 
 113         /* Setup watchdog input clock */
 114         atomic_io_modify(dev->reg + TIMER_CTRL,
 115                         WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT),
 116                         WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT));
 117 
 118         dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO;
 119         return 0;
 120 }
 121 
 122 static int armada375_wdt_clock_init(struct platform_device *pdev,
 123                                     struct orion_watchdog *dev)
 124 {
 125         int ret;
 126 
 127         dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
 128         if (!IS_ERR(dev->clk)) {
 129                 ret = clk_prepare_enable(dev->clk);
 130                 if (ret) {
 131                         clk_put(dev->clk);
 132                         return ret;
 133                 }
 134 
 135                 atomic_io_modify(dev->reg + TIMER_CTRL,
 136                                 WDT_AXP_FIXED_ENABLE_BIT,
 137                                 WDT_AXP_FIXED_ENABLE_BIT);
 138                 dev->clk_rate = clk_get_rate(dev->clk);
 139 
 140                 return 0;
 141         }
 142 
 143         /* Mandatory fallback for proper devicetree backward compatibility */
 144         dev->clk = clk_get(&pdev->dev, NULL);
 145         if (IS_ERR(dev->clk))
 146                 return PTR_ERR(dev->clk);
 147 
 148         ret = clk_prepare_enable(dev->clk);
 149         if (ret) {
 150                 clk_put(dev->clk);
 151                 return ret;
 152         }
 153 
 154         atomic_io_modify(dev->reg + TIMER_CTRL,
 155                         WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT),
 156                         WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT));
 157         dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO;
 158 
 159         return 0;
 160 }
 161 
 162 static int armadaxp_wdt_clock_init(struct platform_device *pdev,
 163                                    struct orion_watchdog *dev)
 164 {
 165         int ret;
 166         u32 val;
 167 
 168         dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
 169         if (IS_ERR(dev->clk))
 170                 return PTR_ERR(dev->clk);
 171         ret = clk_prepare_enable(dev->clk);
 172         if (ret) {
 173                 clk_put(dev->clk);
 174                 return ret;
 175         }
 176 
 177         /* Fix the wdt and timer1 clock freqency to 25MHz */
 178         val = WDT_AXP_FIXED_ENABLE_BIT | TIMER1_FIXED_ENABLE_BIT;
 179         atomic_io_modify(dev->reg + TIMER_CTRL, val, val);
 180 
 181         dev->clk_rate = clk_get_rate(dev->clk);
 182         return 0;
 183 }
 184 
 185 static int orion_wdt_ping(struct watchdog_device *wdt_dev)
 186 {
 187         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 188         /* Reload watchdog duration */
 189         writel(dev->clk_rate * wdt_dev->timeout,
 190                dev->reg + dev->data->wdt_counter_offset);
 191         if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
 192                 writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
 193                        dev->reg + TIMER1_VAL_OFF);
 194 
 195         return 0;
 196 }
 197 
 198 static int armada375_start(struct watchdog_device *wdt_dev)
 199 {
 200         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 201         u32 reg;
 202 
 203         /* Set watchdog duration */
 204         writel(dev->clk_rate * wdt_dev->timeout,
 205                dev->reg + dev->data->wdt_counter_offset);
 206         if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
 207                 writel(dev->clk_rate * (wdt_dev->timeout - wdt_dev->pretimeout),
 208                        dev->reg + TIMER1_VAL_OFF);
 209 
 210         /* Clear the watchdog expiration bit */
 211         atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0);
 212 
 213         /* Enable watchdog timer */
 214         reg = dev->data->wdt_enable_bit;
 215         if (dev->wdt.info->options & WDIOF_PRETIMEOUT)
 216                 reg |= TIMER1_ENABLE_BIT;
 217         atomic_io_modify(dev->reg + TIMER_CTRL, reg, reg);
 218 
 219         /* Enable reset on watchdog */
 220         reg = readl(dev->rstout);
 221         reg |= dev->data->rstout_enable_bit;
 222         writel(reg, dev->rstout);
 223 
 224         atomic_io_modify(dev->rstout_mask, dev->data->rstout_mask_bit, 0);
 225         return 0;
 226 }
 227 
 228 static int armada370_start(struct watchdog_device *wdt_dev)
 229 {
 230         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 231         u32 reg;
 232 
 233         /* Set watchdog duration */
 234         writel(dev->clk_rate * wdt_dev->timeout,
 235                dev->reg + dev->data->wdt_counter_offset);
 236 
 237         /* Clear the watchdog expiration bit */
 238         atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0);
 239 
 240         /* Enable watchdog timer */
 241         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
 242                                                 dev->data->wdt_enable_bit);
 243 
 244         /* Enable reset on watchdog */
 245         reg = readl(dev->rstout);
 246         reg |= dev->data->rstout_enable_bit;
 247         writel(reg, dev->rstout);
 248         return 0;
 249 }
 250 
 251 static int orion_start(struct watchdog_device *wdt_dev)
 252 {
 253         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 254 
 255         /* Set watchdog duration */
 256         writel(dev->clk_rate * wdt_dev->timeout,
 257                dev->reg + dev->data->wdt_counter_offset);
 258 
 259         /* Enable watchdog timer */
 260         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
 261                                                 dev->data->wdt_enable_bit);
 262 
 263         /* Enable reset on watchdog */
 264         atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit,
 265                                       dev->data->rstout_enable_bit);
 266 
 267         return 0;
 268 }
 269 
 270 static int orion_wdt_start(struct watchdog_device *wdt_dev)
 271 {
 272         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 273 
 274         /* There are some per-SoC quirks to handle */
 275         return dev->data->start(wdt_dev);
 276 }
 277 
 278 static int orion_stop(struct watchdog_device *wdt_dev)
 279 {
 280         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 281 
 282         /* Disable reset on watchdog */
 283         atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit, 0);
 284 
 285         /* Disable watchdog timer */
 286         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, 0);
 287 
 288         return 0;
 289 }
 290 
 291 static int armada375_stop(struct watchdog_device *wdt_dev)
 292 {
 293         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 294         u32 reg, mask;
 295 
 296         /* Disable reset on watchdog */
 297         atomic_io_modify(dev->rstout_mask, dev->data->rstout_mask_bit,
 298                                            dev->data->rstout_mask_bit);
 299         reg = readl(dev->rstout);
 300         reg &= ~dev->data->rstout_enable_bit;
 301         writel(reg, dev->rstout);
 302 
 303         /* Disable watchdog timer */
 304         mask = dev->data->wdt_enable_bit;
 305         if (wdt_dev->info->options & WDIOF_PRETIMEOUT)
 306                 mask |= TIMER1_ENABLE_BIT;
 307         atomic_io_modify(dev->reg + TIMER_CTRL, mask, 0);
 308 
 309         return 0;
 310 }
 311 
 312 static int armada370_stop(struct watchdog_device *wdt_dev)
 313 {
 314         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 315         u32 reg;
 316 
 317         /* Disable reset on watchdog */
 318         reg = readl(dev->rstout);
 319         reg &= ~dev->data->rstout_enable_bit;
 320         writel(reg, dev->rstout);
 321 
 322         /* Disable watchdog timer */
 323         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, 0);
 324 
 325         return 0;
 326 }
 327 
 328 static int orion_wdt_stop(struct watchdog_device *wdt_dev)
 329 {
 330         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 331 
 332         return dev->data->stop(wdt_dev);
 333 }
 334 
 335 static int orion_enabled(struct orion_watchdog *dev)
 336 {
 337         bool enabled, running;
 338 
 339         enabled = readl(dev->rstout) & dev->data->rstout_enable_bit;
 340         running = readl(dev->reg + TIMER_CTRL) & dev->data->wdt_enable_bit;
 341 
 342         return enabled && running;
 343 }
 344 
 345 static int armada375_enabled(struct orion_watchdog *dev)
 346 {
 347         bool masked, enabled, running;
 348 
 349         masked = readl(dev->rstout_mask) & dev->data->rstout_mask_bit;
 350         enabled = readl(dev->rstout) & dev->data->rstout_enable_bit;
 351         running = readl(dev->reg + TIMER_CTRL) & dev->data->wdt_enable_bit;
 352 
 353         return !masked && enabled && running;
 354 }
 355 
 356 static int orion_wdt_enabled(struct watchdog_device *wdt_dev)
 357 {
 358         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 359 
 360         return dev->data->enabled(dev);
 361 }
 362 
 363 static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
 364 {
 365         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 366         return readl(dev->reg + dev->data->wdt_counter_offset) / dev->clk_rate;
 367 }
 368 
 369 static struct watchdog_info orion_wdt_info = {
 370         .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 371         .identity = "Orion Watchdog",
 372 };
 373 
 374 static const struct watchdog_ops orion_wdt_ops = {
 375         .owner = THIS_MODULE,
 376         .start = orion_wdt_start,
 377         .stop = orion_wdt_stop,
 378         .ping = orion_wdt_ping,
 379         .get_timeleft = orion_wdt_get_timeleft,
 380 };
 381 
 382 static irqreturn_t orion_wdt_irq(int irq, void *devid)
 383 {
 384         panic("Watchdog Timeout");
 385         return IRQ_HANDLED;
 386 }
 387 
 388 static irqreturn_t orion_wdt_pre_irq(int irq, void *devid)
 389 {
 390         struct orion_watchdog *dev = devid;
 391 
 392         atomic_io_modify(dev->reg + TIMER_A370_STATUS,
 393                          TIMER1_STATUS_BIT, 0);
 394         watchdog_notify_pretimeout(&dev->wdt);
 395         return IRQ_HANDLED;
 396 }
 397 
 398 /*
 399  * The original devicetree binding for this driver specified only
 400  * one memory resource, so in order to keep DT backwards compatibility
 401  * we try to fallback to a hardcoded register address, if the resource
 402  * is missing from the devicetree.
 403  */
 404 static void __iomem *orion_wdt_ioremap_rstout(struct platform_device *pdev,
 405                                               phys_addr_t internal_regs)
 406 {
 407         struct resource *res;
 408         phys_addr_t rstout;
 409 
 410         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 411         if (res)
 412                 return devm_ioremap(&pdev->dev, res->start,
 413                                     resource_size(res));
 414 
 415         rstout = internal_regs + ORION_RSTOUT_MASK_OFFSET;
 416 
 417         WARN(1, FW_BUG "falling back to hardcoded RSTOUT reg %pa\n", &rstout);
 418         return devm_ioremap(&pdev->dev, rstout, 0x4);
 419 }
 420 
 421 static const struct orion_watchdog_data orion_data = {
 422         .rstout_enable_bit = BIT(1),
 423         .wdt_enable_bit = BIT(4),
 424         .wdt_counter_offset = 0x24,
 425         .clock_init = orion_wdt_clock_init,
 426         .enabled = orion_enabled,
 427         .start = orion_start,
 428         .stop = orion_stop,
 429 };
 430 
 431 static const struct orion_watchdog_data armada370_data = {
 432         .rstout_enable_bit = BIT(8),
 433         .wdt_enable_bit = BIT(8),
 434         .wdt_counter_offset = 0x34,
 435         .clock_init = armada370_wdt_clock_init,
 436         .enabled = orion_enabled,
 437         .start = armada370_start,
 438         .stop = armada370_stop,
 439 };
 440 
 441 static const struct orion_watchdog_data armadaxp_data = {
 442         .rstout_enable_bit = BIT(8),
 443         .wdt_enable_bit = BIT(8),
 444         .wdt_counter_offset = 0x34,
 445         .clock_init = armadaxp_wdt_clock_init,
 446         .enabled = orion_enabled,
 447         .start = armada370_start,
 448         .stop = armada370_stop,
 449 };
 450 
 451 static const struct orion_watchdog_data armada375_data = {
 452         .rstout_enable_bit = BIT(8),
 453         .rstout_mask_bit = BIT(10),
 454         .wdt_enable_bit = BIT(8),
 455         .wdt_counter_offset = 0x34,
 456         .clock_init = armada375_wdt_clock_init,
 457         .enabled = armada375_enabled,
 458         .start = armada375_start,
 459         .stop = armada375_stop,
 460 };
 461 
 462 static const struct orion_watchdog_data armada380_data = {
 463         .rstout_enable_bit = BIT(8),
 464         .rstout_mask_bit = BIT(10),
 465         .wdt_enable_bit = BIT(8),
 466         .wdt_counter_offset = 0x34,
 467         .clock_init = armadaxp_wdt_clock_init,
 468         .enabled = armada375_enabled,
 469         .start = armada375_start,
 470         .stop = armada375_stop,
 471 };
 472 
 473 static const struct of_device_id orion_wdt_of_match_table[] = {
 474         {
 475                 .compatible = "marvell,orion-wdt",
 476                 .data = &orion_data,
 477         },
 478         {
 479                 .compatible = "marvell,armada-370-wdt",
 480                 .data = &armada370_data,
 481         },
 482         {
 483                 .compatible = "marvell,armada-xp-wdt",
 484                 .data = &armadaxp_data,
 485         },
 486         {
 487                 .compatible = "marvell,armada-375-wdt",
 488                 .data = &armada375_data,
 489         },
 490         {
 491                 .compatible = "marvell,armada-380-wdt",
 492                 .data = &armada380_data,
 493         },
 494         {},
 495 };
 496 MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
 497 
 498 static int orion_wdt_get_regs(struct platform_device *pdev,
 499                               struct orion_watchdog *dev)
 500 {
 501         struct device_node *node = pdev->dev.of_node;
 502         struct resource *res;
 503 
 504         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 505         if (!res)
 506                 return -ENODEV;
 507         dev->reg = devm_ioremap(&pdev->dev, res->start,
 508                                 resource_size(res));
 509         if (!dev->reg)
 510                 return -ENOMEM;
 511 
 512         /* Each supported compatible has some RSTOUT register quirk */
 513         if (of_device_is_compatible(node, "marvell,orion-wdt")) {
 514 
 515                 dev->rstout = orion_wdt_ioremap_rstout(pdev, res->start &
 516                                                        INTERNAL_REGS_MASK);
 517                 if (!dev->rstout)
 518                         return -ENODEV;
 519 
 520         } else if (of_device_is_compatible(node, "marvell,armada-370-wdt") ||
 521                    of_device_is_compatible(node, "marvell,armada-xp-wdt")) {
 522 
 523                 /* Dedicated RSTOUT register, can be requested. */
 524                 dev->rstout = devm_platform_ioremap_resource(pdev, 1);
 525                 if (IS_ERR(dev->rstout))
 526                         return PTR_ERR(dev->rstout);
 527 
 528         } else if (of_device_is_compatible(node, "marvell,armada-375-wdt") ||
 529                    of_device_is_compatible(node, "marvell,armada-380-wdt")) {
 530 
 531                 /* Dedicated RSTOUT register, can be requested. */
 532                 dev->rstout = devm_platform_ioremap_resource(pdev, 1);
 533                 if (IS_ERR(dev->rstout))
 534                         return PTR_ERR(dev->rstout);
 535 
 536                 res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
 537                 if (!res)
 538                         return -ENODEV;
 539                 dev->rstout_mask = devm_ioremap(&pdev->dev, res->start,
 540                                                 resource_size(res));
 541                 if (!dev->rstout_mask)
 542                         return -ENOMEM;
 543 
 544         } else {
 545                 return -ENODEV;
 546         }
 547 
 548         return 0;
 549 }
 550 
 551 static int orion_wdt_probe(struct platform_device *pdev)
 552 {
 553         struct orion_watchdog *dev;
 554         const struct of_device_id *match;
 555         unsigned int wdt_max_duration;  /* (seconds) */
 556         int ret, irq;
 557 
 558         dev = devm_kzalloc(&pdev->dev, sizeof(struct orion_watchdog),
 559                            GFP_KERNEL);
 560         if (!dev)
 561                 return -ENOMEM;
 562 
 563         match = of_match_device(orion_wdt_of_match_table, &pdev->dev);
 564         if (!match)
 565                 /* Default legacy match */
 566                 match = &orion_wdt_of_match_table[0];
 567 
 568         dev->wdt.info = &orion_wdt_info;
 569         dev->wdt.ops = &orion_wdt_ops;
 570         dev->wdt.min_timeout = 1;
 571         dev->data = match->data;
 572 
 573         ret = orion_wdt_get_regs(pdev, dev);
 574         if (ret)
 575                 return ret;
 576 
 577         ret = dev->data->clock_init(pdev, dev);
 578         if (ret) {
 579                 dev_err(&pdev->dev, "cannot initialize clock\n");
 580                 return ret;
 581         }
 582 
 583         wdt_max_duration = WDT_MAX_CYCLE_COUNT / dev->clk_rate;
 584 
 585         dev->wdt.timeout = wdt_max_duration;
 586         dev->wdt.max_timeout = wdt_max_duration;
 587         dev->wdt.parent = &pdev->dev;
 588         watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
 589 
 590         platform_set_drvdata(pdev, &dev->wdt);
 591         watchdog_set_drvdata(&dev->wdt, dev);
 592 
 593         /*
 594          * Let's make sure the watchdog is fully stopped, unless it's
 595          * explicitly enabled. This may be the case if the module was
 596          * removed and re-inserted, or if the bootloader explicitly
 597          * set a running watchdog before booting the kernel.
 598          */
 599         if (!orion_wdt_enabled(&dev->wdt))
 600                 orion_wdt_stop(&dev->wdt);
 601         else
 602                 set_bit(WDOG_HW_RUNNING, &dev->wdt.status);
 603 
 604         /* Request the IRQ only after the watchdog is disabled */
 605         irq = platform_get_irq_optional(pdev, 0);
 606         if (irq > 0) {
 607                 /*
 608                  * Not all supported platforms specify an interrupt for the
 609                  * watchdog, so let's make it optional.
 610                  */
 611                 ret = devm_request_irq(&pdev->dev, irq, orion_wdt_irq, 0,
 612                                        pdev->name, dev);
 613                 if (ret < 0) {
 614                         dev_err(&pdev->dev, "failed to request IRQ\n");
 615                         goto disable_clk;
 616                 }
 617         }
 618 
 619         /* Optional 2nd interrupt for pretimeout */
 620         irq = platform_get_irq_optional(pdev, 1);
 621         if (irq > 0) {
 622                 orion_wdt_info.options |= WDIOF_PRETIMEOUT;
 623                 ret = devm_request_irq(&pdev->dev, irq, orion_wdt_pre_irq,
 624                                        0, pdev->name, dev);
 625                 if (ret < 0) {
 626                         dev_err(&pdev->dev, "failed to request IRQ\n");
 627                         goto disable_clk;
 628                 }
 629         }
 630 
 631 
 632         watchdog_set_nowayout(&dev->wdt, nowayout);
 633         ret = watchdog_register_device(&dev->wdt);
 634         if (ret)
 635                 goto disable_clk;
 636 
 637         pr_info("Initial timeout %d sec%s\n",
 638                 dev->wdt.timeout, nowayout ? ", nowayout" : "");
 639         return 0;
 640 
 641 disable_clk:
 642         clk_disable_unprepare(dev->clk);
 643         clk_put(dev->clk);
 644         return ret;
 645 }
 646 
 647 static int orion_wdt_remove(struct platform_device *pdev)
 648 {
 649         struct watchdog_device *wdt_dev = platform_get_drvdata(pdev);
 650         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
 651 
 652         watchdog_unregister_device(wdt_dev);
 653         clk_disable_unprepare(dev->clk);
 654         clk_put(dev->clk);
 655         return 0;
 656 }
 657 
 658 static void orion_wdt_shutdown(struct platform_device *pdev)
 659 {
 660         struct watchdog_device *wdt_dev = platform_get_drvdata(pdev);
 661         orion_wdt_stop(wdt_dev);
 662 }
 663 
 664 static struct platform_driver orion_wdt_driver = {
 665         .probe          = orion_wdt_probe,
 666         .remove         = orion_wdt_remove,
 667         .shutdown       = orion_wdt_shutdown,
 668         .driver         = {
 669                 .name   = "orion_wdt",
 670                 .of_match_table = orion_wdt_of_match_table,
 671         },
 672 };
 673 
 674 module_platform_driver(orion_wdt_driver);
 675 
 676 MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
 677 MODULE_DESCRIPTION("Orion Processor Watchdog");
 678 
 679 module_param(heartbeat, int, 0);
 680 MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
 681 
 682 module_param(nowayout, bool, 0);
 683 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 684                                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 685 
 686 MODULE_LICENSE("GPL v2");
 687 MODULE_ALIAS("platform:orion_wdt");

/* [<][>][^][v][top][bottom][index][help] */