diff options
author | Richard Cochran <richardcochran@gmail.com> | 2014-03-20 17:21:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-21 14:21:13 -0400 |
commit | 6092315dfdec5185881605d15a0e200d6e90eb66 (patch) | |
tree | 8b018970396a2e2380fe51ed14d2f860ce6010e1 /drivers/ptp/ptp_clock.c | |
parent | a85ae0e97879f51bccd8511668b07d346d98b3eb (diff) |
ptp: introduce programmable pins.
This patch adds a pair of new ioctls to the PTP Hardware Clock device
interface. Using the ioctls, user space programs can query each pin to
find out its current function and also reprogram a different function
if desired.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ptp/ptp_clock.c')
-rw-r--r-- | drivers/ptp/ptp_clock.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index a8319b266643..e25d2bc898e5 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c | |||
@@ -169,6 +169,7 @@ static void delete_ptp_clock(struct posix_clock *pc) | |||
169 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); | 169 | struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); |
170 | 170 | ||
171 | mutex_destroy(&ptp->tsevq_mux); | 171 | mutex_destroy(&ptp->tsevq_mux); |
172 | mutex_destroy(&ptp->pincfg_mux); | ||
172 | ida_simple_remove(&ptp_clocks_map, ptp->index); | 173 | ida_simple_remove(&ptp_clocks_map, ptp->index); |
173 | kfree(ptp); | 174 | kfree(ptp); |
174 | } | 175 | } |
@@ -203,6 +204,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, | |||
203 | ptp->index = index; | 204 | ptp->index = index; |
204 | spin_lock_init(&ptp->tsevq.lock); | 205 | spin_lock_init(&ptp->tsevq.lock); |
205 | mutex_init(&ptp->tsevq_mux); | 206 | mutex_init(&ptp->tsevq_mux); |
207 | mutex_init(&ptp->pincfg_mux); | ||
206 | init_waitqueue_head(&ptp->tsev_wq); | 208 | init_waitqueue_head(&ptp->tsev_wq); |
207 | 209 | ||
208 | /* Create a new device in our class. */ | 210 | /* Create a new device in our class. */ |
@@ -249,6 +251,7 @@ no_sysfs: | |||
249 | device_destroy(ptp_class, ptp->devid); | 251 | device_destroy(ptp_class, ptp->devid); |
250 | no_device: | 252 | no_device: |
251 | mutex_destroy(&ptp->tsevq_mux); | 253 | mutex_destroy(&ptp->tsevq_mux); |
254 | mutex_destroy(&ptp->pincfg_mux); | ||
252 | no_slot: | 255 | no_slot: |
253 | kfree(ptp); | 256 | kfree(ptp); |
254 | no_memory: | 257 | no_memory: |
@@ -305,6 +308,26 @@ int ptp_clock_index(struct ptp_clock *ptp) | |||
305 | } | 308 | } |
306 | EXPORT_SYMBOL(ptp_clock_index); | 309 | EXPORT_SYMBOL(ptp_clock_index); |
307 | 310 | ||
311 | int ptp_find_pin(struct ptp_clock *ptp, | ||
312 | enum ptp_pin_function func, unsigned int chan) | ||
313 | { | ||
314 | struct ptp_pin_desc *pin = NULL; | ||
315 | int i; | ||
316 | |||
317 | mutex_lock(&ptp->pincfg_mux); | ||
318 | for (i = 0; i < ptp->info->n_pins; i++) { | ||
319 | if (ptp->info->pin_config[i].func == func && | ||
320 | ptp->info->pin_config[i].chan == chan) { | ||
321 | pin = &ptp->info->pin_config[i]; | ||
322 | break; | ||
323 | } | ||
324 | } | ||
325 | mutex_unlock(&ptp->pincfg_mux); | ||
326 | |||
327 | return pin ? i : -1; | ||
328 | } | ||
329 | EXPORT_SYMBOL(ptp_find_pin); | ||
330 | |||
308 | /* module operations */ | 331 | /* module operations */ |
309 | 332 | ||
310 | static void __exit ptp_exit(void) | 333 | static void __exit ptp_exit(void) |