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 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
  54static bool nowayout = WATCHDOG_NOWAYOUT;
  55static int heartbeat;           /* module parameter (seconds) */
  56
  57struct orion_watchdog;
  58
  59struct 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
  71struct 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
  81static 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
  99static 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
 122static 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
 162static 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 frequency 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
 185static 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
 198static 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
 228static 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
 251static 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
 270static 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
 278static 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
 291static 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
 312static 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
 328static 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
 335static 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
 345static 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
 356static 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
 363static 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
 369static struct watchdog_info orion_wdt_info = {
 370        .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 371        .identity = "Orion Watchdog",
 372};
 373
 374static 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
 382static irqreturn_t orion_wdt_irq(int irq, void *devid)
 383{
 384        panic("Watchdog Timeout");
 385        return IRQ_HANDLED;
 386}
 387
 388static 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 */
 404static 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
 421static 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
 431static 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
 441static 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
 451static 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
 462static 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
 473static 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};
 496MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
 497
 498static 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
 551static 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
 641disable_clk:
 642        clk_disable_unprepare(dev->clk);
 643        clk_put(dev->clk);
 644        return ret;
 645}
 646
 647static 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
 658static 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
 664static 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
 674module_platform_driver(orion_wdt_driver);
 675
 676MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
 677MODULE_DESCRIPTION("Orion Processor Watchdog");
 678
 679module_param(heartbeat, int, 0);
 680MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
 681
 682module_param(nowayout, bool, 0);
 683MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 684                                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 685
 686MODULE_LICENSE("GPL v2");
 687MODULE_ALIAS("platform:orion_wdt");
 688