mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
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>
This commit is contained in:
parent
6d53c3b71d
commit
513b032c98
@ -352,10 +352,43 @@ int pps_register_cdev(struct pps_device *pps)
|
||||
|
||||
void pps_unregister_cdev(struct pps_device *pps)
|
||||
{
|
||||
pps->lookup_cookie = NULL;
|
||||
device_destroy(pps_class, pps->dev->devt);
|
||||
cdev_del(&pps->cdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up a pps device by magic cookie.
|
||||
* The cookie is usually a pointer to some enclosing device, but this
|
||||
* code doesn't care; you should never be dereferencing it.
|
||||
*
|
||||
* This is a bit of a kludge that is currently used only by the PPS
|
||||
* serial line discipline. It may need to be tweaked when a second user
|
||||
* is found.
|
||||
*
|
||||
* There is no function interface for setting the lookup_cookie field.
|
||||
* It's initialized to NULL when the pps device is created, and if a
|
||||
* client wants to use it, just fill it in afterward.
|
||||
*
|
||||
* The cookie is automatically set to NULL in pps_unregister_source()
|
||||
* so that it will not be used again, even if the pps device cannot
|
||||
* be removed from the idr due to pending references holding the minor
|
||||
* number in use.
|
||||
*/
|
||||
struct pps_device *pps_lookup_dev(void const *cookie)
|
||||
{
|
||||
struct pps_device *pps;
|
||||
unsigned id;
|
||||
|
||||
rcu_read_lock();
|
||||
idr_for_each_entry(&pps_idr, pps, id)
|
||||
if (cookie == pps->lookup_cookie)
|
||||
break;
|
||||
rcu_read_unlock();
|
||||
return pps;
|
||||
}
|
||||
EXPORT_SYMBOL(pps_lookup_dev);
|
||||
|
||||
/*
|
||||
* Module stuff
|
||||
*/
|
||||
|
@ -43,7 +43,7 @@ struct pps_source_info {
|
||||
int event, void *data); /* PPS echo function */
|
||||
|
||||
struct module *owner;
|
||||
struct device *dev;
|
||||
struct device *dev; /* Parent device for device_create */
|
||||
};
|
||||
|
||||
struct pps_event_time {
|
||||
@ -69,6 +69,7 @@ struct pps_device {
|
||||
wait_queue_head_t queue; /* PPS event queue */
|
||||
|
||||
unsigned int id; /* PPS source unique ID */
|
||||
void const *lookup_cookie; /* pps_lookup_dev only */
|
||||
struct cdev cdev;
|
||||
struct device *dev;
|
||||
struct fasync_struct *async_queue; /* fasync method */
|
||||
@ -81,6 +82,16 @@ struct pps_device {
|
||||
|
||||
extern struct device_attribute pps_attrs[];
|
||||
|
||||
/*
|
||||
* Internal functions.
|
||||
*
|
||||
* These are not actually part of the exported API, but this is a
|
||||
* convenient header file to put them in.
|
||||
*/
|
||||
|
||||
extern int pps_register_cdev(struct pps_device *pps);
|
||||
extern void pps_unregister_cdev(struct pps_device *pps);
|
||||
|
||||
/*
|
||||
* Exported functions
|
||||
*/
|
||||
@ -88,10 +99,10 @@ extern struct device_attribute pps_attrs[];
|
||||
extern struct pps_device *pps_register_source(
|
||||
struct pps_source_info *info, int default_params);
|
||||
extern void pps_unregister_source(struct pps_device *pps);
|
||||
extern int pps_register_cdev(struct pps_device *pps);
|
||||
extern void pps_unregister_cdev(struct pps_device *pps);
|
||||
extern void pps_event(struct pps_device *pps,
|
||||
struct pps_event_time *ts, int event, void *data);
|
||||
/* Look up a pps device by magic cookie */
|
||||
struct pps_device *pps_lookup_dev(void const *cookie);
|
||||
|
||||
static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
|
||||
struct timespec ts)
|
||||
|
Loading…
Reference in New Issue
Block a user