-/* 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 {
.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);
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;
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();
-/* 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");
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;
return t1;
}
+phys_addr_t msm_timer_get_pa(void)
+{
+ return mpm_counter_pa;
+}
+
int boot_stats_init(void)
{
int ret;