Commit 9f1aed97 authored by Philippe Gerum's avatar Philippe Gerum

printk: ipipe: add raw console channel

parent cf7a617d
...@@ -133,10 +133,12 @@ static inline int con_debug_leave(void) ...@@ -133,10 +133,12 @@ static inline int con_debug_leave(void)
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */ #define CON_ANYTIME (16) /* Safe to call when cpu is offline */
#define CON_BRL (32) /* Used for a braille device */ #define CON_BRL (32) /* Used for a braille device */
#define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */ #define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */
#define CON_RAW (128) /* Supports raw write mode */
struct console { struct console {
char name[16]; char name[16];
void (*write)(struct console *, const char *, unsigned); void (*write)(struct console *, const char *, unsigned);
void (*write_raw)(struct console *, const char *, unsigned);
int (*read)(struct console *, char *, unsigned); int (*read)(struct console *, char *, unsigned);
struct tty_driver *(*device)(struct console *, int *); struct tty_driver *(*device)(struct console *, int *);
void (*unblank)(void); void (*unblank)(void);
......
...@@ -155,6 +155,17 @@ static inline void printk_nmi_enter(void) { } ...@@ -155,6 +155,17 @@ static inline void printk_nmi_enter(void) { }
static inline void printk_nmi_exit(void) { } static inline void printk_nmi_exit(void) { }
#endif /* PRINTK_NMI */ #endif /* PRINTK_NMI */
#ifdef CONFIG_RAW_PRINTK
void raw_vprintk(const char *fmt, va_list ap);
asmlinkage __printf(1, 2)
void raw_printk(const char *fmt, ...);
#else
static inline __cold
void raw_vprintk(const char *s, va_list ap) { }
static inline __printf(1, 2) __cold
void raw_printk(const char *s, ...) { }
#endif
#ifdef CONFIG_PRINTK #ifdef CONFIG_PRINTK
asmlinkage __printf(5, 0) asmlinkage __printf(5, 0)
int vprintk_emit(int facility, int level, int vprintk_emit(int facility, int level,
......
...@@ -1238,6 +1238,18 @@ config PRINTK_NMI ...@@ -1238,6 +1238,18 @@ config PRINTK_NMI
depends on PRINTK depends on PRINTK
depends on HAVE_NMI depends on HAVE_NMI
config RAW_PRINTK
bool "Enable support for raw printk"
default n
help
This option enables a printk variant called raw_printk() for
writing all output unmodified to a raw console channel
immediately, without any header or preparation whatsoever,
usable from any context.
Unlike early_printk() console devices, raw_printk() devices
can live past the boot sequence.
config BUG config BUG
bool "BUG() support" if EXPERT bool "BUG() support" if EXPERT
default y default y
......
...@@ -1984,6 +1984,62 @@ asmlinkage __visible void early_printk(const char *fmt, ...) ...@@ -1984,6 +1984,62 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
} }
#endif #endif
#ifdef CONFIG_RAW_PRINTK
static struct console *raw_console;
static IPIPE_DEFINE_RAW_SPINLOCK(raw_console_lock);
void raw_vprintk(const char *fmt, va_list ap)
{
unsigned long flags;
char buf[256];
int n;
if (raw_console == NULL || console_suspended)
return;
n = vscnprintf(buf, sizeof(buf), fmt, ap);
touch_nmi_watchdog();
raw_spin_lock_irqsave(&raw_console_lock, flags);
if (raw_console)
raw_console->write_raw(raw_console, buf, n);
raw_spin_unlock_irqrestore(&raw_console_lock, flags);
}
asmlinkage __visible void raw_printk(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
raw_vprintk(fmt, ap);
va_end(ap);
}
static inline void register_raw_console(struct console *newcon)
{
if ((newcon->flags & CON_RAW) != 0 && newcon->write_raw)
raw_console = newcon;
}
static inline void unregister_raw_console(struct console *oldcon)
{
unsigned long flags;
raw_spin_lock_irqsave(&raw_console_lock, flags);
if (oldcon == raw_console)
raw_console = NULL;
raw_spin_unlock_irqrestore(&raw_console_lock, flags);
}
#else
static inline void register_raw_console(struct console *newcon)
{ }
static inline void unregister_raw_console(struct console *oldcon)
{ }
#endif
static int __add_preferred_console(char *name, int idx, char *options, static int __add_preferred_console(char *name, int idx, char *options,
char *brl_options) char *brl_options)
{ {
...@@ -2612,6 +2668,9 @@ void register_console(struct console *newcon) ...@@ -2612,6 +2668,9 @@ void register_console(struct console *newcon)
console_drivers->next = newcon; console_drivers->next = newcon;
} }
/* The latest raw console to register is current. */
register_raw_console(newcon);
if (newcon->flags & CON_EXTENDED) if (newcon->flags & CON_EXTENDED)
if (!nr_ext_console_drivers++) if (!nr_ext_console_drivers++)
pr_info("printk: continuation disabled due to ext consoles, expect more fragments in /dev/kmsg\n"); pr_info("printk: continuation disabled due to ext consoles, expect more fragments in /dev/kmsg\n");
...@@ -2667,6 +2726,8 @@ int unregister_console(struct console *console) ...@@ -2667,6 +2726,8 @@ int unregister_console(struct console *console)
(console->flags & CON_BOOT) ? "boot" : "" , (console->flags & CON_BOOT) ? "boot" : "" ,
console->name, console->index); console->name, console->index);
unregister_raw_console(console);
res = _braille_unregister_console(console); res = _braille_unregister_console(console);
if (res) if (res)
return res; return res;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment