Release 4.11 drivers/tty/serial/8250/8250_core.c
/*
* Universal/legacy driver for 8250/16550-type serial ports
*
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
*
* Copyright (C) 2001 Russell King.
*
* Supports: ISA-compatible 8250/16550 ports
* PNP 8250/16550 ports
* early_serial_setup() ports
* userspace-configurable "phantom" ports
* "serial8250" platform devices
* serial8250_register_8250_port() ports
*
* 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.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/ratelimit.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/nmi.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
#ifdef CONFIG_SPARC
#include <linux/sunserialcore.h>
#endif
#include <asm/irq.h>
#include "8250.h"
/*
* Configuration:
* share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
* is unsafe when used on edge-triggered interrupts.
*/
static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
static struct uart_driver serial8250_reg;
static unsigned int skip_txen_test;
/* force skip of txen test at init time */
#define PASS_LIMIT 512
#include <asm/serial.h>
/*
* SERIAL_PORT_DFNS tells us about built-in ports that have no
* standard enumeration mechanism. Platforms that can find all
* serial ports via mechanisms like ACPI or PCI need not supply it.
*/
#ifndef SERIAL_PORT_DFNS
#define SERIAL_PORT_DFNS
#endif
static const struct old_serial_port old_serial_port[] = {
SERIAL_PORT_DFNS /* defined in asm/serial.h */
};
#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
#ifdef CONFIG_SERIAL_8250_RSA
#define PORT_RSA_MAX 4
static unsigned long probe_rsa[PORT_RSA_MAX];
static unsigned int probe_rsa_count;
#endif /* CONFIG_SERIAL_8250_RSA */
struct irq_info {
struct hlist_node node;
int irq;
spinlock_t lock; /* Protects list not the hash */
struct list_head *head;
};
#define NR_IRQ_HASH 32
/* Can be adjusted later */
static struct hlist_head irq_lists[NR_IRQ_HASH];
static DEFINE_MUTEX(hash_mutex); /* Used to walk the hash */
/*
* This is the serial driver's interrupt routine.
*
* Arjan thinks the old way was overly complex, so it got simplified.
* Alan disagrees, saying that need the complexity to handle the weird
* nature of ISA shared interrupts. (This is a special exception.)
*
* In order to handle ISA shared interrupts properly, we need to check
* that all ports have been serviced, and therefore the ISA interrupt
* line has been de-asserted.
*
* This means we need to loop through all ports. checking that they
* don't have an interrupt pending.
*/
static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
{
struct irq_info *i = dev_id;
struct list_head *l, *end = NULL;
int pass_counter = 0, handled = 0;
pr_debug("%s(%d): start\n", __func__, irq);
spin_lock(&i->lock);
l = i->head;
do {
struct uart_8250_port *up;
struct uart_port *port;
up = list_entry(l, struct uart_8250_port, list);
port = &up->port;
if (port->handle_irq(port)) {
handled = 1;
end = NULL;
} else if (end == NULL)
end = l;
l = l->next;
if (l == i->head && pass_counter++ > PASS_LIMIT) {
/* If we hit this, we're dead. */
printk_ratelimited(KERN_ERR
"serial8250: too much work for irq%d\n", irq);
break;
}
} while (l != end);
spin_unlock(&i->lock);
pr_debug("%s(%d): end\n", __func__, irq);
return IRQ_RETVAL(handled);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 144 | 77.84% | 1 | 16.67% |
Yoshihiro Yunomae | 17 | 9.19% | 1 | 16.67% |
Russell King | 14 | 7.57% | 3 | 50.00% |
Jiri Slaby | 10 | 5.41% | 1 | 16.67% |
Total | 185 | 100.00% | 6 | 100.00% |
/*
* To support ISA shared interrupts, we need to have one interrupt
* handler that ensures that the IRQ line has been deasserted
* before returning. Failing to do this will result in the IRQ
* line being stuck active, and, since ISA irqs are edge triggered,
* no more IRQs will be seen.
*/
static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
{
spin_lock_irq(&i->lock);
if (!list_empty(i->head)) {
if (i->head == &up->list)
i->head = i->head->next;
list_del(&up->list);
} else {
BUG_ON(i->head != &up->list);
i->head = NULL;
}
spin_unlock_irq(&i->lock);
/* List empty so throw away the hash node */
if (i->head == NULL) {
hlist_del(&i->node);
kfree(i);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 88 | 74.58% | 1 | 50.00% |
Yoshihiro Yunomae | 30 | 25.42% | 1 | 50.00% |
Total | 118 | 100.00% | 2 | 100.00% |
static int serial_link_irq_chain(struct uart_8250_port *up)
{
struct hlist_head *h;
struct hlist_node *n;
struct irq_info *i;
int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
mutex_lock(&hash_mutex);
h = &irq_lists[up->port.irq % NR_IRQ_HASH];
hlist_for_each(n, h) {
i = hlist_entry(n, struct irq_info, node);
if (i->irq == up->port.irq)
break;
}
if (n == NULL) {
i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
if (i == NULL) {
mutex_unlock(&hash_mutex);
return -ENOMEM;
}
spin_lock_init(&i->lock);
i->irq = up->port.irq;
hlist_add_head(&i->node, h);
}
mutex_unlock(&hash_mutex);
spin_lock_irq(&i->lock);
if (i->head) {
list_add(&up->list, i->head);
spin_unlock_irq(&i->lock);
ret = 0;
} else {
INIT_LIST_HEAD(&up->list);
i->head = &up->list;
spin_unlock_irq(&i->lock);
irq_flags |= up->port.irqflags;
ret = request_irq(up->port.irq, serial8250_interrupt,
irq_flags, "serial", i);
if (ret < 0)
serial_do_unlink(i, up);
}
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 192 | 68.57% | 1 | 11.11% |
Yoshihiro Yunomae | 51 | 18.21% | 1 | 11.11% |
Russell King | 25 | 8.93% | 2 | 22.22% |
Matt Schulte | 5 | 1.79% | 2 | 22.22% |
Paul Gortmaker | 3 | 1.07% | 1 | 11.11% |
Manuel Lauss | 2 | 0.71% | 1 | 11.11% |
Stephen Warren | 2 | 0.71% | 1 | 11.11% |
Total | 280 | 100.00% | 9 | 100.00% |
static void serial_unlink_irq_chain(struct uart_8250_port *up)
{
/*
* yes, some broken gcc emit "warning: 'i' may be used uninitialized"
* but no, we are not going to take a patch that assigns NULL below.
*/
struct irq_info *i;
struct hlist_node *n;
struct hlist_head *h;
mutex_lock(&hash_mutex);
h = &irq_lists[up->port.irq % NR_IRQ_HASH];
hlist_for_each(n, h) {
i = hlist_entry(n, struct irq_info, node);
if (i->irq == up->port.irq)
break;
}
BUG_ON(n == NULL);
BUG_ON(i->head == NULL);
if (list_empty(i->head))
free_irq(up->port.irq, i);
serial_do_unlink(i, up);
mutex_unlock(&hash_mutex);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 117 | 90.70% | 1 | 50.00% |
Sebastian Andrzej Siewior | 12 | 9.30% | 1 | 50.00% |
Total | 129 | 100.00% | 2 | 100.00% |
/*
* This function is used to handle ports that do not have an
* interrupt. This doesn't work very well for 16450's, but gives
* barely passable results for a 16550A. (Although at the expense
* of much CPU overhead).
*/
static void serial8250_timeout(unsigned long data)
{
struct uart_8250_port *up = (struct uart_8250_port *)data;
up->port.handle_irq(&up->port);
mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 46 | 88.46% | 1 | 50.00% |
Alan Cox | 6 | 11.54% | 1 | 50.00% |
Total | 52 | 100.00% | 2 | 100.00% |
static void serial8250_backup_timeout(unsigned long data)
{
struct uart_8250_port *up = (struct uart_8250_port *)data;
unsigned int iir, ier = 0, lsr;
unsigned long flags;
spin_lock_irqsave(&up->port.lock, flags);
/*
* Must disable interrupts or else we risk racing with the interrupt
* based handler.
*/
if (up->port.irq) {
ier = serial_in(up, UART_IER);
serial_out(up, UART_IER, 0);
}
iir = serial_in(up, UART_IIR);
/*
* This should be a safe test for anyone who doesn't trust the
* IIR bits on their UART, but it's specifically designed for
* the "Diva" UART used on the management processor on many HP
* ia64 and parisc boxes.
*/
lsr = serial_in(up, UART_LSR);
up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
(!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
(lsr & UART_LSR_THRE)) {
iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
iir |= UART_IIR_THRI;
}
if (!(iir & UART_IIR_NO_INT))
serial8250_tx_chars(up);
if (up->port.irq)
serial_out(up, UART_IER, ier);
spin_unlock_irqrestore(&up->port.lock, flags);
/* Standard timer interval plus 0.2s to keep the port running */
mod_timer(&up->timer,
jiffies + uart_poll_timeout(&up->port) + HZ / 5);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 215 | 94.30% | 2 | 66.67% |
Alan Cox | 13 | 5.70% | 1 | 33.33% |
Total | 228 | 100.00% | 3 | 100.00% |
static int univ8250_setup_irq(struct uart_8250_port *up)
{
struct uart_port *port = &up->port;
int retval = 0;
/*
* The above check will only give an accurate result the first time
* the port is opened so this value needs to be preserved.
*/
if (up->bugs & UART_BUG_THRE) {
pr_debug("ttyS%d - using backup timer\n", serial_index(port));
up->timer.function = serial8250_backup_timeout;
up->timer.data = (unsigned long)up;
mod_timer(&up->timer, jiffies +
uart_poll_timeout(port) + HZ / 5);
}
/*
* If the "interrupt" for this port doesn't correspond with any
* hardware interrupt, we use a timer-based system. The original
* driver used to do this with IRQ0.
*/
if (!port->irq) {
up->timer.data = (unsigned long)up;
mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
} else
retval = serial_link_irq_chain(up);
return retval;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 134 | 100.00% | 4 | 100.00% |
Total | 134 | 100.00% | 4 | 100.00% |
static void univ8250_release_irq(struct uart_8250_port *up)
{
struct uart_port *port = &up->port;
del_timer_sync(&up->timer);
up->timer.function = serial8250_timeout;
if (port->irq)
serial_unlink_irq_chain(up);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 48 | 100.00% | 2 | 100.00% |
Total | 48 | 100.00% | 2 | 100.00% |
#ifdef CONFIG_SERIAL_8250_RSA
static int serial8250_request_rsa_resource(struct uart_8250_port *up)
{
unsigned long start = UART_RSA_BASE << up->port.regshift;
unsigned int size = 8 << up->port.regshift;
struct uart_port *port = &up->port;
int ret = -EINVAL;
switch (port->iotype) {
case UPIO_HUB6:
case UPIO_PORT:
start += port->iobase;
if (request_region(start, size, "serial-rsa"))
ret = 0;
else
ret = -EBUSY;
break;
}
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 96 | 100.00% | 2 | 100.00% |
Total | 96 | 100.00% | 2 | 100.00% |
static void serial8250_release_rsa_resource(struct uart_8250_port *up)
{
unsigned long offset = UART_RSA_BASE << up->port.regshift;
unsigned int size = 8 << up->port.regshift;
struct uart_port *port = &up->port;
switch (port->iotype) {
case UPIO_HUB6:
case UPIO_PORT:
release_region(port->iobase + offset, size);
break;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 71 | 100.00% | 2 | 100.00% |
Total | 71 | 100.00% | 2 | 100.00% |
#endif
static const struct uart_ops *base_ops;
static struct uart_ops univ8250_port_ops;
static const struct uart_8250_ops univ8250_driver_ops = {
.setup_irq = univ8250_setup_irq,
.release_irq = univ8250_release_irq,
};
static struct uart_8250_port serial8250_ports[UART_NR];
/**
* serial8250_get_port - retrieve struct uart_8250_port
* @line: serial line number
*
* This function retrieves struct uart_8250_port for the specific line.
* This struct *must* *not* be used to perform a 8250 or serial core operation
* which is not accessible otherwise. Its only purpose is to make the struct
* accessible to the runtime-pm callbacks for context suspend/restore.
* The lock assumption made here is none because runtime-pm suspend/resume
* callbacks should not be invoked if there is any operation performed on the
* port.
*/
struct uart_8250_port *serial8250_get_port(int line)
{
return &serial8250_ports[line];
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 13 | 76.47% | 1 | 33.33% |
Paul Gortmaker | 3 | 17.65% | 1 | 33.33% |
Russell King | 1 | 5.88% | 1 | 33.33% |
Total | 17 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(serial8250_get_port);
static void (*serial8250_isa_config)(int port, struct uart_port *up,
u32 *capabilities);
void serial8250_set_isa_configurator(
void (*v)(int port, struct uart_port *up, u32 *capabilities))
{
serial8250_isa_config = v;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 23 | 82.14% | 1 | 33.33% |
Russell King | 4 | 14.29% | 1 | 33.33% |
Ed Blake | 1 | 3.57% | 1 | 33.33% |
Total | 28 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(serial8250_set_isa_configurator);
#ifdef CONFIG_SERIAL_8250_RSA
static void univ8250_config_port(struct uart_port *port, int flags)
{
struct uart_8250_port *up = up_to_u8250p(port);
up->probe &= ~UART_PROBE_RSA;
if (port->type == PORT_RSA) {
if (serial8250_request_rsa_resource(up) == 0)
up->probe |= UART_PROBE_RSA;
} else if (flags & UART_CONFIG_TYPE) {
int i;
for (i = 0; i < probe_rsa_count; i++) {
if (probe_rsa[i] == up->port.iobase) {
if (serial8250_request_rsa_resource(up) == 0)
up->probe |= UART_PROBE_RSA;
break;
}
}
}
base_ops->config_port(port, flags);
if (port->type != PORT_RSA && up->probe & UART_PROBE_RSA)
serial8250_release_rsa_resource(up);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 103 | 72.54% | 2 | 22.22% |
Russell King | 21 | 14.79% | 4 | 44.44% |
Alan Cox | 9 | 6.34% | 1 | 11.11% |
Paul Gortmaker | 7 | 4.93% | 1 | 11.11% |
David Daney | 2 | 1.41% | 1 | 11.11% |
Total | 142 | 100.00% | 9 | 100.00% |
static int univ8250_request_port(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
int ret;
ret = base_ops->request_port(port);
if (ret == 0 && port->type == PORT_RSA) {
ret = serial8250_request_rsa_resource(up);
if (ret < 0)
base_ops->release_port(port);
}
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 44 | 62.86% | 2 | 25.00% |
Russell King | 15 | 21.43% | 3 | 37.50% |
Alan Cox | 6 | 8.57% | 1 | 12.50% |
Sean Young | 3 | 4.29% | 1 | 12.50% |
Shmulik Ladkani | 2 | 2.86% | 1 | 12.50% |
Total | 70 | 100.00% | 8 | 100.00% |
static void univ8250_release_port(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
if (port->type == PORT_RSA)
serial8250_release_rsa_resource(up);
base_ops->release_port(port);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 23 | 56.10% | 1 | 20.00% |
Peter Hurley | 13 | 31.71% | 1 | 20.00% |
Jamie Iles | 3 | 7.32% | 1 | 20.00% |
Paul Gortmaker | 1 | 2.44% | 1 | 20.00% |
Andy Shevchenko | 1 | 2.44% | 1 | 20.00% |
Total | 41 | 100.00% | 5 | 100.00% |
static void univ8250_rsa_support(struct uart_ops *ops)
{
ops->config_port = univ8250_config_port;
ops->request_port = univ8250_request_port;
ops->release_port = univ8250_release_port;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 29 | 100.00% | 1 | 100.00% |
Total | 29 | 100.00% | 1 | 100.00% |
#else
#define univ8250_rsa_support(x) do { } while (0)
#endif /* CONFIG_SERIAL_8250_RSA */
static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
static int first = 1;
int i, irqflag = 0;
if (!first)
return;
first = 0;
if (nr_uarts > UART_NR)
nr_uarts = UART_NR;
for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
struct uart_port *port = &up->port;
port->line = i;
serial8250_init_port(up);
if (!base_ops)
base_ops = port->ops;
port->ops = &univ8250_port_ops;
init_timer(&up->timer);
up->timer.function = serial8250_timeout;
up->ops = &univ8250_driver_ops;
/*
* ALPHA_KLUDGE_MCR needs to be killed.
*/
up->mcr_mask = ~ALPHA_KLUDGE_MCR;
up->mcr_force = ALPHA_KLUDGE_MCR;
}
/* chain base port ops to support Remote Supervisor Adapter */
univ8250_port_ops = *base_ops;
univ8250_rsa_support(&univ8250_port_ops);
if (share_irqs)
irqflag = IRQF_SHARED;
for (i = 0, up = serial8250_ports;
i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
i++, up++) {
struct uart_port *port = &up->port;
port->iobase = old_serial_port[i].port;
port->irq = irq_canonicalize(old_serial_port[i].irq);
port->irqflags = 0;
port->uartclk = old_serial_port[i].baud_base * 16;
port->flags = old_serial_port[i].flags;
port->hub6 = 0;
port->membase = old_serial_port[i].iomem_base;
port->iotype = old_serial_port[i].io_type;
port->regshift = old_serial_port[i].iomem_reg_shift;
serial8250_set_defaults(up);
port->irqflags |= irqflag;
if (serial8250_isa_config != NULL)
serial8250_isa_config(i, &up->port, &up->capabilities);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 279 | 83.53% | 3 | 21.43% |
Russell King | 26 | 7.78% | 2 | 14.29% |
Paul Gortmaker | 12 | 3.59% | 2 | 14.29% |
Deepak Saxena | 4 | 1.20% | 1 | 7.14% |
Sebastian Andrzej Siewior | 4 | 1.20% | 1 | 7.14% |
Rabin Vincent | 3 | 0.90% | 1 | 7.14% |
Andrew Morton | 3 | 0.90% | 2 | 14.29% |
Jiri Slaby | 2 | 0.60% | 1 | 7.14% |
Alan Cox | 1 | 0.30% | 1 | 7.14% |
Total | 334 | 100.00% | 14 | 100.00% |
static void __init
serial8250_register_ports(struct uart_driver *drv, struct device *dev)
{
int i;
for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
if (up->port.type == PORT_8250_CIR)
continue;
if (up->port.dev)
continue;
up->port.dev = dev;
if (skip_txen_test)
up->port.flags |= UPF_NO_TXEN_TEST;
uart_add_one_port(drv, &up->port);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 67 | 69.79% | 1 | 14.29% |
Maciej S. Szmigiero | 11 | 11.46% | 1 | 14.29% |
Corey Minyard | 7 | 7.29% | 1 | 14.29% |
Russell King | 6 | 6.25% | 2 | 28.57% |
Sebastian Andrzej Siewior | 4 | 4.17% | 1 | 14.29% |
Paul Gortmaker | 1 | 1.04% | 1 | 14.29% |
Total | 96 | 100.00% | 7 | 100.00% |
#ifdef CONFIG_SERIAL_8250_CONSOLE
static void univ8250_console_write(struct console *co, const char *s,
unsigned int count)
{
struct uart_8250_port *up = &serial8250_ports[co->index];
serial8250_console_write(up, s, count);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 42 | 100.00% | 1 | 100.00% |
Total | 42 | 100.00% | 1 | 100.00% |
static int univ8250_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int retval;
/*
* Check whether an invalid uart number has been specified, and
* if so, search for the first available port that does have
* console support.
*/
if (co->index >= nr_uarts)
co->index = 0;
port = &serial8250_ports[co->index].port;
/* link port to console */
port->cons = co;
retval = serial8250_console_setup(port, options, false);
if (retval != 0)
port->cons = NULL;
return retval;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 83 | 100.00% | 3 | 100.00% |
Total | 83 | 100.00% | 3 | 100.00% |
/**
* univ8250_console_match - non-standard console matching
* @co: registering console
* @name: name from console command line
* @idx: index from console command line
* @options: ptr to option string from console command line
*
* Only attempts to match console command lines of the form:
* console=uart[8250],io|mmio|mmio16|mmio32,<addr>[,<options>]
* console=uart[8250],0x<addr>[,<options>]
* This form is used to register an initial earlycon boot console and
* replace it with the serial8250_console at 8250 driver init.
*
* Performs console setup for a match (as required by interface)
* If no <options> are specified, then assume the h/w is already setup.
*
* Returns 0 if console matches; otherwise non-zero to use default matching
*/
static int univ8250_console_match(struct console *co, char *name, int idx,
char *options)
{
char match[] = "uart"; /* 8250-specific earlycon name */
unsigned char iotype;
resource_size_t addr;
int i;
if (strncmp(name, match, 4) != 0)
return -ENODEV;
if (uart_parse_earlycon(options, &iotype, &addr, &options))
return -ENODEV;
/* try to match the port specified on the command line */
for (i = 0; i < nr_uarts; i++) {
struct uart_port *port = &serial8250_ports[i].port;
if (port->iotype != iotype)
continue;
if ((iotype == UPIO_MEM || iotype == UPIO_MEM16 ||
iotype == UPIO_MEM32 || iotype == UPIO_MEM32BE)
&& (port->mapbase != addr))
continue;
if (iotype == UPIO_PORT && port->iobase != addr)
continue;
co->index = i;
port->cons = co;
return serial8250_console_setup(port, options, true);
}
return -ENODEV;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 165 | 90.66% | 3 | 50.00% |
Masahiro Yamada | 8 | 4.40% | 1 | 16.67% |
Yinghai Lu | 8 | 4.40% | 1 | 16.67% |
Alexander Sverdlin | 1 | 0.55% | 1 | 16.67% |
Total | 182 | 100.00% | 6 | 100.00% |
static struct console univ8250_console = {
.name = "ttyS",
.write = univ8250_console_write,
.device = uart_console_device,
.setup = univ8250_console_setup,
.match = univ8250_console_match,
.flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1,
.data = &serial8250_reg,
};
static int __init univ8250_console_init(void)
{
if (nr_uarts == 0)
return -ENODEV;
serial8250_isa_init_ports();
register_console(&univ8250_console);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 14 | 45.16% | 1 | 20.00% |
Jan Kiszka | 10 | 32.26% | 1 | 20.00% |
Andrew Morton | 4 | 12.90% | 1 | 20.00% |
Peter Hurley | 2 | 6.45% | 1 | 20.00% |
Alan Cox | 1 | 3.23% | 1 | 20.00% |
Total | 31 | 100.00% | 5 | 100.00% |
console_initcall(univ8250_console_init);
#define SERIAL8250_CONSOLE (&univ8250_console)
#else
#define SERIAL8250_CONSOLE NULL
#endif
static struct uart_driver serial8250_reg = {
.owner = THIS_MODULE,
.driver_name = "serial",
.dev_name = "ttyS",
.major = TTY_MAJOR,
.minor = 64,
.cons = SERIAL8250_CONSOLE,
};
/*
* early_serial_setup - early registration for 8250 ports
*
* Setup an 8250 port structure prior to console initialisation. Use
* after console initialisation will cause undefined behaviour.
*/
int __init early_serial_setup(struct uart_port *port)
{
struct uart_port *p;
if (port->line >= ARRAY_SIZE(serial8250_ports) || nr_uarts == 0)
return -ENODEV;
serial8250_isa_init_ports();
p = &serial8250_ports[port->line].port;
p->iobase = port->iobase;
p->membase = port->membase;
p->irq = port->irq;
p->irqflags = port->irqflags;
p->uartclk = port->uartclk;
p->fifosize = port->fifosize;
p->regshift = port->regshift;
p->iotype = port->iotype;
p->flags = port->flags;
p->mapbase = port->mapbase;
p->mapsize = port->mapsize;
p->private_data = port->private_data;
p->type = port->type;
p->line = port->line;
serial8250_set_defaults(up_to_u8250p(p));
if (port->serial_in)
p->serial_in = port->serial_in;
if (port->serial_out)
p->serial_out = port->serial_out;
if (port->handle_irq)
p->handle_irq = port->handle_irq;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Daney | 113 | 52.56% | 2 | 18.18% |
Christoph Hellwig | 18 | 8.37% | 1 | 9.09% |
Helge Deller | 16 | 7.44% | 1 | 9.09% |
Russell King | 15 | 6.98% | 1 | 9.09% |
Andrew Morton | 15 | 6.98% | 1 | 9.09% |
Jamie Iles | 14 | 6.51% | 1 | 9.09% |
Vikram Pandita | 8 | 3.72% | 1 | 9.09% |
Måns Rullgård | 8 | 3.72% | 1 | 9.09% |
Peter Hurley | 4 | 1.86% | 1 | 9.09% |
Jan Kiszka | 4 | 1.86% | 1 | 9.09% |
Total | 215 | 100.00% | 11 | 100.00% |
/**
* serial8250_suspend_port - suspend one serial port
* @line: serial line number
*
* Suspend one serial port.
*/
void serial8250_suspend_port(int line)
{
struct uart_8250_port *up = &serial8250_ports[line];
struct uart_port *port = &up->port;
if (!console_suspend_enabled && uart_console(port) &&
port->type != PORT_8250) {
unsigned char canary = 0xa5;
serial_out(up, UART_SCR, canary);
if (serial_in(up, UART_SCR) == canary)
up->canary = canary;
}
uart_suspend_port(&serial8250_reg, port);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 71 | 81.61% | 2 | 66.67% |
Russell King | 16 | 18.39% | 1 | 33.33% |
Total | 87 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(serial8250_suspend_port);
/**
* serial8250_resume_port - resume one serial port
* @line: serial line number
*
* Resume one serial port.
*/
void serial8250_resume_port(int line)
{
struct uart_8250_port *up = &serial8250_ports[line];
struct uart_port *port = &up->port;
up->canary = 0;
if (up->capabilities & UART_NATSEMI) {
/* Ensure it's still in high speed mode */
serial_port_out(port, UART_LCR, 0xE0);
ns16550a_goto_highspeed(up);
serial_port_out(port, UART_LCR, 0);
port->uartclk = 921600*16;
}
uart_resume_port(&serial8250_reg, port);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
David Woodhouse | 40 | 47.06% | 1 | 14.29% |
Russell King | 16 | 18.82% | 1 | 14.29% |
Paul Gortmaker | 15 | 17.65% | 2 | 28.57% |
Yin Kangkai | 8 | 9.41% | 2 | 28.57% |
Peter Hurley | 6 | 7.06% | 1 | 14.29% |
Total | 85 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL(serial8250_resume_port);
/*
* Register a set of serial devices attached to a platform device. The
* list is terminated with a zero flags entry, which means we expect
* all entries to have at least UPF_BOOT_AUTOCONF set.
*/
static int serial8250_probe(struct platform_device *dev)
{
struct plat_serial8250_port *p = dev_get_platdata(&dev->dev);
struct uart_8250_port uart;
int ret, i, irqflag = 0;
memset(&uart, 0, sizeof(uart));
if (share_irqs)
irqflag = IRQF_SHARED;
for (i = 0; p && p->flags != 0; p++, i++) {
uart.port.iobase = p->iobase;
uart.port.membase = p->membase;
uart.port.irq = p->irq;
uart.port.irqflags = p->irqflags;
uart.port.uartclk = p->uartclk;
uart.port.regshift = p->regshift;
uart.port.iotype = p->iotype;
uart.port.flags = p->flags;
uart.port.mapbase = p->mapbase;
uart.port.hub6 = p->hub6;
uart.port.private_data = p->private_data;
uart.port.type = p->type;
uart.port.serial_in = p->serial_in;
uart.port.serial_out = p->serial_out;
uart.port.handle_irq = p->handle_irq;
uart.port.handle_break = p->handle_break;
uart.port.set_termios = p->set_termios;
uart.port.set_ldisc = p->set_ldisc;
uart.port.get_mctrl = p->get_mctrl;
uart.port.pm = p->pm;
uart.port.dev = &dev->dev;
uart.port.irqflags |= irqflag;
ret = serial8250_register_8250_port(&uart);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
"(IO%lx MEM%llx IRQ%d): %d\n", i,
p->iobase, (unsigned long long)p->mapbase,
p->irq, ret);
}
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 188 | 53.71% | 3 | 17.65% |
Alan Cox | 46 | 13.14% | 1 | 5.88% |
David Daney | 24 | 6.86% | 2 | 11.76% |
André Goddard Rosa | 13 | 3.71% | 1 | 5.88% |
Ed Blake | 10 | 2.86% | 1 | 5.88% |
Wan Ahmad Zainie | 10 | 2.86% | 1 | 5.88% |
Vikram Pandita | 9 | 2.57% | 1 | 5.88% |
Philippe Langlais | 8 | 2.29% | 1 | 5.88% |
Dan J Williams | 8 | 2.29% | 1 | 5.88% |
Will Newton | 8 | 2.29% | 1 | 5.88% |
Manuel Lauss | 8 | 2.29% | 1 | 5.88% |
Jamie Iles | 8 | 2.29% | 1 | 5.88% |
Josh Boyer | 6 | 1.71% | 1 | 5.88% |
Jingoo Han | 4 | 1.14% | 1 | 5.88% |
Total | 350 | 100.00% | 17 | 100.00% |
/*
* Remove serial ports registered against a platform device.
*/
static int serial8250_remove(struct platform_device *dev)
{
int i;
for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
if (up->port.dev == &dev->dev)
serial8250_unregister_port(i);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 60 | 98.36% | 2 | 66.67% |
Kyle McMartin | 1 | 1.64% | 1 | 33.33% |
Total | 61 | 100.00% | 3 | 100.00% |
static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
uart_suspend_port(&serial8250_reg, &up->port);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 77 | 98.72% | 3 | 75.00% |
Pavel Machek | 1 | 1.28% | 1 | 25.00% |
Total | 78 | 100.00% | 4 | 100.00% |
static int serial8250_resume(struct platform_device *dev)
{
int i;
for (i = 0; i < UART_NR; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
serial8250_resume_port(i);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 67 | 97.10% | 2 | 66.67% |
David Woodhouse | 2 | 2.90% | 1 | 33.33% |
Total | 69 | 100.00% | 3 | 100.00% |
static struct platform_driver serial8250_isa_driver = {
.probe = serial8250_probe,
.remove = serial8250_remove,
.suspend = serial8250_suspend,
.resume = serial8250_resume,
.driver = {
.name = "serial8250",
},
};
/*
* This "device" covers _all_ ISA 8250-compatible serial devices listed
* in the table in include/asm/serial.h
*/
static struct platform_device *serial8250_isa_devs;
/*
* serial8250_register_8250_port and serial8250_unregister_port allows for
* 16x50 serial ports to be configured at run-time, to support PCMCIA
* modems and PCI multiport cards.
*/
static DEFINE_MUTEX(serial_mutex);
static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
{
int i;
/*
* First, find a port entry which matches.
*/
for (i = 0; i < nr_uarts; i++)
if (uart_match_port(&serial8250_ports[i].port, port))
return &serial8250_ports[i];
/* try line number first if still available */
i = port->line;
if (i < nr_uarts && serial8250_ports[i].port.type == PORT_UNKNOWN &&
serial8250_ports[i].port.iobase == 0)
return &serial8250_ports[i];
/*
* We didn't find a matching entry, so look for the first
* free entry. We look for one which hasn't been previously
* used (indicated by zero iobase).
*/
for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
serial8250_ports[i].port.iobase == 0)
return &serial8250_ports[i];
/*
* That also failed. Last resort is to find any entry which
* doesn't have a real port associated with it.
*/
for (i = 0; i < nr_uarts; i++)
if (serial8250_ports[i].port.type == PORT_UNKNOWN)
return &serial8250_ports[i];
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 131 | 74.43% | 1 | 33.33% |
Sebastian Andrzej Siewior | 42 | 23.86% | 1 | 33.33% |
Kyle McMartin | 3 | 1.70% | 1 | 33.33% |
Total | 176 | 100.00% | 3 | 100.00% |
/**
* serial8250_register_8250_port - register a serial port
* @up: serial port template
*
* Configure the serial port specified by the request. If the
* port exists and is in use, it is hung up and unregistered
* first.
*
* The port is then probed and if necessary the IRQ is autodetected
* If this fails an error is returned.
*
* On success the port is ready to use and the line number is returned.
*/
int serial8250_register_8250_port(struct uart_8250_port *up)
{
struct uart_8250_port *uart;
int ret = -ENOSPC;
if (up->port.uartclk == 0)
return -EINVAL;
mutex_lock(&serial_mutex);
uart = serial8250_find_match_or_unused(&up->port);
if (uart && uart->port.type != PORT_8250_CIR) {
if (uart->port.dev)
uart_remove_one_port(&serial8250_reg, &uart->port);
uart->port.iobase = up->port.iobase;
uart->port.membase = up->port.membase;
uart->port.irq = up->port.irq;
uart->port.irqflags = up->port.irqflags;
uart->port.uartclk = up->port.uartclk;
uart->port.fifosize = up->port.fifosize;
uart->port.regshift = up->port.regshift;
uart->port.iotype = up->port.iotype;
uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF;
uart->bugs = up->bugs;
uart->port.mapbase = up->port.mapbase;
uart->port.mapsize = up->port.mapsize;
uart->port.private_data = up->port.private_data;
uart->tx_loadsz = up->tx_loadsz;
uart->capabilities = up->capabilities;
uart->port.throttle = up->port.throttle;
uart->port.unthrottle = up->port.unthrottle;
uart->port.rs485_config = up->port.rs485_config;
uart->port.rs485 = up->port.rs485;
uart->dma = up->dma;
/* Take tx_loadsz from fifosize if it wasn't set separately */
if (uart->port.fifosize && !uart->tx_loadsz)
uart->tx_loadsz = uart->port.fifosize;
if (up->port.dev)
uart->port.dev = up->port.dev;
if (skip_txen_test)
uart->port.flags |= UPF_NO_TXEN_TEST;
if (up->port.flags & UPF_FIXED_TYPE)
uart->port.type = up->port.type;
serial8250_set_defaults(uart);
/* Possibly override default I/O functions. */
if (up->port.serial_in)
uart->port.serial_in = up->port.serial_in;
if (up->port.serial_out)
uart->port.serial_out = up->port.serial_out;
if (up->port.handle_irq)
uart->port.handle_irq = up->port.handle_irq;
/* Possibly override set_termios call */
if (up->port.set_termios)
uart->port.set_termios = up->port.set_termios;
if (up->port.set_ldisc)
uart->port.set_ldisc = up->port.set_ldisc;
if (up->port.get_mctrl)
uart->port.get_mctrl = up->port.get_mctrl;
if (up->port.set_mctrl)
uart->port.set_mctrl = up->port.set_mctrl;
if (up->port.startup)
uart->port.startup = up->port.startup;
if (up->port.shutdown)
uart->port.shutdown = up->port.shutdown;
if (up->port.pm)
uart->port.pm = up->port.pm;
if (up->port.handle_break)
uart->port.handle_break = up->port.handle_break;
if (up->dl_read)
uart->dl_read = up->dl_read;
if (up->dl_write)
uart->dl_write = up->dl_write;
if (uart->port.type != PORT_8250_CIR) {
if (serial8250_isa_config != NULL)
serial8250_isa_config(0, &uart->port,
&uart->capabilities);
ret = uart_add_one_port(&serial8250_reg,
&uart->port);
if (ret == 0)
ret = uart->port.line;
} else {
dev_info(uart->port.dev,
"skipping CIR port at 0x%lx / 0x%llx, IRQ %d\n",
uart->port.iobase,
(unsigned long long)uart->port.mapbase,
uart->port.irq);
ret = 0;
}
}
mutex_unlock(&serial_mutex);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 188 | 24.97% | 2 | 6.45% |
Magnus Damm | 118 | 15.67% | 1 | 3.23% |
Sebastian Andrzej Siewior | 62 | 8.23% | 2 | 6.45% |
Maciej S. Szmigiero | 53 | 7.04% | 1 | 3.23% |
Peter Hurley | 46 | 6.11% | 5 | 16.13% |
David Daney | 44 | 5.84% | 2 | 6.45% |
Heikki Krogerus | 40 | 5.31% | 2 | 6.45% |
Alan Cox | 29 | 3.85% | 2 | 6.45% |
Ricardo Ribalda Delgado | 26 | 3.45% | 2 | 6.45% |
Ed Blake | 20 | 2.66% | 1 | 3.23% |
Wan Ahmad Zainie | 20 | 2.66% | 1 | 3.23% |
Sean Young | 16 | 2.12% | 2 | 6.45% |
Philippe Langlais | 15 | 1.99% | 1 | 3.23% |
Manuel Lauss | 14 | 1.86% | 1 | 3.23% |
Jamie Iles | 14 | 1.86% | 1 | 3.23% |
Dan J Williams | 14 | 1.86% | 1 | 3.23% |
Måns Rullgård | 12 | 1.59% | 1 | 3.23% |
Vikram Pandita | 9 | 1.20% | 1 | 3.23% |
Will Newton | 9 | 1.20% | 1 | 3.23% |
Arjan van de Ven | 4 | 0.53% | 1 | 3.23% |
Total | 753 | 100.00% | 31 | 100.00% |
EXPORT_SYMBOL(serial8250_register_8250_port);
/**
* serial8250_unregister_port - remove a 16x50 serial port at runtime
* @line: serial line number
*
* Remove one serial port. This may not be called from interrupt
* context. We hand the port back to the our control.
*/
void serial8250_unregister_port(int line)
{
struct uart_8250_port *uart = &serial8250_ports[line];
mutex_lock(&serial_mutex);
if (uart->em485) {
unsigned long flags;
spin_lock_irqsave(&uart->port.lock, flags);
serial8250_em485_destroy(uart);
spin_unlock_irqrestore(&uart->port.lock, flags);
}
uart_remove_one_port(&serial8250_reg, &uart->port);
if (serial8250_isa_devs) {
uart->port.flags &= ~UPF_BOOT_AUTOCONF;
if (skip_txen_test)
uart->port.flags |= UPF_NO_TXEN_TEST;
uart->port.type = PORT_UNKNOWN;
uart->port.dev = &serial8250_isa_devs->dev;
uart->capabilities = 0;
uart_add_one_port(&serial8250_reg, &uart->port);
} else {
uart->port.dev = NULL;
}
mutex_unlock(&serial_mutex);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 94 | 59.87% | 3 | 37.50% |
Matwey V. Kornilov | 41 | 26.11% | 1 | 12.50% |
Peter Hurley | 13 | 8.28% | 2 | 25.00% |
Breno Leitão | 5 | 3.18% | 1 | 12.50% |
Arjan van de Ven | 4 | 2.55% | 1 | 12.50% |
Total | 157 | 100.00% | 8 | 100.00% |
EXPORT_SYMBOL(serial8250_unregister_port);
static int __init serial8250_init(void)
{
int ret;
if (nr_uarts == 0)
return -ENODEV;
serial8250_isa_init_ports();
pr_info("Serial: 8250/16550 driver, %d ports, IRQ sharing %sabled\n",
nr_uarts, share_irqs ? "en" : "dis");
#ifdef CONFIG_SPARC
ret = sunserial_register_minors(&serial8250_reg, UART_NR);
#else
serial8250_reg.nr = UART_NR;
ret = uart_register_driver(&serial8250_reg);
#endif
if (ret)
goto out;
ret = serial8250_pnp_init();
if (ret)
goto unreg_uart_drv;
serial8250_isa_devs = platform_device_alloc("serial8250",
PLAT8250_DEV_LEGACY);
if (!serial8250_isa_devs) {
ret = -ENOMEM;
goto unreg_pnp;
}
ret = platform_device_add(serial8250_isa_devs);
if (ret)
goto put_dev;
serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
ret = platform_driver_register(&serial8250_isa_driver);
if (ret == 0)
goto out;
platform_device_del(serial8250_isa_devs);
put_dev:
platform_device_put(serial8250_isa_devs);
unreg_pnp:
serial8250_pnp_exit();
unreg_uart_drv:
#ifdef CONFIG_SPARC
sunserial_unregister_minors(&serial8250_reg, UART_NR);
#else
uart_unregister_driver(&serial8250_reg);
#endif
out:
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 111 | 55.78% | 7 | 53.85% |
David S. Miller | 33 | 16.58% | 1 | 7.69% |
Dmitry Torokhov | 21 | 10.55% | 1 | 7.69% |
Sean Young | 20 | 10.05% | 1 | 7.69% |
Jan Kiszka | 10 | 5.03% | 1 | 7.69% |
Phillip Raffeck | 2 | 1.01% | 1 | 7.69% |
Dave Jones | 2 | 1.01% | 1 | 7.69% |
Total | 199 | 100.00% | 13 | 100.00% |
static void __exit serial8250_exit(void)
{
struct platform_device *isa_dev = serial8250_isa_devs;
/*
* This tells serial8250_unregister_port() not to re-register
* the ports (thereby making serial8250_isa_driver permanently
* in use.)
*/
serial8250_isa_devs = NULL;
platform_driver_unregister(&serial8250_isa_driver);
platform_device_unregister(isa_dev);
serial8250_pnp_exit();
#ifdef CONFIG_SPARC
sunserial_unregister_minors(&serial8250_reg, UART_NR);
#else
uart_unregister_driver(&serial8250_reg);
#endif
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Russell King | 38 | 67.86% | 4 | 66.67% |
David S. Miller | 15 | 26.79% | 1 | 16.67% |
Sean Young | 3 | 5.36% | 1 | 16.67% |
Total | 56 | 100.00% | 6 | 100.00% |
module_init(serial8250_init);
module_exit(serial8250_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices (unsafe)");
module_param(nr_uarts, uint, 0644);
MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
module_param(skip_txen_test, uint, 0644);
MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
#ifdef CONFIG_SERIAL_8250_RSA
module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
#endif
MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
#ifndef MODULE
/* This module was renamed to 8250_core in 3.7. Keep the old "8250" name
* working as well for the module options so we don't break people. We
* need to keep the names identical and the convenient macros will happily
* refuse to let us do that by failing the build with redefinition errors
* of global variables. So we stick them inside a dummy function to avoid
* those conflicts. The options still get parsed, and the redefined
* MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
*
* This is hacky. I'm sorry.
*/
static void __used s8250_options(void)
{
#undef MODULE_PARAM_PREFIX
#define MODULE_PARAM_PREFIX "8250_core."
module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644);
module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644);
module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644);
#ifdef CONFIG_SERIAL_8250_RSA
__module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
¶m_array_ops, .arr = &__param_arr_probe_rsa,
0444, -1, 0);
#endif
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Josh Boyer | 80 | 96.39% | 1 | 33.33% |
Jani Nikula | 2 | 2.41% | 1 | 33.33% |
Jiri Slaby | 1 | 1.20% | 1 | 33.33% |
Total | 83 | 100.00% | 3 | 100.00% |
#else
MODULE_ALIAS("8250_core");
#endif
#endif
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Peter Hurley | 2239 | 41.48% | 15 | 10.20% |
Russell King | 1466 | 27.16% | 31 | 21.09% |
David Daney | 183 | 3.39% | 3 | 2.04% |
Alan Cox | 138 | 2.56% | 7 | 4.76% |
Sebastian Andrzej Siewior | 127 | 2.35% | 5 | 3.40% |
Magnus Damm | 123 | 2.28% | 1 | 0.68% |
Yoshihiro Yunomae | 98 | 1.82% | 1 | 0.68% |
Josh Boyer | 98 | 1.82% | 2 | 1.36% |
Maciej S. Szmigiero | 64 | 1.19% | 1 | 0.68% |
David S. Miller | 55 | 1.02% | 2 | 1.36% |
Paul Gortmaker | 50 | 0.93% | 3 | 2.04% |
Sean Young | 43 | 0.80% | 2 | 1.36% |
David Woodhouse | 42 | 0.78% | 1 | 0.68% |
Matwey V. Kornilov | 41 | 0.76% | 1 | 0.68% |
Heikki Krogerus | 40 | 0.74% | 2 | 1.36% |
Jamie Iles | 39 | 0.72% | 2 | 1.36% |
Ed Blake | 32 | 0.59% | 2 | 1.36% |
Dave Jones | 30 | 0.56% | 1 | 0.68% |
Wan Ahmad Zainie | 30 | 0.56% | 1 | 0.68% |
Ricardo Ribalda Delgado | 29 | 0.54% | 3 | 2.04% |
Vikram Pandita | 26 | 0.48% | 1 | 0.68% |
Dan J Williams | 25 | 0.46% | 2 | 1.36% |
Andrew Morton | 25 | 0.46% | 4 | 2.72% |
Jan Kiszka | 24 | 0.44% | 1 | 0.68% |
Manuel Lauss | 24 | 0.44% | 2 | 1.36% |
Philippe Langlais | 23 | 0.43% | 1 | 0.68% |
Chuck Ebbert | 22 | 0.41% | 1 | 0.68% |
Dmitry Torokhov | 21 | 0.39% | 1 | 0.68% |
Måns Rullgård | 20 | 0.37% | 1 | 0.68% |
Jiri Slaby | 20 | 0.37% | 5 | 3.40% |
Christoph Hellwig | 18 | 0.33% | 1 | 0.68% |
Will Newton | 17 | 0.31% | 1 | 0.68% |
Helge Deller | 16 | 0.30% | 1 | 0.68% |
Arjan van de Ven | 14 | 0.26% | 2 | 1.36% |
André Goddard Rosa | 13 | 0.24% | 1 | 0.68% |
Anton Wuerfel | 12 | 0.22% | 3 | 2.04% |
Yinghai Lu | 11 | 0.20% | 1 | 0.68% |
Björn Helgaas | 9 | 0.17% | 1 | 0.68% |
Masahiro Yamada | 9 | 0.17% | 1 | 0.68% |
Al Viro | 8 | 0.15% | 2 | 1.36% |
Yin Kangkai | 8 | 0.15% | 2 | 1.36% |
Corey Minyard | 7 | 0.13% | 1 | 0.68% |
Breno Leitão | 5 | 0.09% | 1 | 0.68% |
Steve Youngs | 5 | 0.09% | 1 | 0.68% |
Matt Schulte | 5 | 0.09% | 2 | 1.36% |
Deepak Saxena | 4 | 0.07% | 1 | 0.68% |
Jingoo Han | 4 | 0.07% | 1 | 0.68% |
Kyle McMartin | 4 | 0.07% | 1 | 0.68% |
Bryan Wu | 3 | 0.06% | 1 | 0.68% |
Daniel Drake | 3 | 0.06% | 1 | 0.68% |
Tejun Heo | 3 | 0.06% | 1 | 0.68% |
Rabin Vincent | 3 | 0.06% | 1 | 0.68% |
Jani Nikula | 2 | 0.04% | 1 | 0.68% |
Phillip Raffeck | 2 | 0.04% | 1 | 0.68% |
Peter Zijlstra | 2 | 0.04% | 1 | 0.68% |
Sergei Shtylyov | 2 | 0.04% | 1 | 0.68% |
Stephen Warren | 2 | 0.04% | 1 | 0.68% |
Adrian Bunk | 2 | 0.04% | 2 | 1.36% |
Shmulik Ladkani | 2 | 0.04% | 1 | 0.68% |
Pavel Machek | 1 | 0.02% | 1 | 0.68% |
Randy Dunlap | 1 | 0.02% | 1 | 0.68% |
Rusty Russell | 1 | 0.02% | 1 | 0.68% |
Alexander Sverdlin | 1 | 0.02% | 1 | 0.68% |
Andy Shevchenko | 1 | 0.02% | 1 | 0.68% |
Thomas Gleixner | 1 | 0.02% | 1 | 0.68% |
Total | 5398 | 100.00% | 147 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.