diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-12 11:14:33 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-09-12 11:14:33 -0400 |
commit | 25a765b7f05cb8460fa01b54568894b20e184862 (patch) | |
tree | 0b56db57b4d9f912393ab303c269e0fe6cdf8635 /drivers/tty | |
parent | 9d2be9287107695708e6aae5105a8a518a6cb4d0 (diff) | |
parent | 64282278989d5b0398dcb3ba7904cb00c621dc35 (diff) |
Merge branch 'x86/platform' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into stable/for-linus-3.7
* 'x86/platform' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (9690 commits)
x86: Document x86_init.paging.pagetable_init()
x86: xen: Cleanup and remove x86_init.paging.pagetable_setup_done()
x86: Move paging_init() call to x86_init.paging.pagetable_init()
x86: Rename pagetable_setup_start() to pagetable_init()
x86: Remove base argument from x86_init.paging.pagetable_setup_start
Linux 3.6-rc5
HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured
Remove user-triggerable BUG from mpol_to_str
xen/pciback: Fix proper FLR steps.
uml: fix compile error in deliver_alarm()
dj: memory scribble in logi_dj
Fix order of arguments to compat_put_time[spec|val]
xen: Use correct masking in xen_swiotlb_alloc_coherent.
xen: fix logical error in tlb flushing
xen/p2m: Fix one-off error in checking the P2M tree directory.
powerpc: Don't use __put_user() in patch_instruction
powerpc: Make sure IPI handlers see data written by IPI senders
powerpc: Restore correct DSCR in context switch
powerpc: Fix DSCR inheritance in copy_thread()
powerpc: Keep thread.dscr and thread.dscr_inherit in sync
...
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/hvc/hvc_xen.c | 15 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250.c | 8 | ||||
-rw-r--r-- | drivers/tty/serial/Kconfig | 10 | ||||
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/ifx6x60.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/imx.c | 6 | ||||
-rw-r--r-- | drivers/tty/serial/mxs-auart.c | 56 | ||||
-rw-r--r-- | drivers/tty/serial/of_serial.c | 1 | ||||
-rw-r--r-- | drivers/tty/serial/pch_uart.c | 59 | ||||
-rw-r--r-- | drivers/tty/serial/pmac_zilog.c | 12 | ||||
-rw-r--r-- | drivers/tty/serial/samsung.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 6 | ||||
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 13 | ||||
-rw-r--r-- | drivers/tty/serial/uartlite.c | 3 | ||||
-rw-r--r-- | drivers/tty/tty_ldisc.c | 2 | ||||
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 47 |
16 files changed, 170 insertions, 76 deletions
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index dc07f56d66b5..2944ff88fdc0 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -211,11 +211,10 @@ static int xen_hvm_console_init(void) | |||
211 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); | 211 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); |
212 | if (!info) | 212 | if (!info) |
213 | return -ENOMEM; | 213 | return -ENOMEM; |
214 | } | 214 | } else if (info->intf != NULL) { |
215 | 215 | /* already configured */ | |
216 | /* already configured */ | ||
217 | if (info->intf != NULL) | ||
218 | return 0; | 216 | return 0; |
217 | } | ||
219 | /* | 218 | /* |
220 | * If the toolstack (or the hypervisor) hasn't set these values, the | 219 | * If the toolstack (or the hypervisor) hasn't set these values, the |
221 | * default value is 0. Even though mfn = 0 and evtchn = 0 are | 220 | * default value is 0. Even though mfn = 0 and evtchn = 0 are |
@@ -261,12 +260,10 @@ static int xen_pv_console_init(void) | |||
261 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); | 260 | info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); |
262 | if (!info) | 261 | if (!info) |
263 | return -ENOMEM; | 262 | return -ENOMEM; |
264 | } | 263 | } else if (info->intf != NULL) { |
265 | 264 | /* already configured */ | |
266 | /* already configured */ | ||
267 | if (info->intf != NULL) | ||
268 | return 0; | 265 | return 0; |
269 | 266 | } | |
270 | info->evtchn = xen_start_info->console.domU.evtchn; | 267 | info->evtchn = xen_start_info->console.domU.evtchn; |
271 | info->intf = mfn_to_virt(xen_start_info->console.domU.mfn); | 268 | info->intf = mfn_to_virt(xen_start_info->console.domU.mfn); |
272 | info->vtermno = HVC_COOKIE; | 269 | info->vtermno = HVC_COOKIE; |
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 6e1958a325bd..8123f784bcda 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
@@ -282,6 +282,14 @@ static const struct serial8250_config uart_config[] = { | |||
282 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 282 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
283 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, | 283 | .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR, |
284 | }, | 284 | }, |
285 | [PORT_LPC3220] = { | ||
286 | .name = "LPC3220", | ||
287 | .fifo_size = 64, | ||
288 | .tx_loadsz = 32, | ||
289 | .fcr = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO | | ||
290 | UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, | ||
291 | .flags = UART_CAP_FIFO, | ||
292 | }, | ||
285 | }; | 293 | }; |
286 | 294 | ||
287 | /* Uart divisor latch read */ | 295 | /* Uart divisor latch read */ |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 070b442c1f81..4720b4ba096a 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -160,10 +160,12 @@ config SERIAL_KS8695_CONSOLE | |||
160 | 160 | ||
161 | config SERIAL_CLPS711X | 161 | config SERIAL_CLPS711X |
162 | tristate "CLPS711X serial port support" | 162 | tristate "CLPS711X serial port support" |
163 | depends on ARM && ARCH_CLPS711X | 163 | depends on ARCH_CLPS711X |
164 | select SERIAL_CORE | 164 | select SERIAL_CORE |
165 | default y | ||
165 | help | 166 | help |
166 | ::: To be written ::: | 167 | This enables the driver for the on-chip UARTs of the Cirrus |
168 | Logic EP711x/EP721x/EP731x processors. | ||
167 | 169 | ||
168 | config SERIAL_CLPS711X_CONSOLE | 170 | config SERIAL_CLPS711X_CONSOLE |
169 | bool "Support for console on CLPS711X serial port" | 171 | bool "Support for console on CLPS711X serial port" |
@@ -173,9 +175,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
173 | Even if you say Y here, the currently visible virtual console | 175 | Even if you say Y here, the currently visible virtual console |
174 | (/dev/tty0) will still be used as the system console by default, but | 176 | (/dev/tty0) will still be used as the system console by default, but |
175 | you can alter that using a kernel command line option such as | 177 | you can alter that using a kernel command line option such as |
176 | "console=ttyCL1". (Try "man bootparam" or see the documentation of | 178 | "console=ttyCL1". |
177 | your boot loader (lilo or loadlin) about how to pass options to the | ||
178 | kernel at boot time.) | ||
179 | 179 | ||
180 | config SERIAL_SAMSUNG | 180 | config SERIAL_SAMSUNG |
181 | tristate "Samsung SoC serial support" | 181 | tristate "Samsung SoC serial support" |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index c17923ec6e95..d3553b5d3fca 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -53,9 +53,9 @@ | |||
53 | #include <linux/delay.h> | 53 | #include <linux/delay.h> |
54 | #include <linux/types.h> | 54 | #include <linux/types.h> |
55 | #include <linux/pinctrl/consumer.h> | 55 | #include <linux/pinctrl/consumer.h> |
56 | #include <linux/sizes.h> | ||
56 | 57 | ||
57 | #include <asm/io.h> | 58 | #include <asm/io.h> |
58 | #include <asm/sizes.h> | ||
59 | 59 | ||
60 | #define UART_NR 14 | 60 | #define UART_NR 14 |
61 | 61 | ||
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 144cd3987d4c..3ad079ffd049 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -1331,7 +1331,7 @@ static const struct spi_device_id ifx_id_table[] = { | |||
1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); | 1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); |
1332 | 1332 | ||
1333 | /* spi operations */ | 1333 | /* spi operations */ |
1334 | static const struct spi_driver ifx_spi_driver = { | 1334 | static struct spi_driver ifx_spi_driver = { |
1335 | .driver = { | 1335 | .driver = { |
1336 | .name = DRVNAME, | 1336 | .name = DRVNAME, |
1337 | .pm = &ifx_spi_pm, | 1337 | .pm = &ifx_spi_pm, |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 4ef747307ecb..d5c689d6217e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -169,7 +169,6 @@ | |||
169 | #define SERIAL_IMX_MAJOR 207 | 169 | #define SERIAL_IMX_MAJOR 207 |
170 | #define MINOR_START 16 | 170 | #define MINOR_START 16 |
171 | #define DEV_NAME "ttymxc" | 171 | #define DEV_NAME "ttymxc" |
172 | #define MAX_INTERNAL_IRQ MXC_INTERNAL_IRQS | ||
173 | 172 | ||
174 | /* | 173 | /* |
175 | * This determines how often we check the modem status signals | 174 | * This determines how often we check the modem status signals |
@@ -741,10 +740,7 @@ static int imx_startup(struct uart_port *port) | |||
741 | 740 | ||
742 | /* do not use RTS IRQ on IrDA */ | 741 | /* do not use RTS IRQ on IrDA */ |
743 | if (!USE_IRDA(sport)) { | 742 | if (!USE_IRDA(sport)) { |
744 | retval = request_irq(sport->rtsirq, imx_rtsint, | 743 | retval = request_irq(sport->rtsirq, imx_rtsint, 0, |
745 | (sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 : | ||
746 | IRQF_TRIGGER_FALLING | | ||
747 | IRQF_TRIGGER_RISING, | ||
748 | DRIVER_NAME, sport); | 744 | DRIVER_NAME, sport); |
749 | if (retval) | 745 | if (retval) |
750 | goto error_out3; | 746 | goto error_out3; |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index ec56d8397aae..3a667eed63d6 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/pinctrl/consumer.h> | 35 | #include <linux/pinctrl/consumer.h> |
36 | #include <linux/of_device.h> | ||
36 | 37 | ||
37 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
38 | 39 | ||
@@ -72,6 +73,7 @@ | |||
72 | #define AUART_CTRL0_CLKGATE (1 << 30) | 73 | #define AUART_CTRL0_CLKGATE (1 << 30) |
73 | 74 | ||
74 | #define AUART_CTRL2_CTSEN (1 << 15) | 75 | #define AUART_CTRL2_CTSEN (1 << 15) |
76 | #define AUART_CTRL2_RTSEN (1 << 14) | ||
75 | #define AUART_CTRL2_RTS (1 << 11) | 77 | #define AUART_CTRL2_RTS (1 << 11) |
76 | #define AUART_CTRL2_RXE (1 << 9) | 78 | #define AUART_CTRL2_RXE (1 << 9) |
77 | #define AUART_CTRL2_TXE (1 << 8) | 79 | #define AUART_CTRL2_TXE (1 << 8) |
@@ -258,9 +260,12 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
258 | 260 | ||
259 | u32 ctrl = readl(u->membase + AUART_CTRL2); | 261 | u32 ctrl = readl(u->membase + AUART_CTRL2); |
260 | 262 | ||
261 | ctrl &= ~AUART_CTRL2_RTS; | 263 | ctrl &= ~AUART_CTRL2_RTSEN; |
262 | if (mctrl & TIOCM_RTS) | 264 | if (mctrl & TIOCM_RTS) { |
263 | ctrl |= AUART_CTRL2_RTS; | 265 | if (u->state->port.flags & ASYNC_CTS_FLOW) |
266 | ctrl |= AUART_CTRL2_RTSEN; | ||
267 | } | ||
268 | |||
264 | s->ctrl = mctrl; | 269 | s->ctrl = mctrl; |
265 | writel(ctrl, u->membase + AUART_CTRL2); | 270 | writel(ctrl, u->membase + AUART_CTRL2); |
266 | } | 271 | } |
@@ -358,9 +363,9 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
358 | 363 | ||
359 | /* figure out the hardware flow control settings */ | 364 | /* figure out the hardware flow control settings */ |
360 | if (cflag & CRTSCTS) | 365 | if (cflag & CRTSCTS) |
361 | ctrl2 |= AUART_CTRL2_CTSEN; | 366 | ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; |
362 | else | 367 | else |
363 | ctrl2 &= ~AUART_CTRL2_CTSEN; | 368 | ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); |
364 | 369 | ||
365 | /* set baud rate */ | 370 | /* set baud rate */ |
366 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); | 371 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); |
@@ -675,6 +680,30 @@ static struct uart_driver auart_driver = { | |||
675 | #endif | 680 | #endif |
676 | }; | 681 | }; |
677 | 682 | ||
683 | /* | ||
684 | * This function returns 1 if pdev isn't a device instatiated by dt, 0 if it | ||
685 | * could successfully get all information from dt or a negative errno. | ||
686 | */ | ||
687 | static int serial_mxs_probe_dt(struct mxs_auart_port *s, | ||
688 | struct platform_device *pdev) | ||
689 | { | ||
690 | struct device_node *np = pdev->dev.of_node; | ||
691 | int ret; | ||
692 | |||
693 | if (!np) | ||
694 | /* no device tree device */ | ||
695 | return 1; | ||
696 | |||
697 | ret = of_alias_get_id(np, "serial"); | ||
698 | if (ret < 0) { | ||
699 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | ||
700 | return ret; | ||
701 | } | ||
702 | s->port.line = ret; | ||
703 | |||
704 | return 0; | ||
705 | } | ||
706 | |||
678 | static int __devinit mxs_auart_probe(struct platform_device *pdev) | 707 | static int __devinit mxs_auart_probe(struct platform_device *pdev) |
679 | { | 708 | { |
680 | struct mxs_auart_port *s; | 709 | struct mxs_auart_port *s; |
@@ -689,6 +718,12 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) | |||
689 | goto out; | 718 | goto out; |
690 | } | 719 | } |
691 | 720 | ||
721 | ret = serial_mxs_probe_dt(s, pdev); | ||
722 | if (ret > 0) | ||
723 | s->port.line = pdev->id < 0 ? 0 : pdev->id; | ||
724 | else if (ret < 0) | ||
725 | goto out_free; | ||
726 | |||
692 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | 727 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
693 | if (IS_ERR(pinctrl)) { | 728 | if (IS_ERR(pinctrl)) { |
694 | ret = PTR_ERR(pinctrl); | 729 | ret = PTR_ERR(pinctrl); |
@@ -711,7 +746,6 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) | |||
711 | s->port.membase = ioremap(r->start, resource_size(r)); | 746 | s->port.membase = ioremap(r->start, resource_size(r)); |
712 | s->port.ops = &mxs_auart_ops; | 747 | s->port.ops = &mxs_auart_ops; |
713 | s->port.iotype = UPIO_MEM; | 748 | s->port.iotype = UPIO_MEM; |
714 | s->port.line = pdev->id < 0 ? 0 : pdev->id; | ||
715 | s->port.fifosize = 16; | 749 | s->port.fifosize = 16; |
716 | s->port.uartclk = clk_get_rate(s->clk); | 750 | s->port.uartclk = clk_get_rate(s->clk); |
717 | s->port.type = PORT_IMX; | 751 | s->port.type = PORT_IMX; |
@@ -728,7 +762,7 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) | |||
728 | 762 | ||
729 | platform_set_drvdata(pdev, s); | 763 | platform_set_drvdata(pdev, s); |
730 | 764 | ||
731 | auart_port[pdev->id] = s; | 765 | auart_port[s->port.line] = s; |
732 | 766 | ||
733 | mxs_auart_reset(&s->port); | 767 | mxs_auart_reset(&s->port); |
734 | 768 | ||
@@ -769,12 +803,19 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev) | |||
769 | return 0; | 803 | return 0; |
770 | } | 804 | } |
771 | 805 | ||
806 | static struct of_device_id mxs_auart_dt_ids[] = { | ||
807 | { .compatible = "fsl,imx23-auart", }, | ||
808 | { /* sentinel */ } | ||
809 | }; | ||
810 | MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); | ||
811 | |||
772 | static struct platform_driver mxs_auart_driver = { | 812 | static struct platform_driver mxs_auart_driver = { |
773 | .probe = mxs_auart_probe, | 813 | .probe = mxs_auart_probe, |
774 | .remove = __devexit_p(mxs_auart_remove), | 814 | .remove = __devexit_p(mxs_auart_remove), |
775 | .driver = { | 815 | .driver = { |
776 | .name = "mxs-auart", | 816 | .name = "mxs-auart", |
777 | .owner = THIS_MODULE, | 817 | .owner = THIS_MODULE, |
818 | .of_match_table = mxs_auart_dt_ids, | ||
778 | }, | 819 | }, |
779 | }; | 820 | }; |
780 | 821 | ||
@@ -807,3 +848,4 @@ module_init(mxs_auart_init); | |||
807 | module_exit(mxs_auart_exit); | 848 | module_exit(mxs_auart_exit); |
808 | MODULE_LICENSE("GPL"); | 849 | MODULE_LICENSE("GPL"); |
809 | MODULE_DESCRIPTION("Freescale MXS application uart driver"); | 850 | MODULE_DESCRIPTION("Freescale MXS application uart driver"); |
851 | MODULE_ALIAS("platform:mxs-auart"); | ||
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 5410c0637266..34e71874a892 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -208,6 +208,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { | |||
208 | { .compatible = "ns16750", .data = (void *)PORT_16750, }, | 208 | { .compatible = "ns16750", .data = (void *)PORT_16750, }, |
209 | { .compatible = "ns16850", .data = (void *)PORT_16850, }, | 209 | { .compatible = "ns16850", .data = (void *)PORT_16850, }, |
210 | { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, | 210 | { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, |
211 | { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, | ||
211 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 212 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
212 | { .compatible = "ibm,qpace-nwp-serial", | 213 | { .compatible = "ibm,qpace-nwp-serial", |
213 | .data = (void *)PORT_NWPSERIAL, }, | 214 | .data = (void *)PORT_NWPSERIAL, }, |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 4fdec6a6b758..558ce8509a9a 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -253,6 +253,9 @@ struct eg20t_port { | |||
253 | dma_addr_t rx_buf_dma; | 253 | dma_addr_t rx_buf_dma; |
254 | 254 | ||
255 | struct dentry *debugfs; | 255 | struct dentry *debugfs; |
256 | |||
257 | /* protect the eg20t_port private structure and io access to membase */ | ||
258 | spinlock_t lock; | ||
256 | }; | 259 | }; |
257 | 260 | ||
258 | /** | 261 | /** |
@@ -754,7 +757,8 @@ static void pch_dma_rx_complete(void *arg) | |||
754 | tty_flip_buffer_push(tty); | 757 | tty_flip_buffer_push(tty); |
755 | tty_kref_put(tty); | 758 | tty_kref_put(tty); |
756 | async_tx_ack(priv->desc_rx); | 759 | async_tx_ack(priv->desc_rx); |
757 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); | 760 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | |
761 | PCH_UART_HAL_RX_ERR_INT); | ||
758 | } | 762 | } |
759 | 763 | ||
760 | static void pch_dma_tx_complete(void *arg) | 764 | static void pch_dma_tx_complete(void *arg) |
@@ -809,7 +813,8 @@ static int handle_rx_to(struct eg20t_port *priv) | |||
809 | int rx_size; | 813 | int rx_size; |
810 | int ret; | 814 | int ret; |
811 | if (!priv->start_rx) { | 815 | if (!priv->start_rx) { |
812 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); | 816 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | |
817 | PCH_UART_HAL_RX_ERR_INT); | ||
813 | return 0; | 818 | return 0; |
814 | } | 819 | } |
815 | buf = &priv->rxbuf; | 820 | buf = &priv->rxbuf; |
@@ -1058,7 +1063,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | |||
1058 | int next = 1; | 1063 | int next = 1; |
1059 | u8 msr; | 1064 | u8 msr; |
1060 | 1065 | ||
1061 | spin_lock_irqsave(&priv->port.lock, flags); | 1066 | spin_lock_irqsave(&priv->lock, flags); |
1062 | handled = 0; | 1067 | handled = 0; |
1063 | while (next) { | 1068 | while (next) { |
1064 | iid = pch_uart_hal_get_iid(priv); | 1069 | iid = pch_uart_hal_get_iid(priv); |
@@ -1078,11 +1083,13 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | |||
1078 | case PCH_UART_IID_RDR: /* Received Data Ready */ | 1083 | case PCH_UART_IID_RDR: /* Received Data Ready */ |
1079 | if (priv->use_dma) { | 1084 | if (priv->use_dma) { |
1080 | pch_uart_hal_disable_interrupt(priv, | 1085 | pch_uart_hal_disable_interrupt(priv, |
1081 | PCH_UART_HAL_RX_INT); | 1086 | PCH_UART_HAL_RX_INT | |
1087 | PCH_UART_HAL_RX_ERR_INT); | ||
1082 | ret = dma_handle_rx(priv); | 1088 | ret = dma_handle_rx(priv); |
1083 | if (!ret) | 1089 | if (!ret) |
1084 | pch_uart_hal_enable_interrupt(priv, | 1090 | pch_uart_hal_enable_interrupt(priv, |
1085 | PCH_UART_HAL_RX_INT); | 1091 | PCH_UART_HAL_RX_INT | |
1092 | PCH_UART_HAL_RX_ERR_INT); | ||
1086 | } else { | 1093 | } else { |
1087 | ret = handle_rx(priv); | 1094 | ret = handle_rx(priv); |
1088 | } | 1095 | } |
@@ -1116,7 +1123,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | |||
1116 | handled |= (unsigned int)ret; | 1123 | handled |= (unsigned int)ret; |
1117 | } | 1124 | } |
1118 | 1125 | ||
1119 | spin_unlock_irqrestore(&priv->port.lock, flags); | 1126 | spin_unlock_irqrestore(&priv->lock, flags); |
1120 | return IRQ_RETVAL(handled); | 1127 | return IRQ_RETVAL(handled); |
1121 | } | 1128 | } |
1122 | 1129 | ||
@@ -1208,7 +1215,8 @@ static void pch_uart_stop_rx(struct uart_port *port) | |||
1208 | struct eg20t_port *priv; | 1215 | struct eg20t_port *priv; |
1209 | priv = container_of(port, struct eg20t_port, port); | 1216 | priv = container_of(port, struct eg20t_port, port); |
1210 | priv->start_rx = 0; | 1217 | priv->start_rx = 0; |
1211 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT); | 1218 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT | |
1219 | PCH_UART_HAL_RX_ERR_INT); | ||
1212 | } | 1220 | } |
1213 | 1221 | ||
1214 | /* Enable the modem status interrupts. */ | 1222 | /* Enable the modem status interrupts. */ |
@@ -1226,9 +1234,9 @@ static void pch_uart_break_ctl(struct uart_port *port, int ctl) | |||
1226 | unsigned long flags; | 1234 | unsigned long flags; |
1227 | 1235 | ||
1228 | priv = container_of(port, struct eg20t_port, port); | 1236 | priv = container_of(port, struct eg20t_port, port); |
1229 | spin_lock_irqsave(&port->lock, flags); | 1237 | spin_lock_irqsave(&priv->lock, flags); |
1230 | pch_uart_hal_set_break(priv, ctl); | 1238 | pch_uart_hal_set_break(priv, ctl); |
1231 | spin_unlock_irqrestore(&port->lock, flags); | 1239 | spin_unlock_irqrestore(&priv->lock, flags); |
1232 | } | 1240 | } |
1233 | 1241 | ||
1234 | /* Grab any interrupt resources and initialise any low level driver state. */ | 1242 | /* Grab any interrupt resources and initialise any low level driver state. */ |
@@ -1263,6 +1271,7 @@ static int pch_uart_startup(struct uart_port *port) | |||
1263 | break; | 1271 | break; |
1264 | case 16: | 1272 | case 16: |
1265 | fifo_size = PCH_UART_HAL_FIFO16; | 1273 | fifo_size = PCH_UART_HAL_FIFO16; |
1274 | break; | ||
1266 | case 1: | 1275 | case 1: |
1267 | default: | 1276 | default: |
1268 | fifo_size = PCH_UART_HAL_FIFO_DIS; | 1277 | fifo_size = PCH_UART_HAL_FIFO_DIS; |
@@ -1300,7 +1309,8 @@ static int pch_uart_startup(struct uart_port *port) | |||
1300 | pch_request_dma(port); | 1309 | pch_request_dma(port); |
1301 | 1310 | ||
1302 | priv->start_rx = 1; | 1311 | priv->start_rx = 1; |
1303 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT); | 1312 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | |
1313 | PCH_UART_HAL_RX_ERR_INT); | ||
1304 | uart_update_timeout(port, CS8, default_baud); | 1314 | uart_update_timeout(port, CS8, default_baud); |
1305 | 1315 | ||
1306 | return 0; | 1316 | return 0; |
@@ -1358,7 +1368,7 @@ static void pch_uart_set_termios(struct uart_port *port, | |||
1358 | stb = PCH_UART_HAL_STB1; | 1368 | stb = PCH_UART_HAL_STB1; |
1359 | 1369 | ||
1360 | if (termios->c_cflag & PARENB) { | 1370 | if (termios->c_cflag & PARENB) { |
1361 | if (!(termios->c_cflag & PARODD)) | 1371 | if (termios->c_cflag & PARODD) |
1362 | parity = PCH_UART_HAL_PARITY_ODD; | 1372 | parity = PCH_UART_HAL_PARITY_ODD; |
1363 | else | 1373 | else |
1364 | parity = PCH_UART_HAL_PARITY_EVEN; | 1374 | parity = PCH_UART_HAL_PARITY_EVEN; |
@@ -1376,7 +1386,8 @@ static void pch_uart_set_termios(struct uart_port *port, | |||
1376 | 1386 | ||
1377 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 1387 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
1378 | 1388 | ||
1379 | spin_lock_irqsave(&port->lock, flags); | 1389 | spin_lock_irqsave(&priv->lock, flags); |
1390 | spin_lock(&port->lock); | ||
1380 | 1391 | ||
1381 | uart_update_timeout(port, termios->c_cflag, baud); | 1392 | uart_update_timeout(port, termios->c_cflag, baud); |
1382 | rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb); | 1393 | rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb); |
@@ -1389,7 +1400,8 @@ static void pch_uart_set_termios(struct uart_port *port, | |||
1389 | tty_termios_encode_baud_rate(termios, baud, baud); | 1400 | tty_termios_encode_baud_rate(termios, baud, baud); |
1390 | 1401 | ||
1391 | out: | 1402 | out: |
1392 | spin_unlock_irqrestore(&port->lock, flags); | 1403 | spin_unlock(&port->lock); |
1404 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1393 | } | 1405 | } |
1394 | 1406 | ||
1395 | static const char *pch_uart_type(struct uart_port *port) | 1407 | static const char *pch_uart_type(struct uart_port *port) |
@@ -1538,8 +1550,9 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
1538 | { | 1550 | { |
1539 | struct eg20t_port *priv; | 1551 | struct eg20t_port *priv; |
1540 | unsigned long flags; | 1552 | unsigned long flags; |
1553 | int priv_locked = 1; | ||
1554 | int port_locked = 1; | ||
1541 | u8 ier; | 1555 | u8 ier; |
1542 | int locked = 1; | ||
1543 | 1556 | ||
1544 | priv = pch_uart_ports[co->index]; | 1557 | priv = pch_uart_ports[co->index]; |
1545 | 1558 | ||
@@ -1547,12 +1560,16 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
1547 | 1560 | ||
1548 | local_irq_save(flags); | 1561 | local_irq_save(flags); |
1549 | if (priv->port.sysrq) { | 1562 | if (priv->port.sysrq) { |
1550 | /* serial8250_handle_port() already took the lock */ | 1563 | spin_lock(&priv->lock); |
1551 | locked = 0; | 1564 | /* serial8250_handle_port() already took the port lock */ |
1565 | port_locked = 0; | ||
1552 | } else if (oops_in_progress) { | 1566 | } else if (oops_in_progress) { |
1553 | locked = spin_trylock(&priv->port.lock); | 1567 | priv_locked = spin_trylock(&priv->lock); |
1554 | } else | 1568 | port_locked = spin_trylock(&priv->port.lock); |
1569 | } else { | ||
1570 | spin_lock(&priv->lock); | ||
1555 | spin_lock(&priv->port.lock); | 1571 | spin_lock(&priv->port.lock); |
1572 | } | ||
1556 | 1573 | ||
1557 | /* | 1574 | /* |
1558 | * First save the IER then disable the interrupts | 1575 | * First save the IER then disable the interrupts |
@@ -1570,8 +1587,10 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
1570 | wait_for_xmitr(priv, BOTH_EMPTY); | 1587 | wait_for_xmitr(priv, BOTH_EMPTY); |
1571 | iowrite8(ier, priv->membase + UART_IER); | 1588 | iowrite8(ier, priv->membase + UART_IER); |
1572 | 1589 | ||
1573 | if (locked) | 1590 | if (port_locked) |
1574 | spin_unlock(&priv->port.lock); | 1591 | spin_unlock(&priv->port.lock); |
1592 | if (priv_locked) | ||
1593 | spin_unlock(&priv->lock); | ||
1575 | local_irq_restore(flags); | 1594 | local_irq_restore(flags); |
1576 | } | 1595 | } |
1577 | 1596 | ||
@@ -1669,6 +1688,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
1669 | pci_enable_msi(pdev); | 1688 | pci_enable_msi(pdev); |
1670 | pci_set_master(pdev); | 1689 | pci_set_master(pdev); |
1671 | 1690 | ||
1691 | spin_lock_init(&priv->lock); | ||
1692 | |||
1672 | iobase = pci_resource_start(pdev, 0); | 1693 | iobase = pci_resource_start(pdev, 0); |
1673 | mapbase = pci_resource_start(pdev, 1); | 1694 | mapbase = pci_resource_start(pdev, 1); |
1674 | priv->mapbase = mapbase; | 1695 | priv->mapbase = mapbase; |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 654755a990df..333c8d012b0e 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -1348,10 +1348,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1348 | static int pmz_poll_get_char(struct uart_port *port) | 1348 | static int pmz_poll_get_char(struct uart_port *port) |
1349 | { | 1349 | { |
1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | 1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; |
1351 | int tries = 2; | ||
1351 | 1352 | ||
1352 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) | 1353 | while (tries) { |
1353 | udelay(5); | 1354 | if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0) |
1354 | return read_zsdata(uap); | 1355 | return read_zsdata(uap); |
1356 | if (tries--) | ||
1357 | udelay(5); | ||
1358 | } | ||
1359 | |||
1360 | return NO_POLL_CHAR; | ||
1355 | } | 1361 | } |
1356 | 1362 | ||
1357 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) | 1363 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index d8b0aee35632..02d07bfcfa8a 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -1014,10 +1014,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, | |||
1014 | * a disturbance in the clock-rate over the change. | 1014 | * a disturbance in the clock-rate over the change. |
1015 | */ | 1015 | */ |
1016 | 1016 | ||
1017 | if (IS_ERR(port->clk)) | 1017 | if (IS_ERR(port->baudclk)) |
1018 | goto exit; | 1018 | goto exit; |
1019 | 1019 | ||
1020 | if (port->baudclk_rate == clk_get_rate(port->clk)) | 1020 | if (port->baudclk_rate == clk_get_rate(port->baudclk)) |
1021 | goto exit; | 1021 | goto exit; |
1022 | 1022 | ||
1023 | if (val == CPUFREQ_PRECHANGE) { | 1023 | if (val == CPUFREQ_PRECHANGE) { |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 246b823c1b27..a21dc8e3b7c0 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -2527,14 +2527,16 @@ void uart_insert_char(struct uart_port *port, unsigned int status, | |||
2527 | struct tty_struct *tty = port->state->port.tty; | 2527 | struct tty_struct *tty = port->state->port.tty; |
2528 | 2528 | ||
2529 | if ((status & port->ignore_status_mask & ~overrun) == 0) | 2529 | if ((status & port->ignore_status_mask & ~overrun) == 0) |
2530 | tty_insert_flip_char(tty, ch, flag); | 2530 | if (tty_insert_flip_char(tty, ch, flag) == 0) |
2531 | ++port->icount.buf_overrun; | ||
2531 | 2532 | ||
2532 | /* | 2533 | /* |
2533 | * Overrun is special. Since it's reported immediately, | 2534 | * Overrun is special. Since it's reported immediately, |
2534 | * it doesn't affect the current character. | 2535 | * it doesn't affect the current character. |
2535 | */ | 2536 | */ |
2536 | if (status & ~port->ignore_status_mask & overrun) | 2537 | if (status & ~port->ignore_status_mask & overrun) |
2537 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 2538 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN) == 0) |
2539 | ++port->icount.buf_overrun; | ||
2538 | } | 2540 | } |
2539 | EXPORT_SYMBOL_GPL(uart_insert_char); | 2541 | EXPORT_SYMBOL_GPL(uart_insert_char); |
2540 | 2542 | ||
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1bd9163bc118..9be296cf7295 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/sh_dma.h> | ||
28 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
@@ -1410,8 +1411,8 @@ static void work_fn_rx(struct work_struct *work) | |||
1410 | /* Handle incomplete DMA receive */ | 1411 | /* Handle incomplete DMA receive */ |
1411 | struct tty_struct *tty = port->state->port.tty; | 1412 | struct tty_struct *tty = port->state->port.tty; |
1412 | struct dma_chan *chan = s->chan_rx; | 1413 | struct dma_chan *chan = s->chan_rx; |
1413 | struct sh_desc *sh_desc = container_of(desc, struct sh_desc, | 1414 | struct shdma_desc *sh_desc = container_of(desc, |
1414 | async_tx); | 1415 | struct shdma_desc, async_tx); |
1415 | unsigned long flags; | 1416 | unsigned long flags; |
1416 | int count; | 1417 | int count; |
1417 | 1418 | ||
@@ -1615,9 +1616,9 @@ static bool filter(struct dma_chan *chan, void *slave) | |||
1615 | struct sh_dmae_slave *param = slave; | 1616 | struct sh_dmae_slave *param = slave; |
1616 | 1617 | ||
1617 | dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, | 1618 | dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, |
1618 | param->slave_id); | 1619 | param->shdma_slave.slave_id); |
1619 | 1620 | ||
1620 | chan->private = param; | 1621 | chan->private = ¶m->shdma_slave; |
1621 | return true; | 1622 | return true; |
1622 | } | 1623 | } |
1623 | 1624 | ||
@@ -1656,7 +1657,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1656 | param = &s->param_tx; | 1657 | param = &s->param_tx; |
1657 | 1658 | ||
1658 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ | 1659 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ |
1659 | param->slave_id = s->cfg->dma_slave_tx; | 1660 | param->shdma_slave.slave_id = s->cfg->dma_slave_tx; |
1660 | 1661 | ||
1661 | s->cookie_tx = -EINVAL; | 1662 | s->cookie_tx = -EINVAL; |
1662 | chan = dma_request_channel(mask, filter, param); | 1663 | chan = dma_request_channel(mask, filter, param); |
@@ -1684,7 +1685,7 @@ static void sci_request_dma(struct uart_port *port) | |||
1684 | param = &s->param_rx; | 1685 | param = &s->param_rx; |
1685 | 1686 | ||
1686 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ | 1687 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ |
1687 | param->slave_id = s->cfg->dma_slave_rx; | 1688 | param->shdma_slave.slave_id = s->cfg->dma_slave_rx; |
1688 | 1689 | ||
1689 | chan = dma_request_channel(mask, filter, param); | 1690 | chan = dma_request_channel(mask, filter, param); |
1690 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); | 1691 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 6cd414341d5e..6579ffdd8e9b 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -216,8 +216,7 @@ static int ulite_startup(struct uart_port *port) | |||
216 | { | 216 | { |
217 | int ret; | 217 | int ret; |
218 | 218 | ||
219 | ret = request_irq(port->irq, ulite_isr, | 219 | ret = request_irq(port->irq, ulite_isr, IRQF_SHARED, "uartlite", port); |
220 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port); | ||
221 | if (ret) | 220 | if (ret) |
222 | return ret; | 221 | return ret; |
223 | 222 | ||
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 9911eb6b34cd..6f99c9959f0c 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -659,7 +659,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
659 | goto enable; | 659 | goto enable; |
660 | } | 660 | } |
661 | 661 | ||
662 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 662 | if (test_bit(TTY_HUPPING, &tty->flags)) { |
663 | /* We were raced by the hangup method. It will have stomped | 663 | /* We were raced by the hangup method. It will have stomped |
664 | the ldisc data and closed the ldisc down */ | 664 | the ldisc data and closed the ldisc down */ |
665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 64618547be11..b841f56d2e66 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
@@ -110,16 +110,7 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new) | |||
110 | wake_up_interruptible(&vt_event_waitqueue); | 110 | wake_up_interruptible(&vt_event_waitqueue); |
111 | } | 111 | } |
112 | 112 | ||
113 | /** | 113 | static void __vt_event_queue(struct vt_event_wait *vw) |
114 | * vt_event_wait - wait for an event | ||
115 | * @vw: our event | ||
116 | * | ||
117 | * Waits for an event to occur which completes our vt_event_wait | ||
118 | * structure. On return the structure has wv->done set to 1 for success | ||
119 | * or 0 if some event such as a signal ended the wait. | ||
120 | */ | ||
121 | |||
122 | static void vt_event_wait(struct vt_event_wait *vw) | ||
123 | { | 114 | { |
124 | unsigned long flags; | 115 | unsigned long flags; |
125 | /* Prepare the event */ | 116 | /* Prepare the event */ |
@@ -129,8 +120,18 @@ static void vt_event_wait(struct vt_event_wait *vw) | |||
129 | spin_lock_irqsave(&vt_event_lock, flags); | 120 | spin_lock_irqsave(&vt_event_lock, flags); |
130 | list_add(&vw->list, &vt_events); | 121 | list_add(&vw->list, &vt_events); |
131 | spin_unlock_irqrestore(&vt_event_lock, flags); | 122 | spin_unlock_irqrestore(&vt_event_lock, flags); |
123 | } | ||
124 | |||
125 | static void __vt_event_wait(struct vt_event_wait *vw) | ||
126 | { | ||
132 | /* Wait for it to pass */ | 127 | /* Wait for it to pass */ |
133 | wait_event_interruptible(vt_event_waitqueue, vw->done); | 128 | wait_event_interruptible(vt_event_waitqueue, vw->done); |
129 | } | ||
130 | |||
131 | static void __vt_event_dequeue(struct vt_event_wait *vw) | ||
132 | { | ||
133 | unsigned long flags; | ||
134 | |||
134 | /* Dequeue it */ | 135 | /* Dequeue it */ |
135 | spin_lock_irqsave(&vt_event_lock, flags); | 136 | spin_lock_irqsave(&vt_event_lock, flags); |
136 | list_del(&vw->list); | 137 | list_del(&vw->list); |
@@ -138,6 +139,22 @@ static void vt_event_wait(struct vt_event_wait *vw) | |||
138 | } | 139 | } |
139 | 140 | ||
140 | /** | 141 | /** |
142 | * vt_event_wait - wait for an event | ||
143 | * @vw: our event | ||
144 | * | ||
145 | * Waits for an event to occur which completes our vt_event_wait | ||
146 | * structure. On return the structure has wv->done set to 1 for success | ||
147 | * or 0 if some event such as a signal ended the wait. | ||
148 | */ | ||
149 | |||
150 | static void vt_event_wait(struct vt_event_wait *vw) | ||
151 | { | ||
152 | __vt_event_queue(vw); | ||
153 | __vt_event_wait(vw); | ||
154 | __vt_event_dequeue(vw); | ||
155 | } | ||
156 | |||
157 | /** | ||
141 | * vt_event_wait_ioctl - event ioctl handler | 158 | * vt_event_wait_ioctl - event ioctl handler |
142 | * @arg: argument to ioctl | 159 | * @arg: argument to ioctl |
143 | * | 160 | * |
@@ -177,10 +194,14 @@ int vt_waitactive(int n) | |||
177 | { | 194 | { |
178 | struct vt_event_wait vw; | 195 | struct vt_event_wait vw; |
179 | do { | 196 | do { |
180 | if (n == fg_console + 1) | ||
181 | break; | ||
182 | vw.event.event = VT_EVENT_SWITCH; | 197 | vw.event.event = VT_EVENT_SWITCH; |
183 | vt_event_wait(&vw); | 198 | __vt_event_queue(&vw); |
199 | if (n == fg_console + 1) { | ||
200 | __vt_event_dequeue(&vw); | ||
201 | break; | ||
202 | } | ||
203 | __vt_event_wait(&vw); | ||
204 | __vt_event_dequeue(&vw); | ||
184 | if (vw.done == 0) | 205 | if (vw.done == 0) |
185 | return -EINTR; | 206 | return -EINTR; |
186 | } while (vw.event.newev != n); | 207 | } while (vw.event.newev != n); |