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