Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
watchdog
watchdog_core.c
Go to the documentation of this file.
1
/*
2
* watchdog_core.c
3
*
4
* (c) Copyright 2008-2011 Alan Cox <
[email protected]
>,
5
* All Rights Reserved.
6
*
7
* (c) Copyright 2008-2011 Wim Van Sebroeck <
[email protected]
>.
8
*
9
* This source code is part of the generic code that can be used
10
* by all the watchdog timer drivers.
11
*
12
* Based on source code of the following authors:
13
* Matt Domsch <
[email protected]
>,
14
* Rob Radez <
[email protected]
>,
15
* Rusty Lynch <
[email protected]
>
16
* Satyam Sharma <
[email protected]
>
17
* Randy Dunlap <
[email protected]
>
18
*
19
* This program is free software; you can redistribute it and/or
20
* modify it under the terms of the GNU General Public License
21
* as published by the Free Software Foundation; either version
22
* 2 of the License, or (at your option) any later version.
23
*
24
* Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
25
* admit liability nor provide warranty for any of this software.
26
* This material is provided "AS-IS" and at no charge.
27
*/
28
29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30
31
#include <linux/module.h>
/* For EXPORT_SYMBOL/module stuff/... */
32
#include <linux/types.h>
/* For standard types */
33
#include <linux/errno.h>
/* For the -ENODEV/... values */
34
#include <linux/kernel.h>
/* For printk/panic/... */
35
#include <linux/watchdog.h>
/* For watchdog specific items */
36
#include <
linux/init.h
>
/* For __init/__exit/... */
37
#include <
linux/idr.h
>
/* For ida_* macros */
38
#include <
linux/err.h
>
/* For IS_ERR macros */
39
40
#include "
watchdog_core.h
"
/* For watchdog_dev_register/... */
41
42
static
DEFINE_IDA
(watchdog_ida);
43
static
struct
class
*watchdog_class;
44
55
int
watchdog_register_device
(
struct
watchdog_device
*wdd)
56
{
57
int
ret
,
id
,
devno
;
58
59
if
(wdd ==
NULL
|| wdd->
info
==
NULL
|| wdd->
ops
==
NULL
)
60
return
-
EINVAL
;
61
62
/* Mandatory operations need to be supported */
63
if
(wdd->
ops
->start ==
NULL
|| wdd->
ops
->stop ==
NULL
)
64
return
-
EINVAL
;
65
66
/*
67
* Check that we have valid min and max timeout values, if
68
* not reset them both to 0 (=not used or unknown)
69
*/
70
if
(wdd->
min_timeout
> wdd->
max_timeout
) {
71
pr_info
(
"Invalid min and max timeout values, resetting to 0!\n"
);
72
wdd->
min_timeout
= 0;
73
wdd->
max_timeout
= 0;
74
}
75
76
/*
77
* Note: now that all watchdog_device data has been verified, we
78
* will not check this anymore in other functions. If data gets
79
* corrupted in a later stage then we expect a kernel panic!
80
*/
81
82
mutex_init
(&wdd->
lock
);
83
id
=
ida_simple_get
(&watchdog_ida, 0,
MAX_DOGS
,
GFP_KERNEL
);
84
if
(
id
< 0)
85
return
id
;
86
wdd->
id
=
id
;
87
88
ret =
watchdog_dev_register
(wdd);
89
if
(ret) {
90
ida_simple_remove
(&watchdog_ida,
id
);
91
if
(!(
id
== 0 && ret == -
EBUSY
))
92
return
ret
;
93
94
/* Retry in case a legacy watchdog module exists */
95
id
=
ida_simple_get
(&watchdog_ida, 1,
MAX_DOGS
,
GFP_KERNEL
);
96
if
(
id
< 0)
97
return
id
;
98
wdd->
id
=
id
;
99
100
ret =
watchdog_dev_register
(wdd);
101
if
(ret) {
102
ida_simple_remove
(&watchdog_ida,
id
);
103
return
ret
;
104
}
105
}
106
107
devno = wdd->
cdev
.dev;
108
wdd->
dev
=
device_create
(watchdog_class, wdd->
parent
, devno,
109
NULL
,
"watchdog%d"
, wdd->
id
);
110
if
(IS_ERR(wdd->
dev
)) {
111
watchdog_dev_unregister
(wdd);
112
ida_simple_remove
(&watchdog_ida,
id
);
113
ret = PTR_ERR(wdd->
dev
);
114
return
ret
;
115
}
116
117
return
0;
118
}
119
EXPORT_SYMBOL_GPL
(
watchdog_register_device
);
120
128
void
watchdog_unregister_device
(
struct
watchdog_device
*wdd)
129
{
130
int
ret
;
131
int
devno
;
132
133
if
(wdd ==
NULL
)
134
return
;
135
136
devno = wdd->
cdev
.dev;
137
ret =
watchdog_dev_unregister
(wdd);
138
if
(ret)
139
pr_err
(
"error unregistering /dev/watchdog (err=%d)\n"
, ret);
140
device_destroy
(watchdog_class, devno);
141
ida_simple_remove
(&watchdog_ida, wdd->
id
);
142
wdd->
dev
=
NULL
;
143
}
144
EXPORT_SYMBOL_GPL
(
watchdog_unregister_device
);
145
146
static
int
__init
watchdog_init(
void
)
147
{
148
int
err
;
149
150
watchdog_class =
class_create
(
THIS_MODULE
,
"watchdog"
);
151
if
(IS_ERR(watchdog_class)) {
152
pr_err
(
"couldn't create class\n"
);
153
return
PTR_ERR(watchdog_class);
154
}
155
156
err =
watchdog_dev_init
();
157
if
(err < 0) {
158
class_destroy
(watchdog_class);
159
return
err
;
160
}
161
162
return
0;
163
}
164
165
static
void
__exit
watchdog_exit(
void
)
166
{
167
watchdog_dev_exit
();
168
class_destroy
(watchdog_class);
169
ida_destroy
(&watchdog_ida);
170
}
171
172
subsys_initcall
(watchdog_init);
173
module_exit
(watchdog_exit);
174
175
MODULE_AUTHOR
(
"Alan Cox <
[email protected]
>"
);
176
MODULE_AUTHOR
(
"Wim Van Sebroeck <
[email protected]
>"
);
177
MODULE_DESCRIPTION
(
"WatchDog Timer Driver Core"
);
178
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 14:43:21 for Linux Kernel by
1.8.2