Skip to content

Commit 513b032

Browse files
George Spelvingregkh
George Spelvin
authored andcommitted
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>
1 parent 6d53c3b commit 513b032

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

drivers/pps/pps.c

+33
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,43 @@ int pps_register_cdev(struct pps_device *pps)
352352

353353
void pps_unregister_cdev(struct pps_device *pps)
354354
{
355+
pps->lookup_cookie = NULL;
355356
device_destroy(pps_class, pps->dev->devt);
356357
cdev_del(&pps->cdev);
357358
}
358359

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+
359392
/*
360393
* Module stuff
361394
*/

include/linux/pps_kernel.h

+14-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct pps_source_info {
4343
int event, void *data); /* PPS echo function */
4444

4545
struct module *owner;
46-
struct device *dev;
46+
struct device *dev; /* Parent device for device_create */
4747
};
4848

4949
struct pps_event_time {
@@ -69,6 +69,7 @@ struct pps_device {
6969
wait_queue_head_t queue; /* PPS event queue */
7070

7171
unsigned int id; /* PPS source unique ID */
72+
void const *lookup_cookie; /* pps_lookup_dev only */
7273
struct cdev cdev;
7374
struct device *dev;
7475
struct fasync_struct *async_queue; /* fasync method */
@@ -81,17 +82,27 @@ struct pps_device {
8182

8283
extern struct device_attribute pps_attrs[];
8384

85+
/*
86+
* Internal functions.
87+
*
88+
* These are not actually part of the exported API, but this is a
89+
* convenient header file to put them in.
90+
*/
91+
92+
extern int pps_register_cdev(struct pps_device *pps);
93+
extern void pps_unregister_cdev(struct pps_device *pps);
94+
8495
/*
8596
* Exported functions
8697
*/
8798

8899
extern struct pps_device *pps_register_source(
89100
struct pps_source_info *info, int default_params);
90101
extern void pps_unregister_source(struct pps_device *pps);
91-
extern int pps_register_cdev(struct pps_device *pps);
92-
extern void pps_unregister_cdev(struct pps_device *pps);
93102
extern void pps_event(struct pps_device *pps,
94103
struct pps_event_time *ts, int event, void *data);
104+
/* Look up a pps device by magic cookie */
105+
struct pps_device *pps_lookup_dev(void const *cookie);
95106

96107
static inline void timespec_to_pps_ktime(struct pps_ktime *kt,
97108
struct timespec ts)

0 commit comments

Comments
 (0)