aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/fw-cdev.c26
-rw-r--r--include/linux/firewire-cdev.h15
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index b960fd99691..290d9f03619 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -25,11 +25,14 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
27#include <linux/poll.h> 27#include <linux/poll.h>
28#include <linux/preempt.h>
29#include <linux/time.h>
28#include <linux/delay.h> 30#include <linux/delay.h>
29#include <linux/mm.h> 31#include <linux/mm.h>
30#include <linux/idr.h> 32#include <linux/idr.h>
31#include <linux/compat.h> 33#include <linux/compat.h>
32#include <linux/firewire-cdev.h> 34#include <linux/firewire-cdev.h>
35#include <asm/system.h>
33#include <asm/uaccess.h> 36#include <asm/uaccess.h>
34#include "fw-transaction.h" 37#include "fw-transaction.h"
35#include "fw-topology.h" 38#include "fw-topology.h"
@@ -811,6 +814,28 @@ static int ioctl_stop_iso(struct client *client, void *buffer)
811 return fw_iso_context_stop(client->iso_context); 814 return fw_iso_context_stop(client->iso_context);
812} 815}
813 816
817static int ioctl_get_cycle_timer(struct client *client, void *buffer)
818{
819 struct fw_cdev_get_cycle_timer *request = buffer;
820 struct fw_card *card = client->device->card;
821 unsigned long long bus_time;
822 struct timeval tv;
823 unsigned long flags;
824
825 preempt_disable();
826 local_irq_save(flags);
827
828 bus_time = card->driver->get_bus_time(card);
829 do_gettimeofday(&tv);
830
831 local_irq_restore(flags);
832 preempt_enable();
833
834 request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
835 request->cycle_timer = bus_time & 0xffffffff;
836 return 0;
837}
838
814static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { 839static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
815 ioctl_get_info, 840 ioctl_get_info,
816 ioctl_send_request, 841 ioctl_send_request,
@@ -824,6 +849,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
824 ioctl_queue_iso, 849 ioctl_queue_iso,
825 ioctl_start_iso, 850 ioctl_start_iso,
826 ioctl_stop_iso, 851 ioctl_stop_iso,
852 ioctl_get_cycle_timer,
827}; 853};
828 854
829static int 855static int
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 1a45d6f41b0..0f0e271f97f 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -178,6 +178,7 @@ union fw_cdev_event {
178#define FW_CDEV_IOC_QUEUE_ISO _IOWR('#', 0x09, struct fw_cdev_queue_iso) 178#define FW_CDEV_IOC_QUEUE_ISO _IOWR('#', 0x09, struct fw_cdev_queue_iso)
179#define FW_CDEV_IOC_START_ISO _IOW('#', 0x0a, struct fw_cdev_start_iso) 179#define FW_CDEV_IOC_START_ISO _IOW('#', 0x0a, struct fw_cdev_start_iso)
180#define FW_CDEV_IOC_STOP_ISO _IOW('#', 0x0b, struct fw_cdev_stop_iso) 180#define FW_CDEV_IOC_STOP_ISO _IOW('#', 0x0b, struct fw_cdev_stop_iso)
181#define FW_CDEV_IOC_GET_CYCLE_TIMER _IOR('#', 0x0c, struct fw_cdev_get_cycle_timer)
181 182
182/* FW_CDEV_VERSION History 183/* FW_CDEV_VERSION History
183 * 184 *
@@ -459,4 +460,18 @@ struct fw_cdev_stop_iso {
459 __u32 handle; 460 __u32 handle;
460}; 461};
461 462
463/**
464 * struct fw_cdev_get_cycle_timer - read cycle timer register
465 * @local_time: system time, in microseconds since the Epoch
466 * @cycle_timer: isochronous cycle timer, as per OHCI 1.1 clause 5.13
467 *
468 * The %FW_CDEV_IOC_GET_CYCLE_TIMER ioctl reads the isochronous cycle timer
469 * and also the system clock. This allows to express the receive time of an
470 * isochronous packet as a system time with microsecond accuracy.
471 */
472struct fw_cdev_get_cycle_timer {
473 __u64 local_time;
474 __u32 cycle_timer;
475};
476
462#endif /* _LINUX_FIREWIRE_CDEV_H */ 477#endif /* _LINUX_FIREWIRE_CDEV_H */