aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/Kconfig9
-rw-r--r--drivers/tty/serial/pch_uart.c160
2 files changed, 168 insertions, 1 deletions
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 5f479dada6f2..956f2f02947b 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1575,6 +1575,15 @@ config SERIAL_PCH_UART
1575 ML7213/ML7223 is companion chip for Intel Atom E6xx series. 1575 ML7213/ML7223 is companion chip for Intel Atom E6xx series.
1576 ML7213/ML7223 is completely compatible for Intel EG20T PCH. 1576 ML7213/ML7223 is completely compatible for Intel EG20T PCH.
1577 1577
1578config SERIAL_PCH_UART_CONSOLE
1579 bool "Support for console on Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH"
1580 depends on SERIAL_PCH_UART=y
1581 select SERIAL_CORE_CONSOLE
1582 help
1583 Say Y here if you wish to use the PCH UART as the system console
1584 (the system console is the device which receives all kernel messages and
1585 warnings and which allows logins in single user mode).
1586
1578config SERIAL_MSM_SMD 1587config SERIAL_MSM_SMD
1579 bool "Enable tty device interface for some SMD ports" 1588 bool "Enable tty device interface for some SMD ports"
1580 default n 1589 default n
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 21febef926aa..b950d059a781 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -25,6 +25,9 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/dmi.h> 27#include <linux/dmi.h>
28#include <linux/console.h>
29#include <linux/nmi.h>
30#include <linux/delay.h>
28 31
29#include <linux/dmaengine.h> 32#include <linux/dmaengine.h>
30#include <linux/pch_dma.h> 33#include <linux/pch_dma.h>
@@ -198,6 +201,10 @@ enum {
198 201
199#define PCI_VENDOR_ID_ROHM 0x10DB 202#define PCI_VENDOR_ID_ROHM 0x10DB
200 203
204#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
205
206#define DEFAULT_BAUD_RATE 1843200 /* 1.8432MHz */
207
201struct pch_uart_buffer { 208struct pch_uart_buffer {
202 unsigned char *buf; 209 unsigned char *buf;
203 int size; 210 int size;
@@ -272,6 +279,9 @@ static struct pch_uart_driver_data drv_dat[] = {
272 [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, 279 [pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
273}; 280};
274 281
282#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
283static struct eg20t_port *pch_uart_ports[PCH_UART_NR];
284#endif
275static unsigned int default_baud = 9600; 285static unsigned int default_baud = 9600;
276static const int trigger_level_256[4] = { 1, 64, 128, 224 }; 286static const int trigger_level_256[4] = { 1, 64, 128, 224 };
277static const int trigger_level_64[4] = { 1, 16, 32, 56 }; 287static const int trigger_level_64[4] = { 1, 16, 32, 56 };
@@ -1380,6 +1390,143 @@ static struct uart_ops pch_uart_ops = {
1380 .verify_port = pch_uart_verify_port 1390 .verify_port = pch_uart_verify_port
1381}; 1391};
1382 1392
1393#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1394
1395/*
1396 * Wait for transmitter & holding register to empty
1397 */
1398static void wait_for_xmitr(struct eg20t_port *up, int bits)
1399{
1400 unsigned int status, tmout = 10000;
1401
1402 /* Wait up to 10ms for the character(s) to be sent. */
1403 for (;;) {
1404 status = ioread8(up->membase + UART_LSR);
1405
1406 if ((status & bits) == bits)
1407 break;
1408 if (--tmout == 0)
1409 break;
1410 udelay(1);
1411 }
1412
1413 /* Wait up to 1s for flow control if necessary */
1414 if (up->port.flags & UPF_CONS_FLOW) {
1415 unsigned int tmout;
1416 for (tmout = 1000000; tmout; tmout--) {
1417 unsigned int msr = ioread8(up->membase + UART_MSR);
1418 if (msr & UART_MSR_CTS)
1419 break;
1420 udelay(1);
1421 touch_nmi_watchdog();
1422 }
1423 }
1424}
1425
1426static void pch_console_putchar(struct uart_port *port, int ch)
1427{
1428 struct eg20t_port *priv =
1429 container_of(port, struct eg20t_port, port);
1430
1431 wait_for_xmitr(priv, UART_LSR_THRE);
1432 iowrite8(ch, priv->membase + PCH_UART_THR);
1433}
1434
1435/*
1436 * Print a string to the serial port trying not to disturb
1437 * any possible real use of the port...
1438 *
1439 * The console_lock must be held when we get here.
1440 */
1441static void
1442pch_console_write(struct console *co, const char *s, unsigned int count)
1443{
1444 struct eg20t_port *priv;
1445
1446 unsigned long flags;
1447 u8 ier;
1448 int locked = 1;
1449
1450 priv = pch_uart_ports[co->index];
1451
1452 touch_nmi_watchdog();
1453
1454 local_irq_save(flags);
1455 if (priv->port.sysrq) {
1456 /* serial8250_handle_port() already took the lock */
1457 locked = 0;
1458 } else if (oops_in_progress) {
1459 locked = spin_trylock(&priv->port.lock);
1460 } else
1461 spin_lock(&priv->port.lock);
1462
1463 /*
1464 * First save the IER then disable the interrupts
1465 */
1466 ier = ioread8(priv->membase + UART_IER);
1467
1468 pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
1469
1470 uart_console_write(&priv->port, s, count, pch_console_putchar);
1471
1472 /*
1473 * Finally, wait for transmitter to become empty
1474 * and restore the IER
1475 */
1476 wait_for_xmitr(priv, BOTH_EMPTY);
1477 iowrite8(ier, priv->membase + UART_IER);
1478
1479 if (locked)
1480 spin_unlock(&priv->port.lock);
1481 local_irq_restore(flags);
1482}
1483
1484static int __init pch_console_setup(struct console *co, char *options)
1485{
1486 struct uart_port *port;
1487 int baud = 9600;
1488 int bits = 8;
1489 int parity = 'n';
1490 int flow = 'n';
1491
1492 /*
1493 * Check whether an invalid uart number has been specified, and
1494 * if so, search for the first available port that does have
1495 * console support.
1496 */
1497 if (co->index >= PCH_UART_NR)
1498 co->index = 0;
1499 port = &pch_uart_ports[co->index]->port;
1500
1501 if (!port || (!port->iobase && !port->membase))
1502 return -ENODEV;
1503
1504 /* setup uartclock */
1505 port->uartclk = DEFAULT_BAUD_RATE;
1506
1507 if (options)
1508 uart_parse_options(options, &baud, &parity, &bits, &flow);
1509
1510 return uart_set_options(port, co, baud, parity, bits, flow);
1511}
1512
1513static struct uart_driver pch_uart_driver;
1514
1515static struct console pch_console = {
1516 .name = PCH_UART_DRIVER_DEVICE,
1517 .write = pch_console_write,
1518 .device = uart_console_device,
1519 .setup = pch_console_setup,
1520 .flags = CON_PRINTBUFFER | CON_ANYTIME,
1521 .index = -1,
1522 .data = &pch_uart_driver,
1523};
1524
1525#define PCH_CONSOLE (&pch_console)
1526#else
1527#define PCH_CONSOLE NULL
1528#endif
1529
1383static struct uart_driver pch_uart_driver = { 1530static struct uart_driver pch_uart_driver = {
1384 .owner = THIS_MODULE, 1531 .owner = THIS_MODULE,
1385 .driver_name = KBUILD_MODNAME, 1532 .driver_name = KBUILD_MODNAME,
@@ -1387,6 +1534,7 @@ static struct uart_driver pch_uart_driver = {
1387 .major = 0, 1534 .major = 0,
1388 .minor = 0, 1535 .minor = 0,
1389 .nr = PCH_UART_NR, 1536 .nr = PCH_UART_NR,
1537 .cons = PCH_CONSOLE,
1390}; 1538};
1391 1539
1392static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, 1540static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
@@ -1413,7 +1561,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
1413 if (!rxbuf) 1561 if (!rxbuf)
1414 goto init_port_free_txbuf; 1562 goto init_port_free_txbuf;
1415 1563
1416 base_baud = 1843200; /* 1.8432MHz */ 1564 base_baud = DEFAULT_BAUD_RATE;
1417 1565
1418 /* quirk for CM-iTC board */ 1566 /* quirk for CM-iTC board */
1419 board_name = dmi_get_system_info(DMI_BOARD_NAME); 1567 board_name = dmi_get_system_info(DMI_BOARD_NAME);
@@ -1463,6 +1611,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
1463 pci_set_drvdata(pdev, priv); 1611 pci_set_drvdata(pdev, priv);
1464 pch_uart_hal_request(pdev, fifosize, base_baud); 1612 pch_uart_hal_request(pdev, fifosize, base_baud);
1465 1613
1614#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1615 pch_uart_ports[board->line_no] = priv;
1616#endif
1466 ret = uart_add_one_port(&pch_uart_driver, &priv->port); 1617 ret = uart_add_one_port(&pch_uart_driver, &priv->port);
1467 if (ret < 0) 1618 if (ret < 0)
1468 goto init_port_hal_free; 1619 goto init_port_hal_free;
@@ -1470,6 +1621,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
1470 return priv; 1621 return priv;
1471 1622
1472init_port_hal_free: 1623init_port_hal_free:
1624#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1625 pch_uart_ports[board->line_no] = NULL;
1626#endif
1473 free_page((unsigned long)rxbuf); 1627 free_page((unsigned long)rxbuf);
1474init_port_free_txbuf: 1628init_port_free_txbuf:
1475 kfree(priv); 1629 kfree(priv);
@@ -1492,6 +1646,10 @@ static void pch_uart_pci_remove(struct pci_dev *pdev)
1492 priv = (struct eg20t_port *)pci_get_drvdata(pdev); 1646 priv = (struct eg20t_port *)pci_get_drvdata(pdev);
1493 1647
1494 pci_disable_msi(pdev); 1648 pci_disable_msi(pdev);
1649
1650#ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1651 pch_uart_ports[priv->port.line] = NULL;
1652#endif
1495 pch_uart_exit_port(priv); 1653 pch_uart_exit_port(priv);
1496 pci_disable_device(pdev); 1654 pci_disable_device(pdev);
1497 kfree(priv); 1655 kfree(priv);