.. | .. |
---|
47 | 47 | #include <linux/sched/clock.h> |
---|
48 | 48 | #include <linux/sched/debug.h> |
---|
49 | 49 | #include <linux/sched/task_stack.h> |
---|
| 50 | +#include <linux/irqstage.h> |
---|
50 | 51 | |
---|
51 | 52 | #include <linux/uaccess.h> |
---|
52 | 53 | #include <asm/sections.h> |
---|
.. | .. |
---|
2188 | 2189 | } |
---|
2189 | 2190 | #endif |
---|
2190 | 2191 | |
---|
| 2192 | +#ifdef CONFIG_RAW_PRINTK |
---|
| 2193 | +static struct console *raw_console; |
---|
| 2194 | +static DEFINE_HARD_SPINLOCK(raw_console_lock); |
---|
| 2195 | + |
---|
| 2196 | +void raw_puts(const char *s, size_t len) |
---|
| 2197 | +{ |
---|
| 2198 | + unsigned long flags; |
---|
| 2199 | + |
---|
| 2200 | + raw_spin_lock_irqsave(&raw_console_lock, flags); |
---|
| 2201 | + if (raw_console) |
---|
| 2202 | + raw_console->write_raw(raw_console, s, len); |
---|
| 2203 | + raw_spin_unlock_irqrestore(&raw_console_lock, flags); |
---|
| 2204 | +} |
---|
| 2205 | +EXPORT_SYMBOL(raw_puts); |
---|
| 2206 | + |
---|
| 2207 | +void raw_vprintk(const char *fmt, va_list ap) |
---|
| 2208 | +{ |
---|
| 2209 | + char buf[256]; |
---|
| 2210 | + size_t n; |
---|
| 2211 | + |
---|
| 2212 | + if (raw_console == NULL || console_suspended) |
---|
| 2213 | + return; |
---|
| 2214 | + |
---|
| 2215 | + touch_nmi_watchdog(); |
---|
| 2216 | + n = vscnprintf(buf, sizeof(buf), fmt, ap); |
---|
| 2217 | + raw_puts(buf, n); |
---|
| 2218 | +} |
---|
| 2219 | +EXPORT_SYMBOL(raw_vprintk); |
---|
| 2220 | + |
---|
| 2221 | +asmlinkage __visible void raw_printk(const char *fmt, ...) |
---|
| 2222 | +{ |
---|
| 2223 | + va_list ap; |
---|
| 2224 | + |
---|
| 2225 | + va_start(ap, fmt); |
---|
| 2226 | + raw_vprintk(fmt, ap); |
---|
| 2227 | + va_end(ap); |
---|
| 2228 | +} |
---|
| 2229 | +EXPORT_SYMBOL(raw_printk); |
---|
| 2230 | + |
---|
| 2231 | +static inline void register_raw_console(struct console *newcon) |
---|
| 2232 | +{ |
---|
| 2233 | + unsigned long flags; |
---|
| 2234 | + |
---|
| 2235 | + raw_spin_lock_irqsave(&raw_console_lock, flags); |
---|
| 2236 | + if (newcon->write_raw) |
---|
| 2237 | + raw_console = newcon; |
---|
| 2238 | + raw_spin_unlock_irqrestore(&raw_console_lock, flags); |
---|
| 2239 | +} |
---|
| 2240 | + |
---|
| 2241 | +static inline void unregister_raw_console(struct console *oldcon) |
---|
| 2242 | +{ |
---|
| 2243 | + unsigned long flags; |
---|
| 2244 | + |
---|
| 2245 | + raw_spin_lock_irqsave(&raw_console_lock, flags); |
---|
| 2246 | + if (oldcon == raw_console) |
---|
| 2247 | + raw_console = NULL; |
---|
| 2248 | + raw_spin_unlock_irqrestore(&raw_console_lock, flags); |
---|
| 2249 | +} |
---|
| 2250 | + |
---|
| 2251 | +#else |
---|
| 2252 | + |
---|
| 2253 | +static inline void register_raw_console(struct console *newcon) { } |
---|
| 2254 | + |
---|
| 2255 | +static inline void unregister_raw_console(struct console *oldcon) { } |
---|
| 2256 | + |
---|
| 2257 | +#endif |
---|
| 2258 | + |
---|
2191 | 2259 | static int __add_preferred_console(char *name, int idx, char *options, |
---|
2192 | 2260 | char *brl_options, bool user_specified) |
---|
2193 | 2261 | { |
---|
.. | .. |
---|
2854 | 2922 | if (err || newcon->flags & CON_BRL) |
---|
2855 | 2923 | return; |
---|
2856 | 2924 | |
---|
| 2925 | + /* The latest raw console to register is current. */ |
---|
| 2926 | + register_raw_console(newcon); |
---|
| 2927 | + |
---|
2857 | 2928 | /* |
---|
2858 | 2929 | * If we have a bootconsole, and are switching to a real console, |
---|
2859 | 2930 | * don't print everything out again, since when the boot console, and |
---|
.. | .. |
---|
2938 | 3009 | (console->flags & CON_BOOT) ? "boot" : "" , |
---|
2939 | 3010 | console->name, console->index); |
---|
2940 | 3011 | |
---|
| 3012 | + unregister_raw_console(console); |
---|
| 3013 | + |
---|
2941 | 3014 | res = _braille_unregister_console(console); |
---|
2942 | 3015 | if (res < 0) |
---|
2943 | 3016 | return res; |
---|