* [PATCH 06/10] 8250: add support for ASIX devices with a FIFO bug
From: Alan Cox @ 2012-07-12 12:00 UTC (permalink / raw)
To: greg, linux-serial
In-Reply-To: <20120712115643.1321.63498.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
Information and a different patch provided by <donald@asix.com.tw>. We do
it a little differently to keep the modularity and to avoid playing with
RLSI.
We add a new uart bug for the parity flaw and set it in the pci matches.
If parity check is enabled then we drop the FIFO trigger to 1 as per the
Asix reference code.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250/8250.c | 8 ++++++--
drivers/tty/serial/8250/8250.h | 1 +
drivers/tty/serial/8250/8250_pci.c | 24 +++++++++++++++++++++---
3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index ca42d16..44f52c6 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -2202,6 +2202,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned char cval, fcr = 0;
unsigned long flags;
unsigned int baud, quot;
+ int fifo_bug = 0;
switch (termios->c_cflag & CSIZE) {
case CS5:
@@ -2221,8 +2222,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
if (termios->c_cflag & CSTOPB)
cval |= UART_LCR_STOP;
- if (termios->c_cflag & PARENB)
+ if (termios->c_cflag & PARENB) {
cval |= UART_LCR_PARITY;
+ if (up->bugs & UART_BUG_PARITY)
+ fifo_bug = 1;
+ }
if (!(termios->c_cflag & PARODD))
cval |= UART_LCR_EPAR;
#ifdef CMSPAR
@@ -2246,7 +2250,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
fcr = uart_config[port->type].fcr;
- if (baud < 2400) {
+ if (baud < 2400 || fifo_bug) {
fcr &= ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
}
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index f9719d1..c335b2b 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -78,6 +78,7 @@ struct serial8250_config {
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
+#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
#define PROBE_RSA (1 << 0)
#define PROBE_ANY (~0)
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 2ef9a07..62e10fe 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1032,8 +1032,15 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)
return number_uarts;
}
-static int
-pci_default_setup(struct serial_private *priv,
+static int pci_asix_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_8250_port *port, int idx)
+{
+ port->bugs |= UART_BUG_PARITY;
+ return pci_default_setup(priv, board, port, idx);
+}
+
+static int pci_default_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
@@ -1187,6 +1194,7 @@ pci_xr17c154_setup(struct serial_private *priv,
#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
+#define PCI_VENDOR_ID_ASIX 0x9710
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -1726,7 +1734,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.setup = pci_omegapci_setup,
- },
+ },
+ /*
+ * ASIX devices with FIFO bug
+ */
+ {
+ .vendor = PCI_VENDOR_ID_ASIX,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_asix_setup,
+ },
/*
* Default "match everything" terminator entry
*/
^ permalink raw reply related
* [PATCH 05/10] 8250: propogate the bugs field
From: Alan Cox @ 2012-07-12 12:00 UTC (permalink / raw)
To: greg, linux-serial
In-Reply-To: <20120712115643.1321.63498.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
Now we are using the uart_8250_port this is trivial
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250/8250.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 2b24685..ca42d16 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -3155,6 +3155,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
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.private_data = up->port.private_data;
if (up->port.dev)
^ permalink raw reply related
* [PATCH 04/10] 8250: use the 8250 register interface not the legacy one
From: Alan Cox @ 2012-07-12 11:59 UTC (permalink / raw)
To: greg, linux-serial
In-Reply-To: <20120712115643.1321.63498.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
The old interface just copies bits over and calls the newer one.
In addition we can now pass more information.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/tty/serial/8250/8250.c | 71 +++++++++-----------------
drivers/tty/serial/8250/8250_acorn.c | 22 ++++----
drivers/tty/serial/8250/8250_dw.c | 38 +++++++-------
drivers/tty/serial/8250/8250_gsc.c | 26 +++++-----
drivers/tty/serial/8250/8250_hp300.c | 26 +++++-----
drivers/tty/serial/8250/8250_pci.c | 92 +++++++++++++++++-----------------
drivers/tty/serial/8250/8250_pnp.c | 28 +++++-----
drivers/tty/serial/8250/serial_cs.c | 30 ++++++-----
include/linux/serial_8250.h | 1
9 files changed, 155 insertions(+), 179 deletions(-)
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 8123f78..2b24685 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -2979,36 +2979,36 @@ void serial8250_resume_port(int line)
static int __devinit serial8250_probe(struct platform_device *dev)
{
struct plat_serial8250_port *p = dev->dev.platform_data;
- struct uart_port port;
+ struct uart_8250_port uart;
int ret, i, irqflag = 0;
- memset(&port, 0, sizeof(struct uart_port));
+ memset(&uart, 0, sizeof(uart));
if (share_irqs)
irqflag = IRQF_SHARED;
for (i = 0; p && p->flags != 0; p++, i++) {
- port.iobase = p->iobase;
- port.membase = p->membase;
- port.irq = p->irq;
- port.irqflags = p->irqflags;
- port.uartclk = p->uartclk;
- port.regshift = p->regshift;
- port.iotype = p->iotype;
- port.flags = p->flags;
- port.mapbase = p->mapbase;
- port.hub6 = p->hub6;
- port.private_data = p->private_data;
- port.type = p->type;
- port.serial_in = p->serial_in;
- port.serial_out = p->serial_out;
- port.handle_irq = p->handle_irq;
- port.handle_break = p->handle_break;
- port.set_termios = p->set_termios;
- port.pm = p->pm;
- port.dev = &dev->dev;
- port.irqflags |= irqflag;
- ret = serial8250_register_port(&port);
+ 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.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,
@@ -3081,7 +3081,7 @@ static struct platform_driver serial8250_isa_driver = {
static struct platform_device *serial8250_isa_devs;
/*
- * serial8250_register_port and serial8250_unregister_port allows for
+ * 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.
*/
@@ -3198,29 +3198,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
EXPORT_SYMBOL(serial8250_register_8250_port);
/**
- * serial8250_register_port - register a serial port
- * @port: 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_port(struct uart_port *port)
-{
- struct uart_8250_port up;
-
- memset(&up, 0, sizeof(up));
- memcpy(&up.port, port, sizeof(*port));
- return serial8250_register_8250_port(&up);
-}
-EXPORT_SYMBOL(serial8250_register_port);
-
-/**
* serial8250_unregister_port - remove a 16x50 serial port at runtime
* @line: serial line number
*
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c
index b0ce8c5..8574983 100644
--- a/drivers/tty/serial/8250/8250_acorn.c
+++ b/drivers/tty/serial/8250/8250_acorn.c
@@ -43,7 +43,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct serial_card_info *info;
struct serial_card_type *type = id->data;
- struct uart_port port;
+ struct uart_8250_port uart;
unsigned long bus_addr;
unsigned int i;
@@ -62,19 +62,19 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
ecard_set_drvdata(ec, info);
- memset(&port, 0, sizeof(struct uart_port));
- port.irq = ec->irq;
- port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
- port.uartclk = type->uartclk;
- port.iotype = UPIO_MEM;
- port.regshift = 2;
- port.dev = &ec->dev;
+ memset(&uart, 0, sizeof(struct uart_8250_port));
+ uart.port.irq = ec->irq;
+ uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+ uart.port.uartclk = type->uartclk;
+ uart.port.iotype = UPIO_MEM;
+ uart.port.regshift = 2;
+ uart.port.dev = &ec->dev;
for (i = 0; i < info->num_ports; i ++) {
- port.membase = info->vaddr + type->offset[i];
- port.mapbase = bus_addr + type->offset[i];
+ uart.port.membase = info->vaddr + type->offset[i];
+ uart.port.mapbase = bus_addr + type->offset[i];
- info->ports[i] = serial8250_register_port(&port);
+ info->ports[i] = serial8250_register_8250_port(&uart);
}
return 0;
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index f574eef..afb955f 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -89,7 +89,7 @@ static int dw8250_handle_irq(struct uart_port *p)
static int __devinit dw8250_probe(struct platform_device *pdev)
{
- struct uart_port port = {};
+ struct uart_8250_port uart = {};
struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct device_node *np = pdev->dev.of_node;
@@ -104,28 +104,28 @@ static int __devinit dw8250_probe(struct platform_device *pdev)
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- port.private_data = data;
-
- spin_lock_init(&port.lock);
- port.mapbase = regs->start;
- port.irq = irq->start;
- port.handle_irq = dw8250_handle_irq;
- port.type = PORT_8250;
- port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+ uart.port.private_data = data;
+
+ spin_lock_init(&uart.port.lock);
+ uart.port.mapbase = regs->start;
+ uart.port.irq = irq->start;
+ uart.port.handle_irq = dw8250_handle_irq;
+ uart.port.type = PORT_8250;
+ uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
UPF_FIXED_PORT | UPF_FIXED_TYPE;
- port.dev = &pdev->dev;
+ uart.port.dev = &pdev->dev;
- port.iotype = UPIO_MEM;
- port.serial_in = dw8250_serial_in;
- port.serial_out = dw8250_serial_out;
+ uart.port.iotype = UPIO_MEM;
+ uart.port.serial_in = dw8250_serial_in;
+ uart.port.serial_out = dw8250_serial_out;
if (!of_property_read_u32(np, "reg-io-width", &val)) {
switch (val) {
case 1:
break;
case 4:
- port.iotype = UPIO_MEM32;
- port.serial_in = dw8250_serial_in32;
- port.serial_out = dw8250_serial_out32;
+ uart.port.iotype = UPIO_MEM32;
+ uart.port.serial_in = dw8250_serial_in32;
+ uart.port.serial_out = dw8250_serial_out32;
break;
default:
dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n",
@@ -135,15 +135,15 @@ static int __devinit dw8250_probe(struct platform_device *pdev)
}
if (!of_property_read_u32(np, "reg-shift", &val))
- port.regshift = val;
+ uart.port.regshift = val;
if (of_property_read_u32(np, "clock-frequency", &val)) {
dev_err(&pdev->dev, "no clock-frequency property set\n");
return -EINVAL;
}
- port.uartclk = val;
+ uart.uart.port.uartclk = val;
- data->line = serial8250_register_port(&port);
+ data->line = serial8250_register_8250_port(&uart);
if (data->line < 0)
return data->line;
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c
index d8c0ffb..097dff9 100644
--- a/drivers/tty/serial/8250/8250_gsc.c
+++ b/drivers/tty/serial/8250/8250_gsc.c
@@ -26,7 +26,7 @@
static int __init serial_init_chip(struct parisc_device *dev)
{
- struct uart_port port;
+ struct uart_8250_port uart;
unsigned long address;
int err;
@@ -48,21 +48,21 @@ static int __init serial_init_chip(struct parisc_device *dev)
if (dev->id.sversion != 0x8d)
address += 0x800;
- memset(&port, 0, sizeof(port));
- port.iotype = UPIO_MEM;
+ memset(&uart, 0, sizeof(uart));
+ uart.port.iotype = UPIO_MEM;
/* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */
- port.uartclk = 7272727;
- port.mapbase = address;
- port.membase = ioremap_nocache(address, 16);
- port.irq = dev->irq;
- port.flags = UPF_BOOT_AUTOCONF;
- port.dev = &dev->dev;
-
- err = serial8250_register_port(&port);
+ uart.port.uartclk = 7272727;
+ uart.port.mapbase = address;
+ uart.port.membase = ioremap_nocache(address, 16);
+ uart.port.irq = dev->irq;
+ uart.port.flags = UPF_BOOT_AUTOCONF;
+ uart.port.dev = &dev->dev;
+
+ err = serial8250_register_8250_port(&uart);
if (err < 0) {
printk(KERN_WARNING
- "serial8250_register_port returned error %d\n", err);
- iounmap(port.membase);
+ "serial8250_register_8250_port returned error %d\n", err);
+ iounmap(uart.port.membase);
return err;
}
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c
index c13438c..8f1dd2c 100644
--- a/drivers/tty/serial/8250/8250_hp300.c
+++ b/drivers/tty/serial/8250/8250_hp300.c
@@ -171,7 +171,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d,
return 0;
}
#endif
- memset(&port, 0, sizeof(struct uart_port));
+ memset(&uart, 0, sizeof(uart));
/* Memory mapped I/O */
port.iotype = UPIO_MEM;
@@ -182,7 +182,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d,
port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
port.regshift = 1;
port.dev = &d->dev;
- line = serial8250_register_port(&port);
+ line = serial8250_register_8250_port(&uart);
if (line < 0) {
printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
@@ -210,7 +210,7 @@ static int __init hp300_8250_init(void)
#ifdef CONFIG_HPAPCI
int line;
unsigned long base;
- struct uart_port uport;
+ struct uart_8250_port uart;
struct hp300_port *port;
int i;
#endif
@@ -248,26 +248,26 @@ static int __init hp300_8250_init(void)
if (!port)
return -ENOMEM;
- memset(&uport, 0, sizeof(struct uart_port));
+ memset(&uart, 0, sizeof(uart));
base = (FRODO_BASE + FRODO_APCI_OFFSET(i));
/* Memory mapped I/O */
- uport.iotype = UPIO_MEM;
- uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
+ uart.port.iotype = UPIO_MEM;
+ uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
| UPF_BOOT_AUTOCONF;
/* XXX - no interrupt support yet */
- uport.irq = 0;
- uport.uartclk = HPAPCI_BAUD_BASE * 16;
- uport.mapbase = base;
- uport.membase = (char *)(base + DIO_VIRADDRBASE);
- uport.regshift = 2;
+ uart.port.irq = 0;
+ uart.port.uartclk = HPAPCI_BAUD_BASE * 16;
+ uart.port.mapbase = base;
+ uart.port.membase = (char *)(base + DIO_VIRADDRBASE);
+ uart.port.regshift = 2;
- line = serial8250_register_port(&uport);
+ line = serial8250_register_8250_port(&uart);
if (line < 0) {
printk(KERN_NOTICE "8250_hp300: register_serial() APCI"
- " %d irq %d failed\n", i, uport.irq);
+ " %d irq %d failed\n", i, uart.port.irq);
kfree(port);
continue;
}
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 66e5909..2ef9a07 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -44,7 +44,7 @@ struct pci_serial_quirk {
int (*init)(struct pci_dev *dev);
int (*setup)(struct serial_private *,
const struct pciserial_board *,
- struct uart_port *, int);
+ struct uart_8250_port *, int);
void (*exit)(struct pci_dev *dev);
};
@@ -59,7 +59,7 @@ struct serial_private {
};
static int pci_default_setup(struct serial_private*,
- const struct pciserial_board*, struct uart_port*, int);
+ const struct pciserial_board*, struct uart_8250_port *, int);
static void moan_device(const char *str, struct pci_dev *dev)
{
@@ -74,7 +74,7 @@ static void moan_device(const char *str, struct pci_dev *dev)
}
static int
-setup_port(struct serial_private *priv, struct uart_port *port,
+setup_port(struct serial_private *priv, struct uart_8250_port *port,
int bar, int offset, int regshift)
{
struct pci_dev *dev = priv->dev;
@@ -93,17 +93,17 @@ setup_port(struct serial_private *priv, struct uart_port *port,
if (!priv->remapped_bar[bar])
return -ENOMEM;
- port->iotype = UPIO_MEM;
- port->iobase = 0;
- port->mapbase = base + offset;
- port->membase = priv->remapped_bar[bar] + offset;
- port->regshift = regshift;
+ port->port.iotype = UPIO_MEM;
+ port->port.iobase = 0;
+ port->port.mapbase = base + offset;
+ port->port.membase = priv->remapped_bar[bar] + offset;
+ port->port.regshift = regshift;
} else {
- port->iotype = UPIO_PORT;
- port->iobase = base + offset;
- port->mapbase = 0;
- port->membase = NULL;
- port->regshift = 0;
+ port->port.iotype = UPIO_PORT;
+ port->port.iobase = base + offset;
+ port->port.mapbase = 0;
+ port->port.membase = NULL;
+ port->port.regshift = 0;
}
return 0;
}
@@ -113,7 +113,7 @@ setup_port(struct serial_private *priv, struct uart_port *port,
*/
static int addidata_apci7800_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar = 0, offset = board->first_offset;
bar = FL_GET_BASE(board->flags);
@@ -140,7 +140,7 @@ static int addidata_apci7800_setup(struct serial_private *priv,
*/
static int
afavlab_setup(struct serial_private *priv, const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar, offset = board->first_offset;
@@ -195,7 +195,7 @@ static int pci_hp_diva_init(struct pci_dev *dev)
static int
pci_hp_diva_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int offset = board->first_offset;
unsigned int bar = FL_GET_BASE(board->flags);
@@ -370,7 +370,7 @@ static void __devexit pci_ni8430_exit(struct pci_dev *dev)
/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
static int
sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar, offset = board->first_offset;
@@ -525,7 +525,7 @@ static int pci_siig_init(struct pci_dev *dev)
static int pci_siig_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0;
@@ -619,7 +619,7 @@ static int pci_timedia_init(struct pci_dev *dev)
static int
pci_timedia_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar = 0, offset = board->first_offset;
@@ -653,7 +653,7 @@ pci_timedia_setup(struct serial_private *priv,
static int
titan_400l_800l_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar, offset = board->first_offset;
@@ -754,7 +754,7 @@ static int pci_ni8430_init(struct pci_dev *dev)
static int
pci_ni8430_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
void __iomem *p;
unsigned long base, len;
@@ -781,7 +781,7 @@ pci_ni8430_setup(struct serial_private *priv,
static int pci_netmos_9900_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar;
@@ -1035,7 +1035,7 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)
static int
pci_default_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
unsigned int bar, offset = board->first_offset, maxnr;
@@ -1057,15 +1057,15 @@ pci_default_setup(struct serial_private *priv,
static int
ce4100_serial_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
int ret;
ret = setup_port(priv, port, 0, 0, board->reg_shift);
- port->iotype = UPIO_MEM32;
- port->type = PORT_XSCALE;
- port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
- port->regshift = 2;
+ port->port.iotype = UPIO_MEM32;
+ port->port.type = PORT_XSCALE;
+ port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+ port->port.regshift = 2;
return ret;
}
@@ -1073,16 +1073,16 @@ ce4100_serial_setup(struct serial_private *priv,
static int
pci_omegapci_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
return setup_port(priv, port, 2, idx * 8, 0);
}
static int skip_tx_en_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
- port->flags |= UPF_NO_TXEN_TEST;
+ port->port.flags |= UPF_NO_TXEN_TEST;
printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
"[%04x:%04x] subsystem [%04x:%04x]\n",
priv->dev->vendor,
@@ -1131,11 +1131,11 @@ static unsigned int kt_serial_in(struct uart_port *p, int offset)
static int kt_serial_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
- port->flags |= UPF_BUG_THRE;
- port->serial_in = kt_serial_in;
- port->handle_break = kt_handle_break;
+ port->port.flags |= UPF_BUG_THRE;
+ port->port.serial_in = kt_serial_in;
+ port->port.handle_break = kt_handle_break;
return skip_tx_en_setup(priv, board, port, idx);
}
@@ -1151,9 +1151,9 @@ static int pci_eg20t_init(struct pci_dev *dev)
static int
pci_xr17c154_setup(struct serial_private *priv,
const struct pciserial_board *board,
- struct uart_port *port, int idx)
+ struct uart_8250_port *port, int idx)
{
- port->flags |= UPF_EXAR_EFR;
+ port->port.flags |= UPF_EXAR_EFR;
return pci_default_setup(priv, board, port, idx);
}
@@ -2720,7 +2720,7 @@ serial_pci_matches(const struct pciserial_board *board,
struct serial_private *
pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
{
- struct uart_port serial_port;
+ struct uart_8250_port uart;
struct serial_private *priv;
struct pci_serial_quirk *quirk;
int rc, nr_ports, i;
@@ -2760,22 +2760,22 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
priv->dev = dev;
priv->quirk = quirk;
- memset(&serial_port, 0, sizeof(struct uart_port));
- serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
- serial_port.uartclk = board->base_baud * 16;
- serial_port.irq = get_pci_irq(dev, board);
- serial_port.dev = &dev->dev;
+ memset(&uart, 0, sizeof(uart));
+ uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+ uart.port.uartclk = board->base_baud * 16;
+ uart.port.irq = get_pci_irq(dev, board);
+ uart.port.dev = &dev->dev;
for (i = 0; i < nr_ports; i++) {
- if (quirk->setup(priv, board, &serial_port, i))
+ if (quirk->setup(priv, board, &uart, i))
break;
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
- serial_port.iobase, serial_port.irq, serial_port.iotype);
+ uart.port.iobase, uart.port.irq, uart.port.iotype);
#endif
- priv->line[i] = serial8250_register_port(&serial_port);
+ priv->line[i] = serial8250_register_8250_port(&uart);
if (priv->line[i] < 0) {
printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
break;
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c
index a2f2365..fde5aa6 100644
--- a/drivers/tty/serial/8250/8250_pnp.c
+++ b/drivers/tty/serial/8250/8250_pnp.c
@@ -424,7 +424,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
static int __devinit
serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
- struct uart_port port;
+ struct uart_8250_port uart;
int ret, line, flags = dev_id->driver_data;
if (flags & UNKNOWN_DEV) {
@@ -433,32 +433,32 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
return ret;
}
- memset(&port, 0, sizeof(struct uart_port));
+ memset(&uart, 0, sizeof(uart));
if (pnp_irq_valid(dev, 0))
- port.irq = pnp_irq(dev, 0);
+ uart.port.irq = pnp_irq(dev, 0);
if (pnp_port_valid(dev, 0)) {
- port.iobase = pnp_port_start(dev, 0);
- port.iotype = UPIO_PORT;
+ uart.port.iobase = pnp_port_start(dev, 0);
+ uart.port.iotype = UPIO_PORT;
} else if (pnp_mem_valid(dev, 0)) {
- port.mapbase = pnp_mem_start(dev, 0);
- port.iotype = UPIO_MEM;
- port.flags = UPF_IOREMAP;
+ uart.port.mapbase = pnp_mem_start(dev, 0);
+ uart.port.iotype = UPIO_MEM;
+ uart.port.flags = UPF_IOREMAP;
} else
return -ENODEV;
#ifdef SERIAL_DEBUG_PNP
printk(KERN_DEBUG
"Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
- port.iobase, port.mapbase, port.irq, port.iotype);
+ uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype);
#endif
- port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+ uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
- port.flags |= UPF_SHARE_IRQ;
- port.uartclk = 1843200;
- port.dev = &dev->dev;
+ uart.port.flags |= UPF_SHARE_IRQ;
+ uart.port.uartclk = 1843200;
+ uart.port.dev = &dev->dev;
- line = serial8250_register_port(&port);
+ line = serial8250_register_8250_port(&uart);
if (line < 0)
return -ENODEV;
diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c
index 29b695d..b7d48b3 100644
--- a/drivers/tty/serial/8250/serial_cs.c
+++ b/drivers/tty/serial/8250/serial_cs.c
@@ -73,7 +73,7 @@ struct serial_quirk {
unsigned int prodid;
int multi; /* 1 = multifunction, > 1 = # ports */
void (*config)(struct pcmcia_device *);
- void (*setup)(struct pcmcia_device *, struct uart_port *);
+ void (*setup)(struct pcmcia_device *, struct uart_8250_port *);
void (*wakeup)(struct pcmcia_device *);
int (*post)(struct pcmcia_device *);
};
@@ -105,9 +105,9 @@ struct serial_cfg_mem {
* Elan VPU16551 UART with 14.7456MHz oscillator
* manfid 0x015D, 0x4C45
*/
-static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_8250_port *uart)
{
- port->uartclk = 14745600;
+ uart->port.uartclk = 14745600;
}
static int quirk_post_ibm(struct pcmcia_device *link)
@@ -343,25 +343,25 @@ static void serial_detach(struct pcmcia_device *link)
static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
unsigned int iobase, int irq)
{
- struct uart_port port;
+ struct uart_8250_port uart;
int line;
- memset(&port, 0, sizeof (struct uart_port));
- port.iobase = iobase;
- port.irq = irq;
- port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
- port.uartclk = 1843200;
- port.dev = &handle->dev;
+ memset(&uart, 0, sizeof(uart));
+ uart.port.iobase = iobase;
+ uart.port.irq = irq;
+ uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+ uart.port.uartclk = 1843200;
+ uart.port.dev = &handle->dev;
if (buggy_uart)
- port.flags |= UPF_BUGGY_UART;
+ uart.port.flags |= UPF_BUGGY_UART;
if (info->quirk && info->quirk->setup)
- info->quirk->setup(handle, &port);
+ info->quirk->setup(handle, &uart);
- line = serial8250_register_port(&port);
+ line = serial8250_register_8250_port(&uart);
if (line < 0) {
- printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
- "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
+ pr_err("serial_cs: serial8250_register_8250_port() at 0x%04lx, irq %d failed\n",
+ (unsigned long)iobase, irq);
return -EINVAL;
}
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index a416e92..f41dcc9 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -69,7 +69,6 @@ struct uart_port;
struct uart_8250_port;
int serial8250_register_8250_port(struct uart_8250_port *);
-int serial8250_register_port(struct uart_port *);
void serial8250_unregister_port(int line);
void serial8250_suspend_port(int line);
void serial8250_resume_port(int line);
^ permalink raw reply related
* [PATCH 03/10] usb, kobil: Sort out some bogus tty handling
From: Alan Cox @ 2012-07-12 11:59 UTC (permalink / raw)
To: greg, linux-serial
In-Reply-To: <20120712115643.1321.63498.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
Stuff noticed while doing the termios conversion.
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/usb/serial/kobil_sct.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index fafeabb..0852472 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -192,8 +192,8 @@ static void kobil_init_termios(struct tty_struct *tty)
{
/* Default to echo off and other sane device settings */
tty->termios->c_lflag = 0;
- tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
- tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+ tty->termios->c_iflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
+ tty->termios->c_iflag |= IGNBRK | IGNPAR | IXOFF;
/* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
tty->termios->c_oflag &= ~ONLCR;
}
@@ -588,7 +588,7 @@ static void kobil_set_termios(struct tty_struct *tty,
if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
/* This device doesn't support ioctl calls */
- *tty->termios = *old;
+ tty_termios_copy_hw(tty->termios, old_termios);
return;
}
^ permalink raw reply related
* [PATCH 02/10] usb: fix sillies in the metro USB driver
From: Alan Cox @ 2012-07-12 11:59 UTC (permalink / raw)
To: greg, linux-serial
In-Reply-To: <20120712115643.1321.63498.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
Bits noticed doing the termios conversion
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/usb/serial/metro-usb.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index d47eb06..7ae9af6 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -130,20 +130,14 @@ static void metrousb_read_int_callback(struct urb *urb)
/* Set the data read from the usb port into the serial port buffer. */
tty = tty_port_tty_get(&port->port);
- if (!tty) {
- dev_err(&port->dev, "%s - bad tty pointer - exiting\n",
- __func__);
- return;
- }
-
if (tty && urb->actual_length) {
/* Loop through the data copying each byte to the tty layer. */
tty_insert_flip_string(tty, data, urb->actual_length);
/* Force the data to the tty layer. */
tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
}
- tty_kref_put(tty);
/* Set any port variables. */
spin_lock_irqsave(&metro_priv->lock, flags);
^ permalink raw reply related
* [PATCH 01/10] f81232: correct stubbed termios handler
From: Alan Cox @ 2012-07-12 11:58 UTC (permalink / raw)
To: greg, linux-serial
In-Reply-To: <20120712115643.1321.63498.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
---
drivers/usb/serial/f81232.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
index 499b15f..acd3267 100644
--- a/drivers/usb/serial/f81232.c
+++ b/drivers/usb/serial/f81232.c
@@ -177,6 +177,7 @@ static void f81232_set_termios(struct tty_struct *tty,
return;
/* Do the real work here... */
+ tty_termios_copy_hw(&tty->termios, old_termios);
}
static int f81232_tiocmget(struct tty_struct *tty)
^ permalink raw reply related
* [PATCH 00/10] Resend: tty updates
From: Alan Cox @ 2012-07-12 11:58 UTC (permalink / raw)
To: greg, linux-serial
TTY cleanups and pre-requisites for the lock handling change.
Resending as it seems these got lost given the stuff before and after
them is already applied (including stuff in -next that depends on these).
Rebased versus the current tree and to resolve tty_port change conflicts.
---
Alan Cox (10):
tty: Move the handling of the tty release logic
vt: fix the keyboard/led locking
tty: tidy up the RESET_TERMIOS case
tty: move the termios object into the tty
8250: add support for ASIX devices with a FIFO bug
8250: propogate the bugs field
8250: use the 8250 register interface not the legacy one
usb, kobil: Sort out some bogus tty handling
usb: fix sillies in the metro USB driver
f81232: correct stubbed termios handler
arch/ia64/hp/sim/simserial.c | 2 -
drivers/bluetooth/hci_ath.c | 2 -
drivers/mmc/card/sdio_uart.c | 20 +++--
drivers/net/irda/irtty-sir.c | 10 +--
drivers/net/usb/hso.c | 12 +--
drivers/tty/amiserial.c | 20 +++--
drivers/tty/cyclades.c | 19 ++---
drivers/tty/hvc/hvsi_lib.c | 2 -
drivers/tty/isicom.c | 8 +-
drivers/tty/moxa.c | 10 +--
drivers/tty/mxser.c | 20 +++--
drivers/tty/n_gsm.c | 8 +-
drivers/tty/n_tty.c | 2 -
drivers/tty/pty.c | 35 ++-------
drivers/tty/rocket.c | 18 ++---
drivers/tty/serial/8250/8250.c | 80 ++++++++-------------
drivers/tty/serial/8250/8250.h | 1
drivers/tty/serial/8250/8250_acorn.c | 22 +++---
drivers/tty/serial/8250/8250_dw.c | 38 +++++-----
drivers/tty/serial/8250/8250_gsc.c | 26 +++----
drivers/tty/serial/8250/8250_hp300.c | 26 +++----
drivers/tty/serial/8250/8250_pci.c | 116 ++++++++++++++++++-------------
drivers/tty/serial/8250/8250_pnp.c | 28 ++++---
drivers/tty/serial/8250/serial_cs.c | 30 ++++----
drivers/tty/serial/bfin_uart.c | 2 -
drivers/tty/serial/crisv10.c | 26 +++----
drivers/tty/serial/ioc4_serial.c | 2 -
drivers/tty/serial/jsm/jsm_tty.c | 8 +-
drivers/tty/serial/samsung.c | 2 -
drivers/tty/serial/serial_core.c | 28 ++++---
drivers/tty/synclink.c | 36 +++++-----
drivers/tty/synclink_gt.c | 24 +++---
drivers/tty/synclinkmp.c | 24 +++---
drivers/tty/tty_io.c | 77 ++++++++------------
drivers/tty/tty_ioctl.c | 124 +++++++++++++++++----------------
drivers/tty/tty_ldisc.c | 10 +--
drivers/tty/tty_port.c | 6 +-
drivers/tty/vt/keyboard.c | 41 ++++++-----
drivers/tty/vt/vt.c | 5 +
drivers/usb/class/cdc-acm.c | 2 -
drivers/usb/serial/ark3116.c | 4 +
drivers/usb/serial/belkin_sa.c | 2 -
drivers/usb/serial/cp210x.c | 8 +-
drivers/usb/serial/cypress_m8.c | 40 +++++------
drivers/usb/serial/digi_acceleport.c | 14 ++--
drivers/usb/serial/empeg.c | 2 -
drivers/usb/serial/f81232.c | 3 +
drivers/usb/serial/ftdi_sio.c | 2 -
drivers/usb/serial/io_edgeport.c | 12 ++-
drivers/usb/serial/io_ti.c | 12 ++-
drivers/usb/serial/ir-usb.c | 2 -
drivers/usb/serial/iuu_phoenix.c | 28 ++++---
drivers/usb/serial/keyspan.c | 6 +-
drivers/usb/serial/keyspan_pda.c | 4 +
drivers/usb/serial/kl5kusb105.c | 18 ++---
drivers/usb/serial/kobil_sct.c | 14 ++--
drivers/usb/serial/mct_u232.c | 4 +
drivers/usb/serial/metro-usb.c | 8 --
drivers/usb/serial/mos7720.c | 14 ++--
drivers/usb/serial/mos7840.c | 12 ++-
drivers/usb/serial/oti6858.c | 10 +--
drivers/usb/serial/pl2303.c | 6 +-
drivers/usb/serial/quatech2.c | 4 +
drivers/usb/serial/sierra.c | 2 -
drivers/usb/serial/spcp8x5.c | 12 ++-
drivers/usb/serial/ssu100.c | 4 +
drivers/usb/serial/ti_usb_3410_5052.c | 10 +--
drivers/usb/serial/usb-serial.c | 5 +
drivers/usb/serial/usb_wwan.c | 2 -
drivers/usb/serial/whiteheat.c | 2 -
include/linux/kbd_kern.h | 1
include/linux/serial_8250.h | 1
include/linux/tty.h | 47 ++++++-------
include/linux/tty_driver.h | 11 +--
net/bluetooth/rfcomm/tty.c | 2 -
net/irda/ircomm/ircomm_tty.c | 12 ++-
net/irda/ircomm/ircomm_tty_ioctl.c | 10 +--
77 files changed, 637 insertions(+), 685 deletions(-)
--
^ permalink raw reply
* Re: [PATCH] 8250: Add new UART type SC16C550
From: Alan Cox @ 2012-07-12 8:59 UTC (permalink / raw)
To: Raphael Assenat; +Cc: linux-serial
In-Reply-To: <20120711195453.GC4260@8d.com>
On Wed, 11 Jul 2012 15:54:53 -0400
Raphael Assenat <raph@8d.com> wrote:
> The NXP SC16C550 has a 16 Byte FIFO and support Automatic Flow Control,
> enabled by setting bit 5 of MCR (a.k.a. AFE).
>
> This patch adds a new 8250 port type (PORT_SC16C550) to support
> this chip correcly. Should also work for TI TL16550C/D.
>
> Tested on a custom OMAP board with an SC16C554 (quad uart) attached
> to the GPMC. We experienced receive overruns when not using AFE.
>
> Signed-off-by: Raphael Assenat <raph@8d.com>
Looks fine and ready to go in as and when patches for the mainline kernel
that actually use it go in (ie submit it with the board support once you
get that far)
Alan
^ permalink raw reply
* [PATCH] 8250: Add new UART type SC16C550
From: Raphael Assenat @ 2012-07-11 19:54 UTC (permalink / raw)
To: linux-serial
The NXP SC16C550 has a 16 Byte FIFO and support Automatic Flow Control,
enabled by setting bit 5 of MCR (a.k.a. AFE).
This patch adds a new 8250 port type (PORT_SC16C550) to support
this chip correcly. Should also work for TI TL16550C/D.
Tested on a custom OMAP board with an SC16C554 (quad uart) attached
to the GPMC. We experienced receive overruns when not using AFE.
Signed-off-by: Raphael Assenat <raph@8d.com>
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 6e1958a..ffea4f3 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -282,6 +282,13 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
},
+ [PORT_SC16C550] = {
+ .name = "SC16C550",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
};
/* Uart divisor latch read */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 65db992..e472af3 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -47,7 +47,8 @@
#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */
#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
#define PORT_XR17D15X 21 /* Exar XR17D15x UART */
-#define PORT_MAX_8250 21 /* max port ID */
+#define PORT_SC16C550 22 /* NXP SC16C550 and equivalents */
+#define PORT_MAX_8250 22 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
^ permalink raw reply related
* The Items are needed urgently and also in large quantity
From: Kapil Bhardwaj @ 2012-07-11 3:02 UTC (permalink / raw)
To: linux-serial
Compliments of the day,
My company is interested in a different but a similar design of your product. please confirm to us if your company can make provision for the exact product as shown on the Chinese trading firm page below. You can view the sample pictures by loggin in to the link below with your correct business email to view pictures. Please note that this items are needed urgently and also in large quantity.
http://www.elcivismo.com.ar/img/viewtradeorder.htm
Pls send us quote after preview immediately.
Thanks & Regards,
Kapil Bhardwaj
(MANAGING PARTENER)
M/S Shree Ganesh Tradings
69-A, Vijay Block
Laxmi Nagar
Delhi-110092
Tel.: 0091 11 47603504
Fax.: 0091 11 47603501
^ permalink raw reply
* [PATCH RFC] Remove minimum FIFO size check for enabling AFE
From: Raphael Assenat @ 2012-07-11 20:02 UTC (permalink / raw)
To: linux-serial
When CRTSCTS is requested and the hardware supports AFE, I don't
understand why having a FIFO of less than 32 bytes is a reason not
to enable it.
The logic currently in place prevents AFE from being enabled when
we use a SC16C550 UART due to its 16 byte FIFO.
The original comment is not wrong. Indeed, if the remote uart is not
using automatic flow control, it will probably send extra bytes
even after RTS is deasserted.
But requiring a local UART FIFO of at least 32 bytes does not make
sense to me because:
1) If AFE is not enabled (due to a small FIFO of 16 bytes, as in my case),
what mechanism will save us from receive overrun? None, and we loose data
if the UART FIFO fills up.
2) If AFE is enabled AND the remote latency is such that it stops
sending data only after several bytes, filling the FIFO, we still loose
data. But at least we /tried/ to stop the remote UART. By doing so,
if the remote UART had been using auto flow control (or would have reacted
fast enough anyway), then the flow would have been properly interrupted and
no data would have been lost. Isn't this better?
3) In the worst case of remote software latency, we can imagine the remote
UART emptying its whole FIFO before stopping. If this FIFO is 64 bytes,
the 32 bytes minimum wouldn't be enough anyway. The real problem here
would be the remote device which really should honor flow control signals
with a more acceptable latency.
Given all the above, I would suggest simply removing the FIFO size check
with the following patch. I don't think anything should break because of
this, but as I could not find when this fifo size check was added, I could
not read about the reasons why it is there...
If this patch is not acceptable, alternatives that would still solve my
problem include reducing the minimum FIFO size to 16 or adding a check
for this specific UART at the same place.
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index ffea4f3..e09b393 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -2252,14 +2252,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
}
/*
- * MCR-based auto flow control. When AFE is enabled, RTS will be
- * deasserted when the receive FIFO contains more characters than
- * the trigger, or the MCR RTS bit is cleared. In the case where
- * the remote UART is not using CTS auto flow control, we must
- * have sufficient FIFO entries for the latency of the remote
- * UART to respond. IOW, at least 32 bytes of FIFO.
+ * MCR-based auto flow control.
*/
- if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) {
+ if (up->capabilities & UART_CAP_AFE) {
up->mcr &= ~UART_MCR_AFE;
if (termios->c_cflag & CRTSCTS)
up->mcr |= UART_MCR_AFE;
^ permalink raw reply related
* [PATCH RFC] tty: serial: OMAP: Pass the uart device instead of NULL
From: Shubhrajyoti D @ 2012-07-11 12:27 UTC (permalink / raw)
To: linux-serial; +Cc: linux-arm-kernel, Shubhrajyoti D
Currently the dma_alloc passes NULL instead of the uart device.
Fix the same by passing the device parameter.
Also fixes the below warn.
[ 8613.094604] omap_uart omap_uart.0: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x0000]
[ 8613.109374] Modules linked in:
[ 8613.112640] [<c001b79c>] (unwind_backtrace+0x0/0xf0) from [<c0040934>] (warn_slowpath_common+0x4c/0x64)
[ 8613.122497] [<c0040934>] (warn_slowpath_common+0x4c/0x64) from [<c00409e0>] (warn_slowpath_fmt+0x30/0x40)
[ 8613.132537] [<c00409e0>] (warn_slowpath_fmt+0x30/0x40) from [<c0281230>] (check_unmap+0x6c8/0x7a8)
[ 8613.141937] [<c0281230>] (check_unmap+0x6c8/0x7a8) from [<c0281368>] (debug_dma_free_coherent+0x58/0x64)
[ 8613.151916] [<c0281368>] (debug_dma_free_coherent+0x58/0x64) from [<c02cafb8>] (serial_omap_shutdown+0x1d0/0x28c)
[ 8613.162689] [<c02cafb8>] (serial_omap_shutdown+0x1d0/0x28c) from [<c02c314c>] (uart_suspend_port+0x294/0x2bc)
[ 8613.173095] [<c02c314c>] (uart_suspend_port+0x294/0x2bc) from [<c02c7fec>] (serial_omap_suspend+0x1c/0x30)
[ 8613.183227] [<c02c7fec>] (serial_omap_suspend+0x1c/0x30) from [<c02d391c>] (platform_pm_suspend+0x2c/0x5c)
[ 8613.193389] [<c02d391c>] (platform_pm_suspend+0x2c/0x5c) from [<c02d7744>] (dpm_run_callback.clone.7+0x30/0xb0)
[ 8613.203979] [<c02d7744>] (dpm_run_callback.clone.7+0x30/0xb0) from [<c02d8238>] (__device_suspend+0x124/0x260)
[ 8613.214477] [<c02d8238>] (__device_suspend+0x124/0x260) from [<c02d8c0c>] (dpm_suspend+0x5c/0x218)
[ 8613.223907] [<c02d8c0c>] (dpm_suspend+0x5c/0x218) from [<c0080638>] (suspend_devices_and_enter+0x78/0x2d0)
[ 8613.234039] [<c0080638>] (suspend_devices_and_enter+0x78/0x2d0) from [<c0080a1c>] (pm_suspend+0x18c/0x208)
[ 8613.244171] [<c0080a1c>] (pm_suspend+0x18c/0x208) from [<c007fcc0>] (state_store+0x120/0x134)
[ 8613.253143] [<c007fcc0>] (state_store+0x120/0x134) from [<c0263ecc>] (kobj_attr_store+0x14/0x20)
[ 8613.262359] [<c0263ecc>] (kobj_attr_store+0x14/0x20) from [<c016a77c>] (sysfs_write_file+0x100/0x184)
[ 8613.272064] [<c016a77c>] (sysfs_write_file+0x100/0x184) from [<c0109b84>] (vfs_write+0xb4/0x148)
[ 8613.281280] [<c0109b84>] (vfs_write+0xb4/0x148) from [<c0109e0c>] (sys_write+0x40/0x70)
[ 8613.289703] [<c0109e0c>] (sys_write+0x40/0x70) from [<c0013ee0>] (ret_fast_syscall+0x0/0x3c)
[ 8613.298553] ---[ end trace e9beb8b35111c507 ]---
While at it also set the coherent mask.
Otherwise we get warnings like.
omap_uart omap_uart.0: coherent DMA mask is unset
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
Boot tested on omap4
drivers/tty/serial/omap-serial.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index d3cda0c..df1ab2f 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -574,18 +574,20 @@ static int serial_omap_startup(struct uart_port *port)
up->msr_saved_flags = 0;
if (up->use_dma) {
+ dma_set_coherent_mask(up->port.dev, DMA_BIT_MASK(32));
free_page((unsigned long)up->port.state->xmit.buf);
- up->port.state->xmit.buf = dma_alloc_coherent(NULL,
+ up->port.state->xmit.buf = dma_alloc_coherent(up->port.dev,
UART_XMIT_SIZE,
(dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys),
- 0);
+ GFP_KERNEL);
init_timer(&(up->uart_dma.rx_timer));
up->uart_dma.rx_timer.function = serial_omap_rxdma_poll;
up->uart_dma.rx_timer.data = up->port.line;
/* Currently the buffer size is 4KB. Can increase it */
- up->uart_dma.rx_buf = dma_alloc_coherent(NULL,
+ up->uart_dma.rx_buf = dma_alloc_coherent(up->port.dev,
up->uart_dma.rx_buf_size,
- (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0);
+ (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys),
+ GFP_KERNEL);
}
/*
* Finally, enable interrupts. Note: Modem status interrupts
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH v2 11/11] MAINTAINERS: add fblog entry
From: David Herrmann @ 2012-07-09 18:38 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <CAMuHMdX_aC1hzKf1eRqoSsQ4oALBev8p77v7++aoB2KrkOUaEw@mail.gmail.com>
Hi Geert
On Mon, Jul 9, 2012 at 9:33 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Sun, Jul 8, 2012 at 11:56 PM, David Herrmann
> <dh.herrmann@googlemail.com> wrote:
>> Add myself as maintainer for the fblog driver to the MAINTAINERS file.
>>
>> Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
>> ---
>> MAINTAINERS | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index ae8fe46..249b02a 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2854,6 +2854,12 @@ F: drivers/video/
>> F: include/video/
>> F: include/linux/fb.h
>>
>> +FRAMEBUFFER LOG DRIVER
>> +M: David Herrmann <dh.herrmann@googlemail.com>
>> +L: linux-serial@vger.kernel.org
>
> Why linux-serial, and not linux-fbdev?
I thought fbcon was maintained on linux-serial as it is very related
to the vt/tty layer. If linux-fbdev is the better place, I can move
this. I CC'ed both lists, anyway.
I have actually no idea where it fits in best.
Thanks
David
^ permalink raw reply
* Re: [PATCH v2 09/11] fblog: register console driver
From: David Herrmann @ 2012-07-09 18:25 UTC (permalink / raw)
To: Joe Perches
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <1341785361.13174.25.camel@joe2Laptop>
Hi Joe
On Mon, Jul 9, 2012 at 12:09 AM, Joe Perches <joe@perches.com> wrote:
> On Sun, 2012-07-08 at 23:56 +0200, David Herrmann wrote:
>> We want to print the kernel log to all FBs so we need a console driver.
>> This registers the driver on startup and writes all messages to all
>> registered fblog instances.
>
> Hi David. Trivia only:
>
>> diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
> []
>> @@ -47,6 +71,107 @@ static struct fblog_fb *fblog_fbs[FB_MAX];
>> static bool active = 1;
>>
>> #define to_fblog_dev(_d) container_of(_d, struct fblog_fb, dev)
>> +#define FBLOG_STR(x) x, sizeof(x) - 1
>
> That's a rather ugly macro.
But handy ;) I've removed it and replaced the call below with a local
variable which works fine too and seems to be even shorter than with
this macro.
>> +static void fblog_buf_resize(struct fblog_buf *buf, size_t width,
>> + size_t height)
>> +{
>> + u16 **lines = NULL;
>> + size_t i, j, minw, minh;
>> +
>> + if (buf->height == height && buf->width == width)
>> + return;
>> +
>> + if (width && height) {
>> + lines = kzalloc(height * sizeof(char*), GFP_KERNEL);
>
> sizeof(char *) is a bit more kernel style like.
Thanks, both fixed.
David
^ permalink raw reply
* Re: [PATCH v2 05/11] fblog: register one fblog object per framebuffer
From: David Herrmann @ 2012-07-09 17:55 UTC (permalink / raw)
To: Joe Perches
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <1341785628.13174.28.camel@joe2Laptop>
Hi Joe
On Mon, Jul 9, 2012 at 12:13 AM, Joe Perches <joe@perches.com> wrote:
> On Sun, 2012-07-08 at 23:56 +0200, David Herrmann wrote:
>>
>
> Hi David. Trivial comments only:
>
>> diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
> []
>> @@ -23,15 +23,204 @@
>> * all fblog instances before running other graphics applications.
>> */
>
> Please add
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> before any #include and...
Thanks, I've added it.
>> static int __init fblog_init(void)
>> {
>> + int ret;
>> +
>> + ret = fb_register_client(&fblog_notifier);
>> + if (ret) {
>> + pr_err("fblog: cannot register framebuffer notifier");
>
> Missing newline, pr_fmt would add module name.
>
> pr_err("cannot register framebuffer notifier\n");
Fixed, too. Thanks!
David
^ permalink raw reply
* Re: [PATCH v2 04/11] fbdev: export get_fb_info()/put_fb_info()
From: David Herrmann @ 2012-07-09 17:34 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <CAMuHMdWsSqMjqDuE_qgNUjc1eCWZqLLo1GNxwLYZNih=YBFh0g@mail.gmail.com>
Hi Geert
On Mon, Jul 9, 2012 at 9:34 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Sun, Jul 8, 2012 at 11:56 PM, David Herrmann
> <dh.herrmann@googlemail.com> wrote:
>> --- a/drivers/video/fbmem.c
>> +++ b/drivers/video/fbmem.c
>> @@ -46,7 +46,7 @@ static DEFINE_MUTEX(registration_lock);
>> struct fb_info *registered_fb[FB_MAX] __read_mostly;
>> int num_registered_fb __read_mostly;
>>
>> -static struct fb_info *get_fb_info(unsigned int idx)
>> +struct fb_info *get_fb_info(unsigned int idx)
>> {
>> struct fb_info *fb_info;
>>
>> @@ -61,14 +61,16 @@ static struct fb_info *get_fb_info(unsigned int idx)
>>
>> return fb_info;
>> }
>> +EXPORT_SYMBOL(get_fb_info);
>
> EXPORT_SYMBOL_GPL?
Thanks, that seems more appropriate here. I've fixed it.
>> -static void put_fb_info(struct fb_info *fb_info)
>> +void put_fb_info(struct fb_info *fb_info)
>> {
>> if (!atomic_dec_and_test(&fb_info->count))
>> return;
>> if (fb_info->fbops->fb_destroy)
>> fb_info->fbops->fb_destroy(fb_info);
>> }
>> +EXPORT_SYMBOL(put_fb_info);
>
> EXPORT_SYMBOL_GPL?
Thanks
David
^ permalink raw reply
* Re: can't detect 16550A at port 0x010 on Vortex86dx board
From: Alan Cox @ 2012-07-09 15:52 UTC (permalink / raw)
To: Aras Vaichas; +Cc: linux-serial
In-Reply-To: <CAJkQPOmBQPejYxa7=nW6pczCP+soYgLCxhuGHQMg3MjO0aZVmQ@mail.gmail.com>
> CONFIG_SERIAL_8250_SHARE_IRQ=y
>
> It needed IRQ sharing to make it work.
Fair enough, that's usually set.
> COM9 on a Vortex86DX is now working in Linux 3.3.8 but it requires
> more than a simple serial driver patch.
>
> I'm not entirely sure how to go about creating a proper patch for the
> changes I have made. My serial driver writes to the South Bridge, but
> it's a quick hack using outl() calls to the right addresses. Should I
> use a proper PCI function call?
If the Southbridge is a PCI device then yes.
> I also modified the x86 io port mappings in /arch/x86/kernel/setup.c.
> Do I either add #ifdef-ery to setup.c, or create a new entry in
> arch/x86/kernel/cpu/ and do my different io mappings there?
ifdeffery is bad. New cpu type is preferable. If the differences are
trivial then some kind of runtime handling is even better.
What you could do is post the hack patch with the questions attached -
not as a proposed kernel patch but as a "what is needed" guide so we can
work out the best way to do it.
Alan
^ permalink raw reply
* Re: can't detect 16550A at port 0x010 on Vortex86dx board
From: Aras Vaichas @ 2012-07-09 15:15 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-serial
In-Reply-To: <CAJkQPO=GYpDYOTiQ+Z-cs34=RRwnJLED79Xo4sZXg_Nd_2xM_A@mail.gmail.com>
> # cat .config
> <snip>
> #
> # Serial drivers
> #
> CONFIG_SERIAL_8250=y
> CONFIG_SERIAL_8250_CONSOLE=y
> CONFIG_FIX_EARLYCON_MEM=y
> CONFIG_SERIAL_8250_NR_UARTS=5
> CONFIG_SERIAL_8250_RUNTIME_UARTS=5
> CONFIG_SERIAL_8250_EXTENDED=y
> CONFIG_SERIAL_8250_MANY_PORTS=y
> CONFIG_SERIAL_8250_VORTEX=y
> </snip>
CONFIG_SERIAL_8250_SHARE_IRQ=y
It needed IRQ sharing to make it work.
COM9 on a Vortex86DX is now working in Linux 3.3.8 but it requires
more than a simple serial driver patch.
I'm not entirely sure how to go about creating a proper patch for the
changes I have made. My serial driver writes to the South Bridge, but
it's a quick hack using outl() calls to the right addresses. Should I
use a proper PCI function call?
I also modified the x86 io port mappings in /arch/x86/kernel/setup.c.
Do I either add #ifdef-ery to setup.c, or create a new entry in
arch/x86/kernel/cpu/ and do my different io mappings there?
Aras
^ permalink raw reply
* Re: can't detect 16550A at port 0x010 on Vortex86dx board
From: Aras Vaichas @ 2012-07-09 12:42 UTC (permalink / raw)
To: Alan Cox; +Cc: linux-serial
In-Reply-To: <20120706235459.5886e2ee@pyramind.ukuu.org.uk>
On 6 July 2012 23:54, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
>> Would Linux block my ability to manually probe these i/o ports?
>
> Not beyond reserving the region which you've said you've covered.
>
> What you may want to try is making sure Linux doesn't program the DMA
> controller (in case its doing something which disables the port in poking
> at it).
>
> Beyond that I guess ask the manufacturer for info.
Thank you. It turned out that I needed to configure the Southbridge.
I managed to get a complete datasheet and I have set all the correct
registers in the Southbridge to enable COM9 at port 0x010 with irq 9
(default values). Either the BIOS or Linux changed it from the default
values. I set the correct values in my serial port init_ function and
autoconfig detects the UART now.
# dmesg
<snip>
Serial: 8250/16550 driver, 5 ports, IRQ sharing disabled
serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
serial8250: ttyS2 at I/O 0x3e8 (irq = 4) is a 16550A
serial8250: ttyS3 at I/O 0x2e8 (irq = 3) is a 16550A
Vortex init of South Bridge for COM9
serial8250.11: ttyS4 at I/O 0x10 (irq = 9) is a 16550A
</snip>
I still have a problem though, I can't seem to use the device. e.g.
# echo hello > /dev/ttyS4
sh: write error: Input/output error
# cat /dev/ttyS4
sh: write error: Input/output error
# picocom -b 115200 /dev/ttyS4
FATAL: failed to add device /dev/ttyS4: Filedes is not a tty
# cat .config
<snip>
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_NR_UARTS=5
CONFIG_SERIAL_8250_RUNTIME_UARTS=5
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_VORTEX=y
</snip>
# cat /proc/tty/drivers
/dev/tty /dev/tty 5 0 system:/dev/tty
/dev/console /dev/console 5 1 system:console
/dev/ptmx /dev/ptmx 5 2 system
/dev/vc/0 /dev/vc/0 4 0 system:vtmaster
serial /dev/ttyS 4 64-68 serial
pty_slave /dev/pts 136 0-1048575 pty:slave
pty_master /dev/ptm 128 0-1048575 pty:master
unknown /dev/tty 4 1-63 console
There only appears to only be 4 ttySx drivers in use.
# cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A port:000003F8 irq:4 tx:19983 rx:548 RTS|DTR|RI
1: uart:16550A port:000002F8 irq:3 tx:0 rx:0
2: uart:16550A port:000003E8 irq:10 tx:0 rx:0
3: uart:16550A port:000002E8 irq:11 tx:7 rx:0
4: uart:16550A port:00000010 irq:9 tx:0 rx:0
Aras
^ permalink raw reply
* Re: [PATCH v2 04/11] fbdev: export get_fb_info()/put_fb_info()
From: Geert Uytterhoeven @ 2012-07-09 7:34 UTC (permalink / raw)
To: David Herrmann
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <1341784614-2797-5-git-send-email-dh.herrmann@googlemail.com>
On Sun, Jul 8, 2012 at 11:56 PM, David Herrmann
<dh.herrmann@googlemail.com> wrote:
> --- a/drivers/video/fbmem.c
> +++ b/drivers/video/fbmem.c
> @@ -46,7 +46,7 @@ static DEFINE_MUTEX(registration_lock);
> struct fb_info *registered_fb[FB_MAX] __read_mostly;
> int num_registered_fb __read_mostly;
>
> -static struct fb_info *get_fb_info(unsigned int idx)
> +struct fb_info *get_fb_info(unsigned int idx)
> {
> struct fb_info *fb_info;
>
> @@ -61,14 +61,16 @@ static struct fb_info *get_fb_info(unsigned int idx)
>
> return fb_info;
> }
> +EXPORT_SYMBOL(get_fb_info);
EXPORT_SYMBOL_GPL?
> -static void put_fb_info(struct fb_info *fb_info)
> +void put_fb_info(struct fb_info *fb_info)
> {
> if (!atomic_dec_and_test(&fb_info->count))
> return;
> if (fb_info->fbops->fb_destroy)
> fb_info->fbops->fb_destroy(fb_info);
> }
> +EXPORT_SYMBOL(put_fb_info);
EXPORT_SYMBOL_GPL?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v2 11/11] MAINTAINERS: add fblog entry
From: Geert Uytterhoeven @ 2012-07-09 7:33 UTC (permalink / raw)
To: David Herrmann
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <1341784614-2797-12-git-send-email-dh.herrmann@googlemail.com>
On Sun, Jul 8, 2012 at 11:56 PM, David Herrmann
<dh.herrmann@googlemail.com> wrote:
> Add myself as maintainer for the fblog driver to the MAINTAINERS file.
>
> Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
> ---
> MAINTAINERS | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ae8fe46..249b02a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2854,6 +2854,12 @@ F: drivers/video/
> F: include/video/
> F: include/linux/fb.h
>
> +FRAMEBUFFER LOG DRIVER
> +M: David Herrmann <dh.herrmann@googlemail.com>
> +L: linux-serial@vger.kernel.org
Why linux-serial, and not linux-fbdev?
> +S: Maintained
> +F: drivers/video/console/fblog.c
> +
> FREESCALE DMA DRIVER
> M: Li Yang <leoli@freescale.com>
> M: Zhang Wei <zw@zh-kernel.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v2 05/11] fblog: register one fblog object per framebuffer
From: Joe Perches @ 2012-07-08 22:13 UTC (permalink / raw)
To: David Herrmann
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <1341784614-2797-6-git-send-email-dh.herrmann@googlemail.com>
On Sun, 2012-07-08 at 23:56 +0200, David Herrmann wrote:
>
Hi David. Trivial comments only:
> diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
[]
> @@ -23,15 +23,204 @@
> * all fblog instances before running other graphics applications.
> */
Please add
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
before any #include and...
> static int __init fblog_init(void)
> {
> + int ret;
> +
> + ret = fb_register_client(&fblog_notifier);
> + if (ret) {
> + pr_err("fblog: cannot register framebuffer notifier");
Missing newline, pr_fmt would add module name.
pr_err("cannot register framebuffer notifier\n");
^ permalink raw reply
* Re: [PATCH v2 09/11] fblog: register console driver
From: Joe Perches @ 2012-07-08 22:09 UTC (permalink / raw)
To: David Herrmann
Cc: linux-serial, linux-kernel, florianschandinat, linux-fbdev,
gregkh, alan, bonbons
In-Reply-To: <1341784614-2797-10-git-send-email-dh.herrmann@googlemail.com>
On Sun, 2012-07-08 at 23:56 +0200, David Herrmann wrote:
> We want to print the kernel log to all FBs so we need a console driver.
> This registers the driver on startup and writes all messages to all
> registered fblog instances.
Hi David. Trivia only:
> diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
[]
> @@ -47,6 +71,107 @@ static struct fblog_fb *fblog_fbs[FB_MAX];
> static bool active = 1;
>
> #define to_fblog_dev(_d) container_of(_d, struct fblog_fb, dev)
> +#define FBLOG_STR(x) x, sizeof(x) - 1
That's a rather ugly macro.
> +static void fblog_buf_resize(struct fblog_buf *buf, size_t width,
> + size_t height)
> +{
> + u16 **lines = NULL;
> + size_t i, j, minw, minh;
> +
> + if (buf->height == height && buf->width == width)
> + return;
> +
> + if (width && height) {
> + lines = kzalloc(height * sizeof(char*), GFP_KERNEL);
sizeof(char *) is a bit more kernel style like.
^ permalink raw reply
* [PATCH v2 07/11] fblog: allow selecting fbs via sysfs
From: David Herrmann @ 2012-07-08 21:56 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, florianschandinat, linux-fbdev, gregkh, alan,
bonbons, David Herrmann
In-Reply-To: <1341784614-2797-1-git-send-email-dh.herrmann@googlemail.com>
fblog is mainly useful during boot, reboot, panics and maintenance. In all
cases you often want to control which monitors are used for console
output. Moreover, in multi-seat environments it is desireable to reduce
system-overhead by not drawing the console to all framebuffers. Two
mechanisms to select framebuffers for fblog are added:
1) "active" module parameter: This parameter selects whether new
framebuffers are opened automatically. By default this is on, that is, all
framebuffers are automatically used by fblog during boot. By passing
fblog.active=0 you can deactivate this.
The init process can set this to 0 via
/sys/modules/fblog/parameters/active, too. However, this does not affect
already available and used framebuffers in any way.
2) "active" sysfs attribute for each fblog object. Reading this value
returns whether a framebuffer is currently active. Writing it opens/closes
the framebuffer. This allows runtime control which fbs are used. For
instance, init can set these to 0 after bootup.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
drivers/video/console/fblog.c | 50 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c
index 113be36..b490dba 100644
--- a/drivers/video/console/fblog.c
+++ b/drivers/video/console/fblog.c
@@ -42,6 +42,7 @@ struct fblog_fb {
static DEFINE_MUTEX(fblog_registration_lock);
static struct fblog_fb *fblog_fbs[FB_MAX];
+static bool active = 1;
#define to_fblog_dev(_d) container_of(_d, struct fblog_fb, dev)
@@ -116,6 +117,37 @@ static void fblog_close(struct fblog_fb *fb, bool kill_dev, bool locked)
mutex_unlock(&fb->lock);
}
+static ssize_t fblog_dev_active_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fblog_fb *fb = to_fblog_dev(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ !!test_bit(FBLOG_OPEN, &fb->flags));
+}
+
+static ssize_t fblog_dev_active_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct fblog_fb *fb = to_fblog_dev(dev);
+ unsigned long num;
+ int ret = 0;
+
+ num = simple_strtoul(buf, NULL, 10);
+ if (num)
+ ret = fblog_open(fb, false);
+ else
+ fblog_close(fb, false, false);
+
+ return ret ? ret : count;
+}
+
+static DEVICE_ATTR(active, S_IRUGO | S_IWUSR | S_IWGRP, fblog_dev_active_show,
+ fblog_dev_active_store);
+
/*
* fblog framebuffer list
* The fblog_fbs[] array contains all currently registered framebuffers. If a
@@ -149,6 +181,7 @@ static void fblog_do_unregister(struct fb_info *info)
fblog_fbs[info->node] = NULL;
fblog_close(fb, true, false);
+ device_remove_file(&fb->dev, &dev_attr_active);
device_del(&fb->dev);
put_device(&fb->dev);
}
@@ -157,6 +190,7 @@ static void fblog_do_register(struct fb_info *info, bool force)
{
struct fblog_fb *fb;
int ret;
+ bool do_open = true;
fb = fblog_fbs[info->node];
if (fb && fb->info != info) {
@@ -187,7 +221,18 @@ static void fblog_do_register(struct fb_info *info, bool force)
return;
}
- fblog_open(fb, true);
+ ret = device_create_file(&fb->dev, &dev_attr_active);
+ if (ret) {
+ pr_err("fblog: cannot create sysfs entry");
+ /* do not open fb if we cannot create control file */
+ do_open = false;
+ }
+
+ if (!active)
+ do_open = false;
+
+ if (do_open)
+ fblog_open(fb, true);
}
static void fblog_register(struct fb_info *info, bool force)
@@ -314,6 +359,9 @@ static void __exit fblog_exit(void)
}
}
+module_param(active, bool, S_IRUGO);
+MODULE_PARM_DESC(active, "Activate fblog by default");
+
module_init(fblog_init);
module_exit(fblog_exit);
MODULE_LICENSE("GPL");
--
1.7.11.1
^ permalink raw reply related
* [PATCH v2 04/11] fbdev: export get_fb_info()/put_fb_info()
From: David Herrmann @ 2012-07-08 21:56 UTC (permalink / raw)
To: linux-serial
Cc: linux-kernel, florianschandinat, linux-fbdev, gregkh, alan,
bonbons, David Herrmann
In-Reply-To: <1341784614-2797-1-git-send-email-dh.herrmann@googlemail.com>
When adding other internal users of the framebuffer subsystem, we need a
way to get references to framebuffers. These two functions already exist
so export them.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
drivers/video/fbmem.c | 6 ++++--
include/linux/fb.h | 3 +++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0dff12a..474460c 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -46,7 +46,7 @@ static DEFINE_MUTEX(registration_lock);
struct fb_info *registered_fb[FB_MAX] __read_mostly;
int num_registered_fb __read_mostly;
-static struct fb_info *get_fb_info(unsigned int idx)
+struct fb_info *get_fb_info(unsigned int idx)
{
struct fb_info *fb_info;
@@ -61,14 +61,16 @@ static struct fb_info *get_fb_info(unsigned int idx)
return fb_info;
}
+EXPORT_SYMBOL(get_fb_info);
-static void put_fb_info(struct fb_info *fb_info)
+void put_fb_info(struct fb_info *fb_info)
{
if (!atomic_dec_and_test(&fb_info->count))
return;
if (fb_info->fbops->fb_destroy)
fb_info->fbops->fb_destroy(fb_info);
}
+EXPORT_SYMBOL(put_fb_info);
int lock_fb_info(struct fb_info *info)
{
diff --git a/include/linux/fb.h b/include/linux/fb.h
index ac3f1c6..2d51c0e 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1033,6 +1033,9 @@ static inline void unlock_fb_info(struct fb_info *info)
mutex_unlock(&info->lock);
}
+extern struct fb_info *get_fb_info(unsigned int idx);
+extern void put_fb_info(struct fb_info *fb_info);
+
static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
u8 *src, u32 s_pitch, u32 height)
{
--
1.7.11.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox