mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 00:21:17 +00:00
Driver core merge for 3.6-rc1
Here's the big driver core pull request for 3.6-rc1. Unlike 3.5, this kernel should be a lot tamer, with the printk changes now settled down. All we have here is some extcon driver updates, w1 driver updates, a few printk cleanups that weren't needed for 3.5, but are good to have now, and some other minor fixes/changes in the driver core. All of these have been in the linux-next releases for a while now. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) iEYEABECAAYFAlARgIUACgkQMUfUDdst+ynDHgCfRNwIB9L+zZvjcKE5e1BhDbUl wVUAn398DFgbJ1+PjGkd1EMR2uVTh7Ou =MIFu -----END PGP SIGNATURE----- Merge tag 'driver-core-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core changes from Greg Kroah-Hartman: "Here's the big driver core pull request for 3.6-rc1. Unlike 3.5, this kernel should be a lot tamer, with the printk changes now settled down. All we have here is some extcon driver updates, w1 driver updates, a few printk cleanups that weren't needed for 3.5, but are good to have now, and some other minor fixes/changes in the driver core. All of these have been in the linux-next releases for a while now. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'driver-core-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (38 commits) printk: Export struct log size and member offsets through vmcoreinfo Drivers: hv: Change the hex constant to a decimal constant driver core: don't trigger uevent after failure extcon: MAX77693: Add extcon-max77693 driver to support Maxim MAX77693 MUIC device sysfs: fail dentry revalidation after namespace change fix sysfs: fail dentry revalidation after namespace change extcon: spelling of detach in function doc extcon: arizona: Stop microphone detection if we give up on it extcon: arizona: Update cable reporting calls and split headset PM / Runtime: Do not increment device usage counts before probing kmsg - do not flush partial lines when the console is busy kmsg - export "continuation record" flag to /dev/kmsg kmsg - avoid warning for CONFIG_PRINTK=n compilations kmsg - properly print over-long continuation lines driver-core: Use kobj_to_dev instead of re-implementing it driver-core: Move kobj_to_dev from genhd.h to device.h driver core: Move deferred devices to the end of dpm_list before probing driver core: move uevent call to driver_register driver core: fix shutdown races with probe/remove(v3) Extcon: Arizona: Add driver for Wolfson Arizona class devices ...
This commit is contained in:
commit
fa93669a19
47 changed files with 2159 additions and 227 deletions
159
kernel/printk.c
159
kernel/printk.c
|
@ -216,6 +216,7 @@ struct log {
|
|||
*/
|
||||
static DEFINE_RAW_SPINLOCK(logbuf_lock);
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
/* the next printk record to read by syslog(READ) or /proc/kmsg */
|
||||
static u64 syslog_seq;
|
||||
static u32 syslog_idx;
|
||||
|
@ -228,14 +229,19 @@ static u32 log_first_idx;
|
|||
|
||||
/* index and sequence number of the next record to store in the buffer */
|
||||
static u64 log_next_seq;
|
||||
#ifdef CONFIG_PRINTK
|
||||
static u32 log_next_idx;
|
||||
|
||||
/* the next printk record to write to the console */
|
||||
static u64 console_seq;
|
||||
static u32 console_idx;
|
||||
static enum log_flags console_prev;
|
||||
|
||||
/* the next printk record to read after the last 'clear' command */
|
||||
static u64 clear_seq;
|
||||
static u32 clear_idx;
|
||||
|
||||
#define LOG_LINE_MAX 1024
|
||||
#define PREFIX_MAX 32
|
||||
#define LOG_LINE_MAX 1024 - PREFIX_MAX
|
||||
|
||||
/* record buffer */
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
|
@ -360,6 +366,7 @@ static void log_store(int facility, int level,
|
|||
struct devkmsg_user {
|
||||
u64 seq;
|
||||
u32 idx;
|
||||
enum log_flags prev;
|
||||
struct mutex lock;
|
||||
char buf[8192];
|
||||
};
|
||||
|
@ -425,6 +432,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
|
|||
struct log *msg;
|
||||
u64 ts_usec;
|
||||
size_t i;
|
||||
char cont = '-';
|
||||
size_t len;
|
||||
ssize_t ret;
|
||||
|
||||
|
@ -462,8 +470,25 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
|
|||
msg = log_from_idx(user->idx);
|
||||
ts_usec = msg->ts_nsec;
|
||||
do_div(ts_usec, 1000);
|
||||
len = sprintf(user->buf, "%u,%llu,%llu;",
|
||||
(msg->facility << 3) | msg->level, user->seq, ts_usec);
|
||||
|
||||
/*
|
||||
* If we couldn't merge continuation line fragments during the print,
|
||||
* export the stored flags to allow an optional external merge of the
|
||||
* records. Merging the records isn't always neccessarily correct, like
|
||||
* when we hit a race during printing. In most cases though, it produces
|
||||
* better readable output. 'c' in the record flags mark the first
|
||||
* fragment of a line, '+' the following.
|
||||
*/
|
||||
if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT))
|
||||
cont = 'c';
|
||||
else if ((msg->flags & LOG_CONT) ||
|
||||
((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
|
||||
cont = '+';
|
||||
|
||||
len = sprintf(user->buf, "%u,%llu,%llu,%c;",
|
||||
(msg->facility << 3) | msg->level,
|
||||
user->seq, ts_usec, cont);
|
||||
user->prev = msg->flags;
|
||||
|
||||
/* escape non-printable characters */
|
||||
for (i = 0; i < msg->text_len; i++) {
|
||||
|
@ -646,6 +671,15 @@ void log_buf_kexec_setup(void)
|
|||
VMCOREINFO_SYMBOL(log_buf_len);
|
||||
VMCOREINFO_SYMBOL(log_first_idx);
|
||||
VMCOREINFO_SYMBOL(log_next_idx);
|
||||
/*
|
||||
* Export struct log size and field offsets. User space tools can
|
||||
* parse it and detect any changes to structure down the line.
|
||||
*/
|
||||
VMCOREINFO_STRUCT_SIZE(log);
|
||||
VMCOREINFO_OFFSET(log, ts_nsec);
|
||||
VMCOREINFO_OFFSET(log, len);
|
||||
VMCOREINFO_OFFSET(log, text_len);
|
||||
VMCOREINFO_OFFSET(log, dict_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -876,7 +910,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev,
|
|||
|
||||
if (buf) {
|
||||
if (print_prefix(msg, syslog, NULL) +
|
||||
text_len + 1>= size - len)
|
||||
text_len + 1 >= size - len)
|
||||
break;
|
||||
|
||||
if (prefix)
|
||||
|
@ -907,7 +941,7 @@ static int syslog_print(char __user *buf, int size)
|
|||
struct log *msg;
|
||||
int len = 0;
|
||||
|
||||
text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
|
||||
text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
|
||||
if (!text)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -930,7 +964,8 @@ static int syslog_print(char __user *buf, int size)
|
|||
|
||||
skip = syslog_partial;
|
||||
msg = log_from_idx(syslog_idx);
|
||||
n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX);
|
||||
n = msg_print_text(msg, syslog_prev, true, text,
|
||||
LOG_LINE_MAX + PREFIX_MAX);
|
||||
if (n - syslog_partial <= size) {
|
||||
/* message fits into buffer, move forward */
|
||||
syslog_idx = log_next(syslog_idx);
|
||||
|
@ -969,7 +1004,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
|
|||
char *text;
|
||||
int len = 0;
|
||||
|
||||
text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
|
||||
text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
|
||||
if (!text)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1022,7 +1057,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
|
|||
struct log *msg = log_from_idx(idx);
|
||||
int textlen;
|
||||
|
||||
textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX);
|
||||
textlen = msg_print_text(msg, prev, true, text,
|
||||
LOG_LINE_MAX + PREFIX_MAX);
|
||||
if (textlen < 0) {
|
||||
len = textlen;
|
||||
break;
|
||||
|
@ -1349,20 +1385,36 @@ static struct cont {
|
|||
u64 ts_nsec; /* time of first print */
|
||||
u8 level; /* log level of first message */
|
||||
u8 facility; /* log level of first message */
|
||||
enum log_flags flags; /* prefix, newline flags */
|
||||
bool flushed:1; /* buffer sealed and committed */
|
||||
} cont;
|
||||
|
||||
static void cont_flush(void)
|
||||
static void cont_flush(enum log_flags flags)
|
||||
{
|
||||
if (cont.flushed)
|
||||
return;
|
||||
if (cont.len == 0)
|
||||
return;
|
||||
|
||||
log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec,
|
||||
NULL, 0, cont.buf, cont.len);
|
||||
|
||||
cont.flushed = true;
|
||||
if (cont.cons) {
|
||||
/*
|
||||
* If a fragment of this line was directly flushed to the
|
||||
* console; wait for the console to pick up the rest of the
|
||||
* line. LOG_NOCONS suppresses a duplicated output.
|
||||
*/
|
||||
log_store(cont.facility, cont.level, flags | LOG_NOCONS,
|
||||
cont.ts_nsec, NULL, 0, cont.buf, cont.len);
|
||||
cont.flags = flags;
|
||||
cont.flushed = true;
|
||||
} else {
|
||||
/*
|
||||
* If no fragment of this line ever reached the console,
|
||||
* just submit it to the store and free the buffer.
|
||||
*/
|
||||
log_store(cont.facility, cont.level, flags, 0,
|
||||
NULL, 0, cont.buf, cont.len);
|
||||
cont.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool cont_add(int facility, int level, const char *text, size_t len)
|
||||
|
@ -1371,7 +1423,8 @@ static bool cont_add(int facility, int level, const char *text, size_t len)
|
|||
return false;
|
||||
|
||||
if (cont.len + len > sizeof(cont.buf)) {
|
||||
cont_flush();
|
||||
/* the line gets too long, split it up in separate records */
|
||||
cont_flush(LOG_CONT);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1380,12 +1433,17 @@ static bool cont_add(int facility, int level, const char *text, size_t len)
|
|||
cont.level = level;
|
||||
cont.owner = current;
|
||||
cont.ts_nsec = local_clock();
|
||||
cont.flags = 0;
|
||||
cont.cons = 0;
|
||||
cont.flushed = false;
|
||||
}
|
||||
|
||||
memcpy(cont.buf + cont.len, text, len);
|
||||
cont.len += len;
|
||||
|
||||
if (cont.len > (sizeof(cont.buf) * 80) / 100)
|
||||
cont_flush(LOG_CONT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1394,7 +1452,7 @@ static size_t cont_print_text(char *text, size_t size)
|
|||
size_t textlen = 0;
|
||||
size_t len;
|
||||
|
||||
if (cont.cons == 0) {
|
||||
if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) {
|
||||
textlen += print_time(cont.ts_nsec, text);
|
||||
size -= textlen;
|
||||
}
|
||||
|
@ -1409,7 +1467,8 @@ static size_t cont_print_text(char *text, size_t size)
|
|||
}
|
||||
|
||||
if (cont.flushed) {
|
||||
text[textlen++] = '\n';
|
||||
if (cont.flags & LOG_NEWLINE)
|
||||
text[textlen++] = '\n';
|
||||
/* got everything, release buffer */
|
||||
cont.len = 0;
|
||||
}
|
||||
|
@ -1507,7 +1566,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|||
* or another task also prints continuation lines.
|
||||
*/
|
||||
if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
|
||||
cont_flush();
|
||||
cont_flush(LOG_NEWLINE);
|
||||
|
||||
/* buffer line if possible, otherwise store it right away */
|
||||
if (!cont_add(facility, level, text, text_len))
|
||||
|
@ -1525,7 +1584,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
|||
if (cont.len && cont.owner == current) {
|
||||
if (!(lflags & LOG_PREFIX))
|
||||
stored = cont_add(facility, level, text, text_len);
|
||||
cont_flush();
|
||||
cont_flush(LOG_NEWLINE);
|
||||
}
|
||||
|
||||
if (!stored)
|
||||
|
@ -1616,9 +1675,20 @@ asmlinkage int printk(const char *fmt, ...)
|
|||
}
|
||||
EXPORT_SYMBOL(printk);
|
||||
|
||||
#else
|
||||
#else /* CONFIG_PRINTK */
|
||||
|
||||
#define LOG_LINE_MAX 0
|
||||
#define PREFIX_MAX 0
|
||||
#define LOG_LINE_MAX 0
|
||||
static u64 syslog_seq;
|
||||
static u32 syslog_idx;
|
||||
static u64 console_seq;
|
||||
static u32 console_idx;
|
||||
static enum log_flags syslog_prev;
|
||||
static u64 log_first_seq;
|
||||
static u32 log_first_idx;
|
||||
static u64 log_next_seq;
|
||||
static enum log_flags console_prev;
|
||||
static struct cont {
|
||||
size_t len;
|
||||
size_t cons;
|
||||
|
@ -1902,10 +1972,34 @@ void wake_up_klogd(void)
|
|||
this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP);
|
||||
}
|
||||
|
||||
/* the next printk record to write to the console */
|
||||
static u64 console_seq;
|
||||
static u32 console_idx;
|
||||
static enum log_flags console_prev;
|
||||
static void console_cont_flush(char *text, size_t size)
|
||||
{
|
||||
unsigned long flags;
|
||||
size_t len;
|
||||
|
||||
raw_spin_lock_irqsave(&logbuf_lock, flags);
|
||||
|
||||
if (!cont.len)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* We still queue earlier records, likely because the console was
|
||||
* busy. The earlier ones need to be printed before this one, we
|
||||
* did not flush any fragment so far, so just let it queue up.
|
||||
*/
|
||||
if (console_seq < log_next_seq && !cont.cons)
|
||||
goto out;
|
||||
|
||||
len = cont_print_text(text, size);
|
||||
raw_spin_unlock(&logbuf_lock);
|
||||
stop_critical_timings();
|
||||
call_console_drivers(cont.level, text, len);
|
||||
start_critical_timings();
|
||||
local_irq_restore(flags);
|
||||
return;
|
||||
out:
|
||||
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* console_unlock - unlock the console system
|
||||
|
@ -1923,7 +2017,7 @@ static enum log_flags console_prev;
|
|||
*/
|
||||
void console_unlock(void)
|
||||
{
|
||||
static char text[LOG_LINE_MAX];
|
||||
static char text[LOG_LINE_MAX + PREFIX_MAX];
|
||||
static u64 seen_seq;
|
||||
unsigned long flags;
|
||||
bool wake_klogd = false;
|
||||
|
@ -1937,19 +2031,7 @@ void console_unlock(void)
|
|||
console_may_schedule = 0;
|
||||
|
||||
/* flush buffered message fragment immediately to console */
|
||||
raw_spin_lock_irqsave(&logbuf_lock, flags);
|
||||
if (cont.len && (cont.cons < cont.len || cont.flushed)) {
|
||||
size_t len;
|
||||
|
||||
len = cont_print_text(text, sizeof(text));
|
||||
raw_spin_unlock(&logbuf_lock);
|
||||
stop_critical_timings();
|
||||
call_console_drivers(cont.level, text, len);
|
||||
start_critical_timings();
|
||||
local_irq_restore(flags);
|
||||
} else
|
||||
raw_spin_unlock_irqrestore(&logbuf_lock, flags);
|
||||
|
||||
console_cont_flush(text, sizeof(text));
|
||||
again:
|
||||
for (;;) {
|
||||
struct log *msg;
|
||||
|
@ -1986,6 +2068,7 @@ skip:
|
|||
* will properly dump everything later.
|
||||
*/
|
||||
msg->flags &= ~LOG_NOCONS;
|
||||
console_prev = msg->flags;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue