From: 黄涛 Date: Mon, 17 Dec 2012 03:49:56 +0000 (+0800) Subject: rk: last_log: version 2.0, map log buf as noncached, add last_log_get API X-Git-Tag: firefly_0821_release~8099^2~15 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=46411181aec739ac0b297e6a1b2051d14ebbdf80;p=firefly-linux-kernel-4.4.55.git rk: last_log: version 2.0, map log buf as noncached, add last_log_get API --- diff --git a/arch/arm/plat-rk/last_log.c b/arch/arm/plat-rk/last_log.c index 6e6ead70372b..61a1d83bb2f7 100644 --- a/arch/arm/plat-rk/last_log.c +++ b/arch/arm/plat-rk/last_log.c @@ -8,17 +8,27 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) "last_log: " fmt #include #include +#include #include #include +#include #include #include #define LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) +#define LOG_BUF_PAGE_ORDER (CONFIG_LOG_BUF_SHIFT - PAGE_SHIFT) static char last_log_buf[LOG_BUF_LEN]; extern void switch_log_buf(char *new_log_buf, unsigned size); +char *last_log_get(unsigned *size) +{ + *size = LOG_BUF_LEN; + return last_log_buf; +} + static ssize_t last_log_read(struct file *file, char __user *buf, size_t len, loff_t *offset) { @@ -41,24 +51,43 @@ static const struct file_operations last_log_file_ops = { .read = last_log_read, }; +static void * __init last_log_vmap(phys_addr_t start, unsigned int page_count) +{ + struct page *pages[page_count]; + unsigned int i; + + for (i = 0; i < page_count; i++) { + phys_addr_t addr = start + i * PAGE_SIZE; + pages[i] = pfn_to_page(addr >> PAGE_SHIFT); + } + return vmap(pages, page_count, VM_MAP, pgprot_noncached(PAGE_KERNEL)); +} + static int __init last_log_init(void) { - char *log_buf; + char *log_buf, *new_log_buf; struct proc_dir_entry *entry; - log_buf = (char *)__get_free_pages(GFP_KERNEL, CONFIG_LOG_BUF_SHIFT - PAGE_SHIFT); + log_buf = (char *)__get_free_pages(GFP_KERNEL, LOG_BUF_PAGE_ORDER); if (!log_buf) { - printk(KERN_ERR "last_log: failed to __get_free_pages(%d)\n", CONFIG_LOG_BUF_SHIFT - PAGE_SHIFT); + pr_err("failed to __get_free_pages(%d)\n", LOG_BUF_PAGE_ORDER); + return 0; + } + + new_log_buf = last_log_vmap(virt_to_phys(log_buf), 1 << LOG_BUF_PAGE_ORDER); + if (!new_log_buf) { + pr_err("failed to map %d pages at 0x%08x\n", 1 << LOG_BUF_PAGE_ORDER, virt_to_phys(log_buf)); return 0; } - printk("last_log: 0x%p 0x%p\n", log_buf, last_log_buf); + + pr_info("0x%p map to 0x%p and copy to 0x%p (version 2.0)\n", log_buf, new_log_buf, last_log_buf); memcpy(last_log_buf, log_buf, LOG_BUF_LEN); - switch_log_buf(log_buf, LOG_BUF_LEN); + switch_log_buf(new_log_buf, LOG_BUF_LEN); entry = create_proc_entry("last_log", S_IFREG | S_IRUGO, NULL); if (!entry) { - printk(KERN_ERR "last_log: failed to create proc entry\n"); + pr_err("failed to create proc entry\n"); return 0; }