123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- /*
- * arch/arm/kernel/fiq_printk.c
- *
- * Copyright (C) 2011-2012 Amlogic, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- #include <linux/kernel.h>
- #include <linux/mm.h>
- #include <linux/tty.h>
- #include <linux/tty_driver.h>
- #include <linux/console.h>
- #include <linux/init.h>
- #include <linux/jiffies.h>
- #include <linux/nmi.h>
- #include <linux/module.h>
- #include <linux/moduleparam.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- #include <linux/smp.h>
- #include <linux/security.h>
- #include <linux/bootmem.h>
- #include <linux/syscalls.h>
- #include <linux/kexec.h>
- #include <linux/ratelimit.h>
- #include <linux/kmsg_dump.h>
- #include <linux/syslog.h>
- #include <linux/timer.h>
- #include <asm/uaccess.h>
- #define MAX_PRINT_SIZE 1024
- #define FIQ_PREF "<FIQ>:"
- static unsigned char fiqprint_buf[MAX_PRINT_SIZE+4];
- static unsigned char fiqprint_buf1[MAX_PRINT_SIZE+4];
- static int fiqprint_buf_off=0;
- static struct timer_list fiq_print_timer;
- /* Must call in FIQ mode */
- int fiq_vprintk(const char *fmt, va_list args)
- {
- int r;
- char *bufptr = fiqprint_buf + fiqprint_buf_off;
- int buflen = MAX_PRINT_SIZE - fiqprint_buf_off;
- if (buflen > sizeof(FIQ_PREF) + 16) {
- strcpy(bufptr, FIQ_PREF);
- bufptr += strlen(FIQ_PREF);
- buflen -= strlen(FIQ_PREF);
- }
- r = vscnprintf(bufptr, MAX_PRINT_SIZE - fiqprint_buf_off, fmt, args);
- fiqprint_buf_off += r;
- if (fiqprint_buf_off > MAX_PRINT_SIZE)
- fiqprint_buf_off = 0; // Overflow, drop all
- return r;
- }
- EXPORT_SYMBOL(fiq_vprintk);
- int fiq_printk(const char *fmt, ...)
- {
- int r;
- va_list args;
- va_start(args, fmt);
- r = fiq_vprintk(fmt, args);
- va_end(args);
- return r;
- }
- EXPORT_SYMBOL(fiq_printk);
- static void fiq_printk_timer(unsigned long arg)
- {
- unsigned long flags;
- int len = 0;
- if (fiqprint_buf_off > 0) {
- raw_local_save_flags(flags);
- local_fiq_disable();
- memcpy(fiqprint_buf1, fiqprint_buf, fiqprint_buf_off);
- len = fiqprint_buf_off;
- fiqprint_buf_off = 0;
- fiqprint_buf1[len] = '\n';
- fiqprint_buf1[len + 1] = '0';
- raw_local_irq_restore(flags);
- }
- if (len > 0)
- printk("%s\n", fiqprint_buf1);
- mod_timer(&fiq_print_timer,jiffies + HZ / 10);
- }
- static __init int fiq_printk_init(void)
- {
- init_timer(&fiq_print_timer);
- fiq_print_timer.function = fiq_printk_timer;
- fiq_print_timer.expires = jiffies + 1;
- fiq_print_timer.data = 0;
- add_timer(&fiq_print_timer);
- return 0;
- }
- module_init(fiq_printk_init);
|