aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
commitc6da2cfeb05178a11c6d062a06f8078150ee492f (patch)
treef3b4021d252c52d6463a9b3c1bb7245e399b009c /drivers/tty
parentc6d7c4dbff353eac7919342ae6b3299a378160a6 (diff)
downloadkernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2
samsung update 1
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250.c2
-rw-r--r--drivers/tty/serial/Kconfig15
-rw-r--r--drivers/tty/serial/s5pv210.c14
-rw-r--r--drivers/tty/serial/samsung.c99
-rw-r--r--drivers/tty/serial/samsung.h19
-rw-r--r--drivers/tty/serial/serial_core.c22
-rw-r--r--drivers/tty/sysrq.c3
-rw-r--r--drivers/tty/vt/.gitignore2
8 files changed, 124 insertions, 52 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index 762ce72..d1ccd3a 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -1772,7 +1772,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
static void serial_unlink_irq_chain(struct uart_8250_port *up)
{
- struct irq_info *i;
+ struct irq_info *i = NULL;
struct hlist_node *n;
struct hlist_head *h;
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 9789293..3577377 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -489,6 +489,17 @@ config SERIAL_SAMSUNG_CONSOLE
your boot loader about how to pass options to the kernel at
boot time.)
+config SERIAL_SAMSUNG_CONSOLE_SWITCH
+ bool "Support for console switch on Samsung SoC serial port"
+ depends on SERIAL_SAMSUNG_CONSOLE=y
+ default n
+ help
+ Allow kernel cmdline to switch Samsung Soc serial ports for use as
+ an virtual console or not. This may serve a port usage selection.
+
+ Even if you say Y here, you should add samsung.uart_debug=1
+ into kernel cmdline to enable virtual console.
+
config SERIAL_S3C2400
tristate "Samsung S3C2410 Serial port support"
depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400
@@ -537,8 +548,8 @@ config SERIAL_S3C6400
config SERIAL_S5PV210
tristate "Samsung S5PV210 Serial port support"
- depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210)
- select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210)
+ depends on SERIAL_SAMSUNG && (CPU_S5PV210 || ARCH_EXYNOS)
+ select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || ARCH_EXYNOS)
default y
help
Serial port support for Samsung's S5P Family of SoC's
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
index dd194dc..ce7a077 100644
--- a/drivers/tty/serial/s5pv210.c
+++ b/drivers/tty/serial/s5pv210.c
@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
+#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
@@ -83,6 +84,12 @@ static int s5pv210_serial_resetport(struct uart_port *port,
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
+ wr_regl(port, S3C64XX_UINTM, 0xf);
+ wr_regl(port, S3C64XX_UINTP, 0xf);
+
+ /* It is need to delay when reset FIFO register */
+ udelay(1);
+
return 0;
}
@@ -135,13 +142,6 @@ static struct platform_driver s5p_serial_driver = {
},
};
-static int __init s5pv210_serial_console_init(void)
-{
- return s3c24xx_serial_initconsole(&s5p_serial_driver, s5p_uart_inf);
-}
-
-console_initcall(s5pv210_serial_console_init);
-
static int __init s5p_serial_init(void)
{
return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf);
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index f66f648..2468df0 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -66,6 +66,18 @@
/* flag to ignore all characters coming in */
#define RXSTAT_DUMMY_READ (0x10000000)
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_MIDAS) || \
+ defined(CONFIG_MACH_SLP_PQ)||defined(CONFIG_MACH_P10)
+/* Devices */
+#define CONFIG_BT_S3C_UART 0
+#define CONFIG_GPS_S3C_UART 1
+#endif
+
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH
+static unsigned uart_debug; /* Initialized automatically with 0 by compiler */
+module_param_named(uart_debug, uart_debug, uint, 0644);
+#endif
+
static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
{
return container_of(port, struct s3c24xx_uart_port, port);
@@ -351,6 +363,28 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
/* todo - possibly remove AFC and do manual CTS */
+
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_MIDAS) || \
+ defined(CONFIG_MACH_SLP_PQ) || defined(CONFIG_MACH_P10) || \
+ defined(CONFIG_MACH_U1CAMERA_BD)
+ unsigned int umcon = 0;
+ umcon = rd_regl(port, S3C2410_UMCON);
+
+ if (port->line == CONFIG_BT_S3C_UART) {
+ if (mctrl & TIOCM_RTS) {
+ umcon |= S3C2410_UMCOM_AFC;
+ } else {
+ umcon &= ~S3C2410_UMCOM_AFC;
+ }
+
+ } else if (port->line == CONFIG_GPS_S3C_UART) {
+ umcon |= S3C2410_UMCOM_AFC;
+ } else {
+ umcon &= ~S3C2410_UMCOM_AFC;
+ }
+
+ wr_regl(port, S3C2410_UMCON, umcon);
+#endif
}
static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
@@ -375,29 +409,40 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
static void s3c24xx_serial_shutdown(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
+ struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
if (ourport->tx_claimed) {
+ disable_irq(ourport->tx_irq);
free_irq(ourport->tx_irq, ourport);
tx_enabled(port) = 0;
ourport->tx_claimed = 0;
}
if (ourport->rx_claimed) {
+ disable_irq(ourport->rx_irq);
free_irq(ourport->rx_irq, ourport);
ourport->rx_claimed = 0;
rx_enabled(port) = 0;
}
+
+ if (cfg->set_runstate)
+ cfg->set_runstate(0);
}
static int s3c24xx_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
+ struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
int ret;
dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
port->mapbase, port->membase);
+ /* runstate should be 1 before request_irq is called */
+ if (cfg->set_runstate)
+ cfg->set_runstate(1);
+
rx_enabled(port) = 1;
ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
@@ -405,7 +450,7 @@ static int s3c24xx_serial_startup(struct uart_port *port)
if (ret != 0) {
printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
- return ret;
+ goto err;
}
ourport->rx_claimed = 1;
@@ -574,7 +619,7 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
*/
if (strcmp(clkp->name, "fclk") == 0) {
- struct s3c24xx_uart_clksrc src;
+ struct s3c24xx_uart_clksrc src = { "", 0, };
s3c24xx_serial_getsource(port, &src);
@@ -596,6 +641,7 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
} else {
resptr = res;
+ best = res;
for (i = 0; i < cfg->clocks_size; i++, clkp++) {
if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
resptr++;
@@ -608,6 +654,7 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
unsigned int deviation = (1<<30)|((1<<30)-1);
int calc_deviation;
+ best = res;
for (sptr = res; sptr < resptr; sptr++) {
calc_deviation = baud - sptr->calc;
if (calc_deviation < 0)
@@ -675,9 +722,12 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
/*
* Ask the core to calculate the divisor for us.
*/
-
- baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
-
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_MIDAS) || \
+ defined(CONFIG_MACH_SLP_PQ)||defined(CONFIG_MACH_P10)
+ baud = uart_get_baud_rate(port, termios, old, 0, 4000000); // 4Mbps
+#else
+ baud = uart_get_baud_rate(port, termios, old, 0, 3000000);
+#endif
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor;
else
@@ -849,6 +899,14 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
return 0;
}
+static void
+s3c24xx_serial_wake_peer(struct uart_port *port)
+{
+ struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
+
+ if(cfg->wake_peer)
+ cfg->wake_peer(port);
+}
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
@@ -877,6 +935,7 @@ static struct uart_ops s3c24xx_serial_ops = {
.request_port = s3c24xx_serial_request_port,
.config_port = s3c24xx_serial_config_port,
.verify_port = s3c24xx_serial_verify_port,
+ .wake_peer = s3c24xx_serial_wake_peer,
};
@@ -884,7 +943,11 @@ static struct uart_driver s3c24xx_uart_drv = {
.owner = THIS_MODULE,
.driver_name = "s3c2410_serial",
.nr = CONFIG_SERIAL_SAMSUNG_UARTS,
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH
+ .cons = NULL,
+#else
.cons = S3C24XX_SERIAL_CONSOLE,
+#endif
.dev_name = S3C24XX_SERIAL_NAME,
.major = S3C24XX_SERIAL_MAJOR,
.minor = S3C24XX_SERIAL_MINOR,
@@ -982,10 +1045,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
* a disturbance in the clock-rate over the change.
*/
- if (IS_ERR(port->clk))
+ if (IS_ERR_OR_NULL(port->baudclk))
goto exit;
- if (port->baudclk_rate == clk_get_rate(port->clk))
+ if (port->baudclk_rate == clk_get_rate(port->baudclk))
goto exit;
if (val == CPUFREQ_PRECHANGE) {
@@ -1109,7 +1172,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
ourport->rx_irq = ret;
ourport->tx_irq = ret + 1;
}
-
+
ret = platform_get_irq(platdev, 1);
if (ret > 0)
ourport->tx_irq = ret;
@@ -1132,7 +1195,8 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
struct uart_port *port = s3c24xx_dev_to_port(dev);
struct s3c24xx_uart_port *ourport = to_ourport(port);
- return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name);
+ return snprintf(buf, PAGE_SIZE, "* %s\n",
+ ourport->clksrc ? ourport->clksrc->name : "(null)");
}
static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
@@ -1244,7 +1308,10 @@ EXPORT_SYMBOL_GPL(s3c24xx_serial_init);
static int __init s3c24xx_serial_modinit(void)
{
int ret;
-
+#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH
+ if (uart_debug)
+ s3c24xx_uart_drv.cons = S3C24XX_SERIAL_CONSOLE;
+#endif
ret = uart_register_driver(&s3c24xx_uart_drv);
if (ret < 0) {
printk(KERN_ERR "failed to register UART driver\n");
@@ -1307,7 +1374,7 @@ static void __init
s3c24xx_serial_get_options(struct uart_port *port, int *baud,
int *parity, int *bits)
{
- struct s3c24xx_uart_clksrc clksrc;
+ struct s3c24xx_uart_clksrc clksrc = { "", 0, };
struct clk *clk;
unsigned int ulcon;
unsigned int ucon;
@@ -1365,7 +1432,6 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
else
rate = 1;
-
*baud = rate / (16 * (ubrdiv + 1));
dbg("calculated baud %d\n", *baud);
}
@@ -1416,10 +1482,8 @@ s3c24xx_serial_console_setup(struct console *co, char *options)
/* is the port configured? */
- if (port->mapbase == 0x0) {
- co->index = 0;
- port = &s3c24xx_serial_ports[co->index].port;
- }
+ if (port->mapbase == 0x0)
+ return -ENODEV;
cons_uart = port;
@@ -1451,7 +1515,8 @@ static struct console s3c24xx_serial_console = {
.flags = CON_PRINTBUFFER,
.index = -1,
.write = s3c24xx_serial_console_write,
- .setup = s3c24xx_serial_console_setup
+ .setup = s3c24xx_serial_console_setup,
+ .data = &s3c24xx_uart_drv,
};
int s3c24xx_serial_initconsole(struct platform_driver *drv,
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 5b098cd..a69d9a5 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -79,25 +79,6 @@ extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
extern int s3c24xx_serial_init(struct platform_driver *drv,
struct s3c24xx_uart_info *info);
-#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
-
-#define s3c24xx_console_init(__drv, __inf) \
-static int __init s3c_serial_console_init(void) \
-{ \
- struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS]; \
- int i; \
- \
- for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) \
- uinfo[i] = __inf; \
- return s3c24xx_serial_initconsole(__drv, uinfo); \
-} \
- \
-console_initcall(s3c_serial_console_init)
-
-#else
-#define s3c24xx_console_init(drv, inf) extern void no_console(void)
-#endif
-
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
extern void printascii(const char *);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 6bc20d7..65db939 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -91,6 +91,9 @@ static void __uart_start(struct tty_struct *tty)
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
+ if (port->ops->wake_peer)
+ port->ops->wake_peer(port);
+
if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
!tty->stopped && !tty->hw_stopped)
port->ops->start_tx(port);
@@ -159,13 +162,17 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in
* buffer.
*/
if (!state->xmit.buf) {
+ unsigned long flags;
+
/* This is protected by the per port mutex */
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
+ spin_lock_irqsave(&uport->lock, flags);
state->xmit.buf = (unsigned char *) page;
uart_circ_clear(&state->xmit);
+ spin_unlock_irqrestore(&uport->lock, flags);
}
retval = uport->ops->startup(uport);
@@ -258,8 +265,11 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
* Free the transmit buffer page.
*/
if (state->xmit.buf) {
+ unsigned long flags;
+ spin_lock_irqsave(&uport->lock, flags);
free_page((unsigned long)state->xmit.buf);
state->xmit.buf = NULL;
+ spin_unlock_irqrestore(&uport->lock, flags);
}
}
@@ -468,10 +478,12 @@ static inline int __uart_put_char(struct uart_port *port,
unsigned long flags;
int ret = 0;
- if (!circ->buf)
+ spin_lock_irqsave(&port->lock, flags);
+ if (!circ->buf) {
+ spin_unlock_irqrestore(&port->lock, flags);
return 0;
+ }
- spin_lock_irqsave(&port->lock, flags);
if (uart_circ_chars_free(circ) != 0) {
circ->buf[circ->head] = c;
circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
@@ -514,10 +526,12 @@ static int uart_write(struct tty_struct *tty,
port = state->uart_port;
circ = &state->xmit;
- if (!circ->buf)
+ spin_lock_irqsave(&port->lock, flags);
+ if (!circ->buf) {
+ spin_unlock_irqrestore(&port->lock, flags);
return 0;
+ }
- spin_lock_irqsave(&port->lock, flags);
while (1) {
c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
if (count < c)
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 43db715..b74b08f 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -142,6 +142,9 @@ static struct sysrq_key_op sysrq_crash_op = {
static void sysrq_handle_reboot(int key)
{
+#ifdef COFIG_SEC_DEBUG_SYSRQ_B
+ BUG();
+#endif
lockdep_off();
local_irq_enable();
emergency_restart();
diff --git a/drivers/tty/vt/.gitignore b/drivers/tty/vt/.gitignore
deleted file mode 100644
index 83683a2..0000000
--- a/drivers/tty/vt/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-consolemap_deftbl.c
-defkeymap.c