1 /* 2 * watchdog_dev.c 3 * 4 * (c) Copyright 2008-2011 Alan Cox <alan@lxorguk.ukuu.org.uk>, 5 * All Rights Reserved. 6 * 7 * (c) Copyright 2008-2011 Wim Van Sebroeck <wim@iguana.be>. 8 * 9 * 10 * This source code is part of the generic code that can be used 11 * by all the watchdog timer drivers. 12 * 13 * This part of the generic code takes care of the following 14 * misc device: /dev/watchdog. 15 * 16 * Based on source code of the following authors: 17 * Matt Domsch <Matt_Domsch@dell.com>, 18 * Rob Radez <rob@osinvestor.com>, 19 * Rusty Lynch <rusty@linux.co.intel.com> 20 * Satyam Sharma <satyam@infradead.org> 21 * Randy Dunlap <randy.dunlap@oracle.com> 22 * 23 * This program is free software; you can redistribute it and/or 24 * modify it under the terms of the GNU General Public License 25 * as published by the Free Software Foundation; either version 26 * 2 of the License, or (at your option) any later version. 27 * 28 * Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw. 29 * admit liability nor provide warranty for any of this software. 30 * This material is provided "AS-IS" and at no charge. 31 */ 32 33 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 34 35 #include <linux/cdev.h> /* For character device */ 36 #include <linux/errno.h> /* For the -ENODEV/... values */ 37 #include <linux/fs.h> /* For file operations */ 38 #include <linux/init.h> /* For __init/__exit/... */ 39 #include <linux/kernel.h> /* For printk/panic/... */ 40 #include <linux/kref.h> /* For data references */ 41 #include <linux/miscdevice.h> /* For handling misc devices */ 42 #include <linux/module.h> /* For module stuff/... */ 43 #include <linux/mutex.h> /* For mutexes */ 44 #include <linux/slab.h> /* For memory functions */ 45 #include <linux/types.h> /* For standard types (like size_t) */ 46 #include <linux/watchdog.h> /* For watchdog specific items */ 47 #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ 48 49 #include "watchdog_core.h" 50 51 /* 52 * struct watchdog_core_data - watchdog core internal data 53 * @kref: Reference count. 54 * @cdev: The watchdog's Character device. 55 * @wdd: Pointer to watchdog device. 56 * @lock: Lock for watchdog core. 57 * @status: Watchdog core internal status bits. 58 */ 59 struct watchdog_core_data { 60 struct kref kref; 61 struct cdev cdev; 62 struct watchdog_device *wdd; 63 struct mutex lock; 64 unsigned long status; /* Internal status bits */ 65 #define _WDOG_DEV_OPEN 0 /* Opened ? */ 66 #define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */ 67 }; 68 69 /* the dev_t structure to store the dynamically allocated watchdog devices */ 70 static dev_t watchdog_devt; 71 /* Reference to watchdog device behind /dev/watchdog */ 72 static struct watchdog_core_data *old_wd_data; 73 74 /* 75 * watchdog_ping: ping the watchdog. 76 * @wdd: the watchdog device to ping 77 * 78 * The caller must hold wd_data->lock. 79 * 80 * If the watchdog has no own ping operation then it needs to be 81 * restarted via the start operation. This wrapper function does 82 * exactly that. 83 * We only ping when the watchdog device is running. 84 */ 85 86 static int watchdog_ping(struct watchdog_device *wdd) 87 { 88 int err; 89 90 if (!watchdog_active(wdd)) 91 return 0; 92 93 if (wdd->ops->ping) 94 err = wdd->ops->ping(wdd); /* ping the watchdog */ 95 else 96 err = wdd->ops->start(wdd); /* restart watchdog */ 97 98 return err; 99 } 100 101 /* 102 * watchdog_start: wrapper to start the watchdog. 103 * @wdd: the watchdog device to start 104 * 105 * The caller must hold wd_data->lock. 106 * 107 * Start the watchdog if it is not active and mark it active. 108 * This function returns zero on success or a negative errno code for 109 * failure. 110 */ 111 112 static int watchdog_start(struct watchdog_device *wdd) 113 { 114 int err; 115 116 if (watchdog_active(wdd)) 117 return 0; 118 119 err = wdd->ops->start(wdd); 120 if (err == 0) 121 set_bit(WDOG_ACTIVE, &wdd->status); 122 123 return err; 124 } 125 126 /* 127 * watchdog_stop: wrapper to stop the watchdog. 128 * @wdd: the watchdog device to stop 129 * 130 * The caller must hold wd_data->lock. 131 * 132 * Stop the watchdog if it is still active and unmark it active. 133 * This function returns zero on success or a negative errno code for 134 * failure. 135 * If the 'nowayout' feature was set, the watchdog cannot be stopped. 136 */ 137 138 static int watchdog_stop(struct watchdog_device *wdd) 139 { 140 int err; 141 142 if (!watchdog_active(wdd)) 143 return 0; 144 145 if (test_bit(WDOG_NO_WAY_OUT, &wdd->status)) { 146 pr_info("watchdog%d: nowayout prevents watchdog being stopped!\n", 147 wdd->id); 148 return -EBUSY; 149 } 150 151 err = wdd->ops->stop(wdd); 152 if (err == 0) 153 clear_bit(WDOG_ACTIVE, &wdd->status); 154 155 return err; 156 } 157 158 /* 159 * watchdog_get_status: wrapper to get the watchdog status 160 * @wdd: the watchdog device to get the status from 161 * 162 * The caller must hold wd_data->lock. 163 * 164 * Get the watchdog's status flags. 165 */ 166 167 static unsigned int watchdog_get_status(struct watchdog_device *wdd) 168 { 169 if (!wdd->ops->status) 170 return 0; 171 172 return wdd->ops->status(wdd); 173 } 174 175 /* 176 * watchdog_set_timeout: set the watchdog timer timeout 177 * @wdd: the watchdog device to set the timeout for 178 * @timeout: timeout to set in seconds 179 * 180 * The caller must hold wd_data->lock. 181 */ 182 183 static int watchdog_set_timeout(struct watchdog_device *wdd, 184 unsigned int timeout) 185 { 186 int err = 0; 187 188 if (!(wdd->info->options & WDIOF_SETTIMEOUT)) 189 return -EOPNOTSUPP; 190 191 if (watchdog_timeout_invalid(wdd, timeout)) 192 return -EINVAL; 193 194 if (wdd->ops->set_timeout) 195 err = wdd->ops->set_timeout(wdd, timeout); 196 else 197 wdd->timeout = timeout; 198 199 return err; 200 } 201 202 /* 203 * watchdog_get_timeleft: wrapper to get the time left before a reboot 204 * @wdd: the watchdog device to get the remaining time from 205 * @timeleft: the time that's left 206 * 207 * The caller must hold wd_data->lock. 208 * 209 * Get the time before a watchdog will reboot (if not pinged). 210 */ 211 212 static int watchdog_get_timeleft(struct watchdog_device *wdd, 213 unsigned int *timeleft) 214 { 215 *timeleft = 0; 216 217 if (!wdd->ops->get_timeleft) 218 return -EOPNOTSUPP; 219 220 *timeleft = wdd->ops->get_timeleft(wdd); 221 222 return 0; 223 } 224 225 #ifdef CONFIG_WATCHDOG_SYSFS 226 static ssize_t nowayout_show(struct device *dev, struct device_attribute *attr, 227 char *buf) 228 { 229 struct watchdog_device *wdd = dev_get_drvdata(dev); 230 231 return sprintf(buf, "%d\n", !!test_bit(WDOG_NO_WAY_OUT, &wdd->status)); 232 } 233 static DEVICE_ATTR_RO(nowayout); 234 235 static ssize_t status_show(struct device *dev, struct device_attribute *attr, 236 char *buf) 237 { 238 struct watchdog_device *wdd = dev_get_drvdata(dev); 239 struct watchdog_core_data *wd_data = wdd->wd_data; 240 unsigned int status; 241 242 mutex_lock(&wd_data->lock); 243 status = watchdog_get_status(wdd); 244 mutex_unlock(&wd_data->lock); 245 246 return sprintf(buf, "%u\n", status); 247 } 248 static DEVICE_ATTR_RO(status); 249 250 static ssize_t bootstatus_show(struct device *dev, 251 struct device_attribute *attr, char *buf) 252 { 253 struct watchdog_device *wdd = dev_get_drvdata(dev); 254 255 return sprintf(buf, "%u\n", wdd->bootstatus); 256 } 257 static DEVICE_ATTR_RO(bootstatus); 258 259 static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr, 260 char *buf) 261 { 262 struct watchdog_device *wdd = dev_get_drvdata(dev); 263 struct watchdog_core_data *wd_data = wdd->wd_data; 264 ssize_t status; 265 unsigned int val; 266 267 mutex_lock(&wd_data->lock); 268 status = watchdog_get_timeleft(wdd, &val); 269 mutex_unlock(&wd_data->lock); 270 if (!status) 271 status = sprintf(buf, "%u\n", val); 272 273 return status; 274 } 275 static DEVICE_ATTR_RO(timeleft); 276 277 static ssize_t timeout_show(struct device *dev, struct device_attribute *attr, 278 char *buf) 279 { 280 struct watchdog_device *wdd = dev_get_drvdata(dev); 281 282 return sprintf(buf, "%u\n", wdd->timeout); 283 } 284 static DEVICE_ATTR_RO(timeout); 285 286 static ssize_t identity_show(struct device *dev, struct device_attribute *attr, 287 char *buf) 288 { 289 struct watchdog_device *wdd = dev_get_drvdata(dev); 290 291 return sprintf(buf, "%s\n", wdd->info->identity); 292 } 293 static DEVICE_ATTR_RO(identity); 294 295 static ssize_t state_show(struct device *dev, struct device_attribute *attr, 296 char *buf) 297 { 298 struct watchdog_device *wdd = dev_get_drvdata(dev); 299 300 if (watchdog_active(wdd)) 301 return sprintf(buf, "active\n"); 302 303 return sprintf(buf, "inactive\n"); 304 } 305 static DEVICE_ATTR_RO(state); 306 307 static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr, 308 int n) 309 { 310 struct device *dev = container_of(kobj, struct device, kobj); 311 struct watchdog_device *wdd = dev_get_drvdata(dev); 312 umode_t mode = attr->mode; 313 314 if (attr == &dev_attr_status.attr && !wdd->ops->status) 315 mode = 0; 316 else if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft) 317 mode = 0; 318 319 return mode; 320 } 321 static struct attribute *wdt_attrs[] = { 322 &dev_attr_state.attr, 323 &dev_attr_identity.attr, 324 &dev_attr_timeout.attr, 325 &dev_attr_timeleft.attr, 326 &dev_attr_bootstatus.attr, 327 &dev_attr_status.attr, 328 &dev_attr_nowayout.attr, 329 NULL, 330 }; 331 332 static const struct attribute_group wdt_group = { 333 .attrs = wdt_attrs, 334 .is_visible = wdt_is_visible, 335 }; 336 __ATTRIBUTE_GROUPS(wdt); 337 #else 338 #define wdt_groups NULL 339 #endif 340 341 /* 342 * watchdog_ioctl_op: call the watchdog drivers ioctl op if defined 343 * @wdd: the watchdog device to do the ioctl on 344 * @cmd: watchdog command 345 * @arg: argument pointer 346 * 347 * The caller must hold wd_data->lock. 348 */ 349 350 static int watchdog_ioctl_op(struct watchdog_device *wdd, unsigned int cmd, 351 unsigned long arg) 352 { 353 if (!wdd->ops->ioctl) 354 return -ENOIOCTLCMD; 355 356 return wdd->ops->ioctl(wdd, cmd, arg); 357 } 358 359 /* 360 * watchdog_write: writes to the watchdog. 361 * @file: file from VFS 362 * @data: user address of data 363 * @len: length of data 364 * @ppos: pointer to the file offset 365 * 366 * A write to a watchdog device is defined as a keepalive ping. 367 * Writing the magic 'V' sequence allows the next close to turn 368 * off the watchdog (if 'nowayout' is not set). 369 */ 370 371 static ssize_t watchdog_write(struct file *file, const char __user *data, 372 size_t len, loff_t *ppos) 373 { 374 struct watchdog_core_data *wd_data = file->private_data; 375 struct watchdog_device *wdd; 376 int err; 377 size_t i; 378 char c; 379 380 if (len == 0) 381 return 0; 382 383 /* 384 * Note: just in case someone wrote the magic character 385 * five months ago... 386 */ 387 clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status); 388 389 /* scan to see whether or not we got the magic character */ 390 for (i = 0; i != len; i++) { 391 if (get_user(c, data + i)) 392 return -EFAULT; 393 if (c == 'V') 394 set_bit(_WDOG_ALLOW_RELEASE, &wd_data->status); 395 } 396 397 /* someone wrote to us, so we send the watchdog a keepalive ping */ 398 399 err = -ENODEV; 400 mutex_lock(&wd_data->lock); 401 wdd = wd_data->wdd; 402 if (wdd) 403 err = watchdog_ping(wdd); 404 mutex_unlock(&wd_data->lock); 405 406 if (err < 0) 407 return err; 408 409 return len; 410 } 411 412 /* 413 * watchdog_ioctl: handle the different ioctl's for the watchdog device. 414 * @file: file handle to the device 415 * @cmd: watchdog command 416 * @arg: argument pointer 417 * 418 * The watchdog API defines a common set of functions for all watchdogs 419 * according to their available features. 420 */ 421 422 static long watchdog_ioctl(struct file *file, unsigned int cmd, 423 unsigned long arg) 424 { 425 struct watchdog_core_data *wd_data = file->private_data; 426 void __user *argp = (void __user *)arg; 427 struct watchdog_device *wdd; 428 int __user *p = argp; 429 unsigned int val; 430 int err; 431 432 mutex_lock(&wd_data->lock); 433 434 wdd = wd_data->wdd; 435 if (!wdd) { 436 err = -ENODEV; 437 goto out_ioctl; 438 } 439 440 err = watchdog_ioctl_op(wdd, cmd, arg); 441 if (err != -ENOIOCTLCMD) 442 goto out_ioctl; 443 444 switch (cmd) { 445 case WDIOC_GETSUPPORT: 446 err = copy_to_user(argp, wdd->info, 447 sizeof(struct watchdog_info)) ? -EFAULT : 0; 448 break; 449 case WDIOC_GETSTATUS: 450 val = watchdog_get_status(wdd); 451 err = put_user(val, p); 452 break; 453 case WDIOC_GETBOOTSTATUS: 454 err = put_user(wdd->bootstatus, p); 455 break; 456 case WDIOC_SETOPTIONS: 457 if (get_user(val, p)) { 458 err = -EFAULT; 459 break; 460 } 461 if (val & WDIOS_DISABLECARD) { 462 err = watchdog_stop(wdd); 463 if (err < 0) 464 break; 465 } 466 if (val & WDIOS_ENABLECARD) 467 err = watchdog_start(wdd); 468 break; 469 case WDIOC_KEEPALIVE: 470 if (!(wdd->info->options & WDIOF_KEEPALIVEPING)) { 471 err = -EOPNOTSUPP; 472 break; 473 } 474 err = watchdog_ping(wdd); 475 break; 476 case WDIOC_SETTIMEOUT: 477 if (get_user(val, p)) { 478 err = -EFAULT; 479 break; 480 } 481 err = watchdog_set_timeout(wdd, val); 482 if (err < 0) 483 break; 484 /* If the watchdog is active then we send a keepalive ping 485 * to make sure that the watchdog keep's running (and if 486 * possible that it takes the new timeout) */ 487 err = watchdog_ping(wdd); 488 if (err < 0) 489 break; 490 /* Fall */ 491 case WDIOC_GETTIMEOUT: 492 /* timeout == 0 means that we don't know the timeout */ 493 if (wdd->timeout == 0) { 494 err = -EOPNOTSUPP; 495 break; 496 } 497 err = put_user(wdd->timeout, p); 498 break; 499 case WDIOC_GETTIMELEFT: 500 err = watchdog_get_timeleft(wdd, &val); 501 if (err < 0) 502 break; 503 err = put_user(val, p); 504 break; 505 default: 506 err = -ENOTTY; 507 break; 508 } 509 510 out_ioctl: 511 mutex_unlock(&wd_data->lock); 512 return err; 513 } 514 515 /* 516 * watchdog_open: open the /dev/watchdog* devices. 517 * @inode: inode of device 518 * @file: file handle to device 519 * 520 * When the /dev/watchdog* device gets opened, we start the watchdog. 521 * Watch out: the /dev/watchdog device is single open, so we make sure 522 * it can only be opened once. 523 */ 524 525 static int watchdog_open(struct inode *inode, struct file *file) 526 { 527 struct watchdog_core_data *wd_data; 528 struct watchdog_device *wdd; 529 int err; 530 531 /* Get the corresponding watchdog device */ 532 if (imajor(inode) == MISC_MAJOR) 533 wd_data = old_wd_data; 534 else 535 wd_data = container_of(inode->i_cdev, struct watchdog_core_data, 536 cdev); 537 538 /* the watchdog is single open! */ 539 if (test_and_set_bit(_WDOG_DEV_OPEN, &wd_data->status)) 540 return -EBUSY; 541 542 wdd = wd_data->wdd; 543 544 /* 545 * If the /dev/watchdog device is open, we don't want the module 546 * to be unloaded. 547 */ 548 if (!try_module_get(wdd->ops->owner)) { 549 err = -EBUSY; 550 goto out_clear; 551 } 552 553 err = watchdog_start(wdd); 554 if (err < 0) 555 goto out_mod; 556 557 file->private_data = wd_data; 558 559 kref_get(&wd_data->kref); 560 561 /* dev/watchdog is a virtual (and thus non-seekable) filesystem */ 562 return nonseekable_open(inode, file); 563 564 out_mod: 565 module_put(wd_data->wdd->ops->owner); 566 out_clear: 567 clear_bit(_WDOG_DEV_OPEN, &wd_data->status); 568 return err; 569 } 570 571 static void watchdog_core_data_release(struct kref *kref) 572 { 573 struct watchdog_core_data *wd_data; 574 575 wd_data = container_of(kref, struct watchdog_core_data, kref); 576 577 kfree(wd_data); 578 } 579 580 /* 581 * watchdog_release: release the watchdog device. 582 * @inode: inode of device 583 * @file: file handle to device 584 * 585 * This is the code for when /dev/watchdog gets closed. We will only 586 * stop the watchdog when we have received the magic char (and nowayout 587 * was not set), else the watchdog will keep running. 588 */ 589 590 static int watchdog_release(struct inode *inode, struct file *file) 591 { 592 struct watchdog_core_data *wd_data = file->private_data; 593 struct watchdog_device *wdd; 594 int err = -EBUSY; 595 596 mutex_lock(&wd_data->lock); 597 598 wdd = wd_data->wdd; 599 if (!wdd) 600 goto done; 601 602 /* 603 * We only stop the watchdog if we received the magic character 604 * or if WDIOF_MAGICCLOSE is not set. If nowayout was set then 605 * watchdog_stop will fail. 606 */ 607 if (!test_bit(WDOG_ACTIVE, &wdd->status)) 608 err = 0; 609 else if (test_and_clear_bit(_WDOG_ALLOW_RELEASE, &wd_data->status) || 610 !(wdd->info->options & WDIOF_MAGICCLOSE)) 611 err = watchdog_stop(wdd); 612 613 /* If the watchdog was not stopped, send a keepalive ping */ 614 if (err < 0) { 615 pr_crit("watchdog%d: watchdog did not stop!\n", wdd->id); 616 watchdog_ping(wdd); 617 } 618 619 /* make sure that /dev/watchdog can be re-opened */ 620 clear_bit(_WDOG_DEV_OPEN, &wd_data->status); 621 622 done: 623 mutex_unlock(&wd_data->lock); 624 /* Allow the owner module to be unloaded again */ 625 module_put(wd_data->cdev.owner); 626 kref_put(&wd_data->kref, watchdog_core_data_release); 627 return 0; 628 } 629 630 static const struct file_operations watchdog_fops = { 631 .owner = THIS_MODULE, 632 .write = watchdog_write, 633 .unlocked_ioctl = watchdog_ioctl, 634 .open = watchdog_open, 635 .release = watchdog_release, 636 }; 637 638 static struct miscdevice watchdog_miscdev = { 639 .minor = WATCHDOG_MINOR, 640 .name = "watchdog", 641 .fops = &watchdog_fops, 642 }; 643 644 /* 645 * watchdog_cdev_register: register watchdog character device 646 * @wdd: watchdog device 647 * @devno: character device number 648 * 649 * Register a watchdog character device including handling the legacy 650 * /dev/watchdog node. /dev/watchdog is actually a miscdevice and 651 * thus we set it up like that. 652 */ 653 654 static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno) 655 { 656 struct watchdog_core_data *wd_data; 657 int err; 658 659 wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL); 660 if (!wd_data) 661 return -ENOMEM; 662 kref_init(&wd_data->kref); 663 mutex_init(&wd_data->lock); 664 665 wd_data->wdd = wdd; 666 wdd->wd_data = wd_data; 667 668 if (wdd->id == 0) { 669 old_wd_data = wd_data; 670 watchdog_miscdev.parent = wdd->parent; 671 err = misc_register(&watchdog_miscdev); 672 if (err != 0) { 673 pr_err("%s: cannot register miscdev on minor=%d (err=%d).\n", 674 wdd->info->identity, WATCHDOG_MINOR, err); 675 if (err == -EBUSY) 676 pr_err("%s: a legacy watchdog module is probably present.\n", 677 wdd->info->identity); 678 old_wd_data = NULL; 679 kfree(wd_data); 680 return err; 681 } 682 } 683 684 /* Fill in the data structures */ 685 cdev_init(&wd_data->cdev, &watchdog_fops); 686 wd_data->cdev.owner = wdd->ops->owner; 687 688 /* Add the device */ 689 err = cdev_add(&wd_data->cdev, devno, 1); 690 if (err) { 691 pr_err("watchdog%d unable to add device %d:%d\n", 692 wdd->id, MAJOR(watchdog_devt), wdd->id); 693 if (wdd->id == 0) { 694 misc_deregister(&watchdog_miscdev); 695 old_wd_data = NULL; 696 kref_put(&wd_data->kref, watchdog_core_data_release); 697 } 698 } 699 return err; 700 } 701 702 /* 703 * watchdog_cdev_unregister: unregister watchdog character device 704 * @watchdog: watchdog device 705 * 706 * Unregister watchdog character device and if needed the legacy 707 * /dev/watchdog device. 708 */ 709 710 static void watchdog_cdev_unregister(struct watchdog_device *wdd) 711 { 712 struct watchdog_core_data *wd_data = wdd->wd_data; 713 714 cdev_del(&wd_data->cdev); 715 if (wdd->id == 0) { 716 misc_deregister(&watchdog_miscdev); 717 old_wd_data = NULL; 718 } 719 720 mutex_lock(&wd_data->lock); 721 wd_data->wdd = NULL; 722 wdd->wd_data = NULL; 723 mutex_unlock(&wd_data->lock); 724 725 kref_put(&wd_data->kref, watchdog_core_data_release); 726 } 727 728 static struct class watchdog_class = { 729 .name = "watchdog", 730 .owner = THIS_MODULE, 731 .dev_groups = wdt_groups, 732 }; 733 734 /* 735 * watchdog_dev_register: register a watchdog device 736 * @wdd: watchdog device 737 * 738 * Register a watchdog device including handling the legacy 739 * /dev/watchdog node. /dev/watchdog is actually a miscdevice and 740 * thus we set it up like that. 741 */ 742 743 int watchdog_dev_register(struct watchdog_device *wdd) 744 { 745 struct device *dev; 746 dev_t devno; 747 int ret; 748 749 devno = MKDEV(MAJOR(watchdog_devt), wdd->id); 750 751 ret = watchdog_cdev_register(wdd, devno); 752 if (ret) 753 return ret; 754 755 dev = device_create_with_groups(&watchdog_class, wdd->parent, 756 devno, wdd, wdd->groups, 757 "watchdog%d", wdd->id); 758 if (IS_ERR(dev)) { 759 watchdog_cdev_unregister(wdd); 760 return PTR_ERR(dev); 761 } 762 763 return ret; 764 } 765 766 /* 767 * watchdog_dev_unregister: unregister a watchdog device 768 * @watchdog: watchdog device 769 * 770 * Unregister watchdog device and if needed the legacy 771 * /dev/watchdog device. 772 */ 773 774 void watchdog_dev_unregister(struct watchdog_device *wdd) 775 { 776 device_destroy(&watchdog_class, wdd->wd_data->cdev.dev); 777 watchdog_cdev_unregister(wdd); 778 } 779 780 /* 781 * watchdog_dev_init: init dev part of watchdog core 782 * 783 * Allocate a range of chardev nodes to use for watchdog devices 784 */ 785 786 int __init watchdog_dev_init(void) 787 { 788 int err; 789 790 err = class_register(&watchdog_class); 791 if (err < 0) { 792 pr_err("couldn't register class\n"); 793 return err; 794 } 795 796 err = alloc_chrdev_region(&watchdog_devt, 0, MAX_DOGS, "watchdog"); 797 if (err < 0) { 798 pr_err("watchdog: unable to allocate char dev region\n"); 799 class_unregister(&watchdog_class); 800 return err; 801 } 802 803 return 0; 804 } 805 806 /* 807 * watchdog_dev_exit: exit dev part of watchdog core 808 * 809 * Release the range of chardev nodes used for watchdog devices 810 */ 811 812 void __exit watchdog_dev_exit(void) 813 { 814 unregister_chrdev_region(watchdog_devt, MAX_DOGS); 815 class_unregister(&watchdog_class); 816 } 817