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