Merge changes Ia2010a78,I8ad2be73 into msm-3.0
* changes:
msm: smem_log: Use sched_clock() for SMEM Log Timestamp
msm: smem_log: Handle uninitialized logs
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index 98f9957..2e9a97c 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -59,10 +59,20 @@
#define D(x...) do {} while (0)
#endif
+/*
+ * Legacy targets use the 32KHz hardware timer and new targets will use
+ * the scheduler timer scaled to a 32KHz tick count.
+ *
+ * As testing on legacy targets permits, we will move them to use
+ * sched_clock() and eventually remove the conditiona compilation.
+ */
#if defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) \
|| defined(CONFIG_ARCH_FSM9XXX)
#define TIMESTAMP_ADDR (MSM_TMR_BASE + 0x08)
-#else
+#elif defined(CONFIG_ARCH_APQ8064) || defined(CONFIG_ARCH_MSM7X01A) || \
+ defined(CONFIG_ARCH_MSM7x25) || defined(CONFIG_ARCH_MSM7X27) || \
+ defined(CONFIG_ARCH_MSM7X27A) || defined(CONFIG_ARCH_MSM8960) || \
+ defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_QSD8X50)
#define TIMESTAMP_ADDR (MSM_TMR_BASE + 0x04)
#endif
@@ -623,6 +633,8 @@
static void init_syms(void) {}
#endif
+#ifdef TIMESTAMP_ADDR
+/* legacy timestamp using 32.768KHz clock */
static inline unsigned int read_timestamp(void)
{
unsigned int tick = 0;
@@ -637,6 +649,18 @@
return tick;
}
+#else
+static inline unsigned int read_timestamp(void)
+{
+ unsigned long long val;
+
+ /* SMEM LOG uses a 32.768KHz timestamp */
+ val = sched_clock() * 32768U;
+ do_div(val, 1000000000U);
+
+ return (unsigned int)val;
+}
+#endif
static void smem_log_event_from_user(struct smem_log_inst *inst,
const char __user *buf, int size, int num)
@@ -649,6 +673,11 @@
int first = 1;
int ret;
+ if (!inst->idx) {
+ pr_err("%s: invalid write index\n", __func__);
+ return;
+ }
+
remote_spin_lock_irqsave(inst->remote_spinlock, flags);
while (num--) {
@@ -898,6 +927,9 @@
local_inst = fp->private_data;
+ if (!local_inst->idx)
+ return -ENODEV;
+
remote_spin_lock_irqsave(local_inst->remote_spinlock, flags);
orig_idx = *local_inst->idx;
@@ -947,6 +979,8 @@
struct smem_log_inst *inst;
inst = fp->private_data;
+ if (!inst->idx)
+ return -ENODEV;
remote_spin_lock_irqsave(inst->remote_spinlock, flags);
@@ -1185,8 +1219,10 @@
int curr_read_avail;
unsigned long flags = 0;
- remote_spin_lock_irqsave(inst->remote_spinlock, flags);
+ if (!inst->idx)
+ return 0;
+ remote_spin_lock_irqsave(inst->remote_spinlock, flags);
curr_read_avail = (*inst->idx - inst->read_idx);
if (curr_read_avail < 0)
curr_read_avail = inst->num - inst->read_idx + *inst->idx;
@@ -1694,6 +1730,10 @@
static int debug_dump(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[GEN].idx || !inst[GEN].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[GEN]);
r = wait_event_interruptible_timeout(inst[GEN].read_wait,
@@ -1714,6 +1754,10 @@
static int debug_dump_sym(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[GEN].idx || !inst[GEN].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[GEN]);
r = wait_event_interruptible_timeout(inst[GEN].read_wait,
@@ -1734,6 +1778,10 @@
static int debug_dump_static(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[STA].idx || !inst[STA].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[STA]);
r = wait_event_interruptible_timeout(inst[STA].read_wait,
@@ -1754,6 +1802,10 @@
static int debug_dump_static_sym(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[STA].idx || !inst[STA].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[STA]);
r = wait_event_interruptible_timeout(inst[STA].read_wait,
@@ -1774,6 +1826,10 @@
static int debug_dump_power(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[POW].idx || !inst[POW].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[POW]);
r = wait_event_interruptible_timeout(inst[POW].read_wait,
@@ -1794,6 +1850,10 @@
static int debug_dump_power_sym(char *buf, int max, uint32_t cont)
{
int r;
+
+ if (!inst[POW].idx || !inst[POW].events)
+ return -ENODEV;
+
while (cont) {
update_read_avail(&inst[POW]);
r = wait_event_interruptible_timeout(inst[POW].read_wait,
@@ -1822,10 +1882,15 @@
size_t count, loff_t *ppos)
{
int r;
- static int bsize;
+ int bsize = 0;
int (*fill)(char *, int, uint32_t) = file->private_data;
- if (!(*ppos))
+ if (!(*ppos)) {
bsize = fill(debug_buffer, EVENTS_PRINT_SIZE, 0);
+
+ if (bsize < 0)
+ bsize = scnprintf(debug_buffer,
+ EVENTS_PRINT_SIZE, "Log not available\n");
+ }
DBG("%s: count %d ppos %d\n", __func__, count, (unsigned int)*ppos);
r = simple_read_from_buffer(buf, count, ppos, debug_buffer,
bsize);
@@ -1840,12 +1905,21 @@
int bsize;
if (!buffer)
return -ENOMEM;
+
bsize = fill(buffer, count, 1);
+ if (bsize < 0) {
+ if (*ppos == 0)
+ bsize = scnprintf(buffer, count, "Log not available\n");
+ else
+ bsize = 0;
+ }
+
DBG("%s: count %d bsize %d\n", __func__, count, bsize);
if (copy_to_user(buf, buffer, bsize)) {
kfree(buffer);
return -EFAULT;
}
+ *ppos += bsize;
kfree(buffer);
return bsize;
}