qcacmn: Create qdf_log_timestamp_to_secs helper function

Create a timestamp conversion helper that returns whole seconds and
remaining micro seconds, for easier consumption by logging methods.

Change-Id: I5bc40075566485f3dc9f7e5fd81a13ec462c5da0
CRs-Fixed: 2031564
diff --git a/htc/htc_send.c b/htc/htc_send.c
index 1a1f3f9..3b82ac3 100644
--- a/htc/htc_send.c
+++ b/htc/htc_send.c
@@ -114,11 +114,12 @@
 	      "Time (seconds)     Type                         Credits    Queue Depth");
 	while (count) {
 		HTC_CREDIT_HISTORY *hist = &htc_credit_history_buffer[idx];
-		long long us = qdf_log_timestamp_to_usecs(hist->time);
+		uint64_t secs, usecs;
 
+		qdf_log_timestamp_to_secs(hist->time, &secs, &usecs);
 		print(print_priv, "% 8lld.%06lld    %-25s    %-7.d    %d",
-		      us / 1000000,
-		      us % 1000000,
+		      secs,
+		      usecs,
 		      htc_credit_exchange_type_str(hist->type),
 		      hist->tx_credit,
 		      hist->htc_tx_queue_depth);
diff --git a/qdf/inc/qdf_time.h b/qdf/inc/qdf_time.h
index c3bacd7..148e023 100644
--- a/qdf/inc/qdf_time.h
+++ b/qdf/inc/qdf_time.h
@@ -168,16 +168,39 @@
 #ifdef QCA_WIFI_3_0_ADRASTEA
 #define QDF_LOG_TIMESTAMP_UNIT QTIMER
 #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 192
+
+static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
+{
+	/*
+	 * Try to preserve precision by multiplying by 10 first.
+	 * If that would cause a wrap around, divide first instead.
+	 */
+	if (time * 10 < time) {
+		do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
+		return time * 10;
+	}
+
+	time = time * 10;
+	do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
+
+	return time;
+}
 #else
 #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG
 #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10
+
+static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
+{
+	/* timestamps are already in micro seconds */
+	return time;
+}
 #endif
 
-static inline unsigned long long qdf_log_timestamp_to_usecs(uint64_t time)
+static inline void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs,
+					     uint64_t *usecs)
 {
-	if ((time * 10) < time)
-		return (time / QDF_LOG_TIMESTAMP_CYCLES_PER_10_US) * 10;
-	return (time * 10) / QDF_LOG_TIMESTAMP_CYCLES_PER_10_US;
+	*secs = qdf_log_timestamp_to_usecs(time);
+	*usecs = do_div(*secs, 1000000ul);
 }
 
 static inline uint64_t qdf_usecs_to_log_timestamp(uint64_t usecs)
diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c
index 73b9d7a..7ac4b75 100644
--- a/wmi/src/wmi_unified.c
+++ b/wmi/src/wmi_unified.c
@@ -588,13 +588,14 @@
 	while (count) {
 		struct wmi_command_debug *cmd_log = (struct wmi_command_debug *)
 			&((struct wmi_command_debug *)log_buffer->buf)[idx];
-		long long us = qdf_log_timestamp_to_usecs(cmd_log->time);
+		uint64_t secs, usecs;
 		int len = 0;
 		int i;
 
+		qdf_log_timestamp_to_secs(cmd_log->time, &secs, &usecs);
 		len += scnprintf(str + len, sizeof(str) - len,
 				 "% 8lld.%06lld    %6u (0x%06x)    ",
-				 us / 1000000, us % 1000000,
+				 secs, usecs,
 				 cmd_log->command, cmd_log->command);
 		for (i = 0; i < data_len; ++i) {
 			len += scnprintf(str + len, sizeof(str) - len,
@@ -641,13 +642,14 @@
 	while (count) {
 		struct wmi_event_debug *event_log = (struct wmi_event_debug *)
 			&((struct wmi_event_debug *)log_buffer->buf)[idx];
-		long long us = qdf_log_timestamp_to_usecs(event_log->time);
+		uint64_t secs, usecs;
 		int len = 0;
 		int i;
 
+		qdf_log_timestamp_to_secs(event_log->time, &secs, &usecs);
 		len += scnprintf(str + len, sizeof(str) - len,
 				 "% 8lld.%06lld    %6u (0x%06x)    ",
-				 us / 1000000, us % 1000000,
+				 secs, usecs,
 				 event_log->event, event_log->event);
 		for (i = 0; i < data_len; ++i) {
 			len += scnprintf(str + len, sizeof(str) - len,