firewire: Implement CSR cycle time and bus time registers.

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index a9e1346..6f9895d2 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -139,6 +139,7 @@
 	int node_id;
 	int generation;
 	int request_generation;
+	u32 bus_seconds;
 
 	/* Spinlock for accessing fw_ohci data.  Never call out of
 	 * this driver with this lock held. */
@@ -959,7 +960,7 @@
 static irqreturn_t irq_handler(int irq, void *data)
 {
 	struct fw_ohci *ohci = data;
-	u32 event, iso_event;
+	u32 event, iso_event, cycle_time;
 	int i;
 
 	event = reg_read(ohci, OHCI1394_IntEventClear);
@@ -1002,6 +1003,12 @@
 		iso_event &= ~(1 << i);
 	}
 
+	if (event & OHCI1394_cycle64Seconds) {
+		cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
+		if ((cycle_time & 0x80000000) == 0)
+			ohci->bus_seconds++;
+	}
+
 	return IRQ_HANDLED;
 }
 
@@ -1213,6 +1220,19 @@
 	return retval;
 }
 
+static u64
+ohci_get_bus_time(struct fw_card *card)
+{
+	struct fw_ohci *ohci = fw_ohci(card);
+	u32 cycle_time;
+	u64 bus_time;
+
+	cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
+	bus_time = ((u64) ohci->bus_seconds << 32) | cycle_time;
+
+	return bus_time;
+}
+
 static int handle_ir_bufferfill_packet(struct context *context,
 				       struct descriptor *d,
 				       struct descriptor *last)
@@ -1686,6 +1706,7 @@
 	.send_response		= ohci_send_response,
 	.cancel_packet		= ohci_cancel_packet,
 	.enable_phys_dma	= ohci_enable_phys_dma,
+	.get_bus_time		= ohci_get_bus_time,
 
 	.allocate_iso_context	= ohci_allocate_iso_context,
 	.free_iso_context	= ohci_free_iso_context,
@@ -1862,7 +1883,8 @@
 		  OHCI1394_RQPkt | OHCI1394_RSPkt |
 		  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
 		  OHCI1394_isochRx | OHCI1394_isochTx |
-		  OHCI1394_masterIntEnable);
+		  OHCI1394_masterIntEnable |
+		  OHCI1394_cycle64Seconds);
 
 	bus_options = reg_read(ohci, OHCI1394_BusOptions);
 	max_receive = (bus_options >> 12) & 0xf;