diff options
author | Alexander Gordeev <lasaine@lvk.cs.msu.su> | 2011-01-12 20:00:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 11:03:21 -0500 |
commit | 717c033669ed3ceaee8df57d4562fafcc1a6267a (patch) | |
tree | 892e922c08b5f5eee8fbe7c8e0fdc774db660c67 /drivers/pps/pps.c | |
parent | e2c18e49a0d4f822ffc29fb4958943beb1ff08b7 (diff) |
pps: add kernel consumer support
Add an optional feature of PPSAPI, kernel consumer support, which uses the
added hardpps() function.
Signed-off-by: Alexander Gordeev <lasaine@lvk.cs.msu.su>
Acked-by: Rodolfo Giometti <giometti@linux.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/pps/pps.c')
-rw-r--r-- | drivers/pps/pps.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 9e15cf1da946..2baadd21b7a6 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/pps_kernel.h> | 33 | #include <linux/pps_kernel.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | 35 | ||
36 | #include "kc.h" | ||
37 | |||
36 | /* | 38 | /* |
37 | * Local variables | 39 | * Local variables |
38 | */ | 40 | */ |
@@ -198,9 +200,43 @@ static long pps_cdev_ioctl(struct file *file, | |||
198 | 200 | ||
199 | break; | 201 | break; |
200 | } | 202 | } |
203 | case PPS_KC_BIND: { | ||
204 | struct pps_bind_args bind_args; | ||
205 | |||
206 | dev_dbg(pps->dev, "PPS_KC_BIND\n"); | ||
207 | |||
208 | /* Check the capabilities */ | ||
209 | if (!capable(CAP_SYS_TIME)) | ||
210 | return -EPERM; | ||
211 | |||
212 | if (copy_from_user(&bind_args, uarg, | ||
213 | sizeof(struct pps_bind_args))) | ||
214 | return -EFAULT; | ||
215 | |||
216 | /* Check for supported capabilities */ | ||
217 | if ((bind_args.edge & ~pps->info.mode) != 0) { | ||
218 | dev_err(pps->dev, "unsupported capabilities (%x)\n", | ||
219 | bind_args.edge); | ||
220 | return -EINVAL; | ||
221 | } | ||
222 | |||
223 | /* Validate parameters roughly */ | ||
224 | if (bind_args.tsformat != PPS_TSFMT_TSPEC || | ||
225 | (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 || | ||
226 | bind_args.consumer != PPS_KC_HARDPPS) { | ||
227 | dev_err(pps->dev, "invalid kernel consumer bind" | ||
228 | " parameters (%x)\n", bind_args.edge); | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | err = pps_kc_bind(pps, &bind_args); | ||
233 | if (err < 0) | ||
234 | return err; | ||
235 | |||
236 | break; | ||
237 | } | ||
201 | default: | 238 | default: |
202 | return -ENOTTY; | 239 | return -ENOTTY; |
203 | break; | ||
204 | } | 240 | } |
205 | 241 | ||
206 | return 0; | 242 | return 0; |