summaryrefslogtreecommitdiff
path: root/drivers/firewire
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-card.c39
-rw-r--r--drivers/firewire/core-cdev.c6
-rw-r--r--drivers/firewire/core-transaction.c18
3 files changed, 61 insertions, 2 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c
index f3b3953cac83..6ac5ff20a2fe 100644
--- a/drivers/firewire/core-card.c
+++ b/drivers/firewire/core-card.c
@@ -616,6 +616,15 @@ static struct fw_iso_context *dummy_allocate_iso_context(struct fw_card *card,
return ERR_PTR(-ENODEV);
}
+static u32 dummy_read_csr(struct fw_card *card, int csr_offset)
+{
+ return 0;
+}
+
+static void dummy_write_csr(struct fw_card *card, int csr_offset, u32 value)
+{
+}
+
static int dummy_start_iso(struct fw_iso_context *ctx,
s32 cycle, u32 sync, u32 tags)
{
@@ -649,6 +658,8 @@ static const struct fw_card_driver dummy_driver_template = {
.send_response = dummy_send_response,
.cancel_packet = dummy_cancel_packet,
.enable_phys_dma = dummy_enable_phys_dma,
+ .read_csr = dummy_read_csr,
+ .write_csr = dummy_write_csr,
.allocate_iso_context = dummy_allocate_iso_context,
.start_iso = dummy_start_iso,
.set_iso_channels = dummy_set_iso_channels,
@@ -694,3 +705,31 @@ void fw_core_remove_card(struct fw_card *card)
WARN_ON(!list_empty(&card->transaction_list));
}
EXPORT_SYMBOL(fw_core_remove_card);
+
+/**
+ * fw_card_read_cycle_time: read from Isochronous Cycle Timer Register of 1394 OHCI in MMIO region
+ * for controller card.
+ * @card: The instance of card for 1394 OHCI controller.
+ * @cycle_time: The mutual reference to value of cycle time for the read operation.
+ *
+ * Read value from Isochronous Cycle Timer Register of 1394 OHCI in MMIO region for the given
+ * controller card. This function accesses the region without any lock primitives or IRQ mask.
+ * When returning successfully, the content of @value argument has value aligned to host endianness,
+ * formetted by CYCLE_TIME CSR Register of IEEE 1394 std.
+ *
+ * Context: Any context.
+ * Return:
+ * * 0 - Read successfully.
+ * * -ENODEV - The controller is unavailable due to being removed or unbound.
+ */
+int fw_card_read_cycle_time(struct fw_card *card, u32 *cycle_time)
+{
+ if (card->driver->read_csr == dummy_read_csr)
+ return -ENODEV;
+
+ // It's possible to switch to dummy driver between the above and the below. This is the best
+ // effort to return -ENODEV.
+ *cycle_time = card->driver->read_csr(card, CSR_CYCLE_TIME);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fw_card_read_cycle_time);
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 708e417200f4..c9fe5903725a 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -1216,7 +1216,9 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
local_irq_disable();
- cycle_time = card->driver->read_csr(card, CSR_CYCLE_TIME);
+ ret = fw_card_read_cycle_time(card, &cycle_time);
+ if (ret < 0)
+ goto end;
switch (a->clk_id) {
case CLOCK_REALTIME: ktime_get_real_ts64(&ts); break;
@@ -1225,7 +1227,7 @@ static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
default:
ret = -EINVAL;
}
-
+end:
local_irq_enable();
a->tv_sec = ts.tv_sec;
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 6c20815cc8d1..af498d767702 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -620,6 +620,7 @@ struct fw_request {
struct fw_packet response;
u32 request_header[4];
int ack;
+ u32 timestamp;
u32 length;
u32 data[];
};
@@ -789,6 +790,7 @@ static struct fw_request *allocate_request(struct fw_card *card,
request->response.ack = 0;
request->response.callback = free_response_callback;
request->ack = p->ack;
+ request->timestamp = p->timestamp;
request->length = length;
if (data)
memcpy(request->data, data, length);
@@ -833,6 +835,22 @@ int fw_get_request_speed(struct fw_request *request)
}
EXPORT_SYMBOL(fw_get_request_speed);
+/**
+ * fw_request_get_timestamp: Get timestamp of the request.
+ * @request: The opaque pointer to request structure.
+ *
+ * Get timestamp when 1394 OHCI controller receives the asynchronous request subaction. The
+ * timestamp consists of the low order 3 bits of second field and the full 13 bits of count
+ * field of isochronous cycle time register.
+ *
+ * Returns: timestamp of the request.
+ */
+u32 fw_request_get_timestamp(const struct fw_request *request)
+{
+ return request->timestamp;
+}
+EXPORT_SYMBOL_GPL(fw_request_get_timestamp);
+
static void handle_exclusive_region_request(struct fw_card *card,
struct fw_packet *p,
struct fw_request *request,