diff options
| author | George Spelvin <linux@horizon.com> | 2013-02-10 04:08:32 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-02-13 12:40:35 -0500 |
| commit | 513b032c98b4b9414aa4e9b4a315cb1bf0380101 (patch) | |
| tree | 3483659abdcc63cb831bf9ded62e981de3ffd5e3 /drivers/pps | |
| parent | 6d53c3b71d32da665dc2742c1e8663741f27d3cd (diff) | |
pps: Add pps_lookup_dev() function
The PPS serial line discipline wants to attach a PPS device to a tty
without changing the tty code to add a struct pps_device * pointer.
Since the number of PPS devices in a typical system is generally very low
(n=1 is by far the most common), it's practical to search the entire list
of allocated pps devices. (We capture the timestamp before the lookup,
so the timing isn't affected.)
It is a bit ugly that this function, which is part of the in-kernel
PPS API, has to be in pps.c as opposed to kapi,c, but that's not
something that affects users.
Signed-off-by: George Spelvin <linux@horizon.com>
Acked-by: Rodolfo Giometti <giometti@enneenne.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pps')
| -rw-r--r-- | drivers/pps/pps.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 2420d5af0583..a70e384262e5 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
| @@ -352,11 +352,44 @@ free_idr: | |||
| 352 | 352 | ||
| 353 | void pps_unregister_cdev(struct pps_device *pps) | 353 | void pps_unregister_cdev(struct pps_device *pps) |
| 354 | { | 354 | { |
| 355 | pps->lookup_cookie = NULL; | ||
| 355 | device_destroy(pps_class, pps->dev->devt); | 356 | device_destroy(pps_class, pps->dev->devt); |
| 356 | cdev_del(&pps->cdev); | 357 | cdev_del(&pps->cdev); |
| 357 | } | 358 | } |
| 358 | 359 | ||
| 359 | /* | 360 | /* |
| 361 | * Look up a pps device by magic cookie. | ||
| 362 | * The cookie is usually a pointer to some enclosing device, but this | ||
| 363 | * code doesn't care; you should never be dereferencing it. | ||
| 364 | * | ||
| 365 | * This is a bit of a kludge that is currently used only by the PPS | ||
| 366 | * serial line discipline. It may need to be tweaked when a second user | ||
| 367 | * is found. | ||
| 368 | * | ||
| 369 | * There is no function interface for setting the lookup_cookie field. | ||
| 370 | * It's initialized to NULL when the pps device is created, and if a | ||
| 371 | * client wants to use it, just fill it in afterward. | ||
| 372 | * | ||
| 373 | * The cookie is automatically set to NULL in pps_unregister_source() | ||
| 374 | * so that it will not be used again, even if the pps device cannot | ||
| 375 | * be removed from the idr due to pending references holding the minor | ||
| 376 | * number in use. | ||
| 377 | */ | ||
| 378 | struct pps_device *pps_lookup_dev(void const *cookie) | ||
| 379 | { | ||
| 380 | struct pps_device *pps; | ||
| 381 | unsigned id; | ||
| 382 | |||
| 383 | rcu_read_lock(); | ||
| 384 | idr_for_each_entry(&pps_idr, pps, id) | ||
| 385 | if (cookie == pps->lookup_cookie) | ||
| 386 | break; | ||
| 387 | rcu_read_unlock(); | ||
| 388 | return pps; | ||
| 389 | } | ||
| 390 | EXPORT_SYMBOL(pps_lookup_dev); | ||
| 391 | |||
| 392 | /* | ||
| 360 | * Module stuff | 393 | * Module stuff |
| 361 | */ | 394 | */ |
| 362 | 395 | ||
