OSDN Git Service

soc: qcom: boot_marker: add mpm timer interface
authorZhiqiang Tu <ztu@codeaurora.org>
Fri, 1 Jun 2018 06:34:56 +0000 (14:34 +0800)
committerZhiqiang Tu <ztu@codeaurora.org>
Fri, 1 Jun 2018 06:34:56 +0000 (14:34 +0800)
Provide a debugfs interface to get count of mpm timer.

Change-Id: I24e927b6219b8bd4c2f4ddecb8f51518f0db663a
Signed-off-by: Zhiqiang Tu <ztu@codeaurora.org>
drivers/soc/qcom/boot_marker.c
drivers/soc/qcom/boot_stats.c
include/soc/qcom/boot_stats.h

index b3a6c9f..0b72d76 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016,2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/mm.h>
 #include <soc/qcom/boot_stats.h>
 
 #define MAX_STRING_LEN 256
 #define BOOT_MARKER_MAX_LEN 40
-static struct dentry *dent_bkpi, *dent_bkpi_status;
+static struct dentry *dent_bkpi, *dent_bkpi_status, *dent_mpm_timer;
 static struct boot_marker boot_marker_list;
 
 struct boot_marker {
@@ -140,6 +141,48 @@ static const struct file_operations fops_bkpi = {
        .write = bootkpi_writer,
 };
 
+static ssize_t mpm_timer_read(struct file *fp, char __user *user_buffer,
+                       size_t count, loff_t *position)
+{
+       unsigned long long int timer_value;
+       int rc = 0;
+       char buf[100];
+       int temp = 0;
+
+       timer_value = msm_timer_get_sclk_ticks();
+
+       temp = scnprintf(buf, sizeof(buf), "%llu.%03llu seconds\n",
+                       timer_value/TIMER_KHZ,
+                       (((timer_value % TIMER_KHZ) * 1000) / TIMER_KHZ));
+
+       rc = simple_read_from_buffer(user_buffer, count, position, buf, temp);
+
+       return rc;
+}
+
+static int mpm_timer_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static int mpm_timer_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       phys_addr_t addr = msm_timer_get_pa();
+
+       if (vma->vm_flags & VM_WRITE)
+               return -EPERM;
+
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       return vm_iomap_memory(vma, addr, PAGE_SIZE);
+}
+
+static const struct file_operations fops_mpm_timer = {
+       .owner = THIS_MODULE,
+       .open  = mpm_timer_open,
+       .read  = mpm_timer_read,
+       .mmap = mpm_timer_mmap,
+};
+
 static int __init init_bootkpi(void)
 {
        dent_bkpi = debugfs_create_dir("bootkpi", NULL);
@@ -147,7 +190,7 @@ static int __init init_bootkpi(void)
                return -ENODEV;
 
        dent_bkpi_status = debugfs_create_file("kpi_values",
-               (S_IRUGO|S_IWUGO), dent_bkpi, 0, &fops_bkpi);
+               (S_IRUGO|S_IWUGO), dent_bkpi, NULL, &fops_bkpi);
        if (IS_ERR_OR_NULL(dent_bkpi_status)) {
                debugfs_remove(dent_bkpi);
                dent_bkpi = NULL;
@@ -155,6 +198,17 @@ static int __init init_bootkpi(void)
                return -ENODEV;
        }
 
+       dent_mpm_timer = debugfs_create_file("mpm_timer",
+               S_IRUGO, dent_bkpi, NULL, &fops_mpm_timer);
+       if (IS_ERR_OR_NULL(dent_mpm_timer)) {
+               debugfs_remove(dent_bkpi_status);
+               dent_bkpi_status = NULL;
+               debugfs_remove(dent_bkpi);
+               dent_bkpi = NULL;
+               pr_err("boot_marker: Could not create 'mpm_timer' debugfs file\n");
+               return -ENODEV;
+       }
+
        INIT_LIST_HEAD(&boot_marker_list.list);
        mutex_init(&boot_marker_list.lock);
        set_bootloader_stats();
index eb5357e..35b8108 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014,2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014,2016,2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
 #include <soc/qcom/boot_stats.h>
 
 static void __iomem *mpm_counter_base;
+static phys_addr_t mpm_counter_pa;
 static uint32_t mpm_counter_freq;
 struct boot_stats __iomem *boot_stats;
 
 static int mpm_parse_dt(void)
 {
        struct device_node *np;
+       const __be32 *addrp;
        u32 freq;
 
        np = of_find_compatible_node(NULL, NULL, "qcom,msm-imem-boot_stats");
@@ -58,12 +60,19 @@ static int mpm_parse_dt(void)
        else
                return -ENODEV;
 
-       if (of_get_address(np, 0, NULL, NULL)) {
+       addrp = of_get_address(np, 0, NULL, NULL);
+       if (addrp) {
                mpm_counter_base = of_iomap(np, 0);
                if (!mpm_counter_base) {
                        pr_err("mpm_counter: cant map counter base\n");
                        return -ENODEV;
                }
+
+               mpm_counter_pa = of_translate_address(np, addrp);
+               if (mpm_counter_pa == OF_BAD_ADDR) {
+                       pr_err("mpm_counter: failed to get physical address\n");
+                       return -ENODEV;
+               }
        }
 
        return 0;
@@ -121,6 +130,11 @@ unsigned long long int msm_timer_get_sclk_ticks(void)
        return t1;
 }
 
+phys_addr_t msm_timer_get_pa(void)
+{
+       return mpm_counter_pa;
+}
+
 int boot_stats_init(void)
 {
        int ret;
index cebf4be..53868ad 100644 (file)
@@ -31,12 +31,14 @@ struct boot_stats {
 int boot_stats_init(void);
 int boot_stats_exit(void);
 unsigned long long int msm_timer_get_sclk_ticks(void);
+phys_addr_t msm_timer_get_pa(void);
 #else
 static inline int boot_stats_init(void) { return 0; }
 static inline unsigned long long int msm_timer_get_sclk_ticks(void)
 {
        return 0;
 }
+static inline phys_addr_t msm_timer_get_pa(void) { return 0; }
 #endif
 
 #ifdef CONFIG_MSM_BOOT_TIME_MARKER