diff options
Diffstat (limited to 'drivers/tty')
| -rw-r--r-- | drivers/tty/serial/8250/8250_core.c (renamed from drivers/tty/serial/8250/8250.c) | 54 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 34 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_pnp.c | 12 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/Makefile | 8 | ||||
| -rw-r--r-- | drivers/tty/serial/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/tty/serial/atmel_serial.c | 11 | ||||
| -rw-r--r-- | drivers/tty/serial/bcm63xx_uart.c | 8 | ||||
| -rw-r--r-- | drivers/tty/serial/mpc52xx_uart.c | 2 | ||||
| -rw-r--r-- | drivers/tty/serial/of_serial.c | 6 | ||||
| -rw-r--r-- | drivers/tty/serial/sunsu.c | 21 | ||||
| -rw-r--r-- | drivers/tty/serial/vt8500_serial.c | 9 | ||||
| -rw-r--r-- | drivers/tty/serial/xilinx_uartps.c | 2 | ||||
| -rw-r--r-- | drivers/tty/tty_buffer.c | 2 | ||||
| -rw-r--r-- | drivers/tty/vt/vc_screen.c | 6 | 
15 files changed, 140 insertions, 56 deletions
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250_core.c index 0efc815a496..35f9c96aada 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -301,7 +301,28 @@ static const struct serial8250_config uart_config[] = {  	},  	[PORT_8250_CIR] = {  		.name		= "CIR port" -	} +	}, +	[PORT_ALTR_16550_F32] = { +		.name		= "Altera 16550 FIFO32", +		.fifo_size	= 32, +		.tx_loadsz	= 32, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +	[PORT_ALTR_16550_F64] = { +		.name		= "Altera 16550 FIFO64", +		.fifo_size	= 64, +		.tx_loadsz	= 64, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	}, +	[PORT_ALTR_16550_F128] = { +		.name		= "Altera 16550 FIFO128", +		.fifo_size	= 128, +		.tx_loadsz	= 128, +		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, +		.flags		= UART_CAP_FIFO | UART_CAP_AFE, +	},  };  /* Uart divisor latch read */ @@ -3396,3 +3417,34 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);  MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");  #endif  MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); + +#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS +#ifndef MODULE +/* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name + * working as well for the module options so we don't break people.  We + * need to keep the names identical and the convenient macros will happily + * refuse to let us do that by failing the build with redefinition errors + * of global variables.  So we stick them inside a dummy function to avoid + * those conflicts.  The options still get parsed, and the redefined + * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive. + * + * This is hacky.  I'm sorry. + */ +static void __used s8250_options(void) +{ +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "8250_core." + +	module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644); +	module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644); +	module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644); +#ifdef CONFIG_SERIAL_8250_RSA +	__module_param_call(MODULE_PARAM_PREFIX, probe_rsa, +		¶m_array_ops, .arr = &__param_arr_probe_rsa, +		0444, -1); +#endif +} +#else +MODULE_ALIAS("8250_core"); +#endif +#endif diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 791c5a77ec6..26e3a97ab15 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1554,6 +1554,7 @@ pci_wch_ch353_setup(struct serial_private *priv,  #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA	0xc001  #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d  #define PCI_VENDOR_ID_WCH		0x4348 +#define PCI_DEVICE_ID_WCH_CH352_2S	0x3253  #define PCI_DEVICE_ID_WCH_CH353_4S	0x3453  #define PCI_DEVICE_ID_WCH_CH353_2S1PF	0x5046  #define PCI_DEVICE_ID_WCH_CH353_2S1P	0x7053 @@ -1571,6 +1572,7 @@ pci_wch_ch353_setup(struct serial_private *priv,  /* Unknown vendors/cards - this should not be in linux/pci_ids.h */  #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584	0x1584 +#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588	0x1588  /*   * Master list of serial port init/setup/exit quirks. @@ -1852,15 +1854,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {  	},  	{  		.vendor		= PCI_VENDOR_ID_PLX, -		.device		= PCI_DEVICE_ID_PLX_9050, -		.subvendor	= PCI_VENDOR_ID_PLX, -		.subdevice	= PCI_SUBDEVICE_ID_UNKNOWN_0x1584, -		.init		= pci_plx9050_init, -		.setup		= pci_default_setup, -		.exit		= pci_plx9050_exit, -	}, -	{ -		.vendor		= PCI_VENDOR_ID_PLX,  		.device		= PCI_DEVICE_ID_PLX_ROMULUS,  		.subvendor	= PCI_VENDOR_ID_PLX,  		.subdevice	= PCI_DEVICE_ID_PLX_ROMULUS, @@ -2180,6 +2173,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {  		.subdevice      = PCI_ANY_ID,  		.setup          = pci_wch_ch353_setup,  	}, +	/* WCH CH352 2S card (16550 clone) */ +	{ +		.vendor		= PCI_VENDOR_ID_WCH, +		.device		= PCI_DEVICE_ID_WCH_CH352_2S, +		.subvendor	= PCI_ANY_ID, +		.subdevice	= PCI_ANY_ID, +		.setup		= pci_wch_ch353_setup, +	},  	/*  	 * ASIX devices with FIFO bug  	 */ @@ -3733,7 +3734,12 @@ static struct pci_device_id serial_pci_tbl[] = {  	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,  		PCI_VENDOR_ID_PLX,  		PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0, -		pbn_b0_4_115200 }, +		pbn_b2_4_115200 }, +	/* Unknown card - subdevice 0x1588 */ +	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, +		PCI_VENDOR_ID_PLX, +		PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0, +		pbn_b2_8_115200 },  	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,  		PCI_SUBVENDOR_ID_KEYSPAN,  		PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0, @@ -4791,6 +4797,10 @@ static struct pci_device_id serial_pci_tbl[] = {  		PCI_VENDOR_ID_IBM, 0x0299,  		0, 0, pbn_b0_bt_2_115200 }, +	{	PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, +		0x1000, 0x0012, +		0, 0, pbn_b0_bt_2_115200 }, +  	{	PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,  		0xA000, 0x1000,  		0, 0, pbn_b0_1_115200 }, @@ -4869,6 +4879,10 @@ static struct pci_device_id serial_pci_tbl[] = {  		PCI_ANY_ID, PCI_ANY_ID,  		0, 0, pbn_b0_bt_2_115200 }, +	{	PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S, +		PCI_ANY_ID, PCI_ANY_ID, +		0, 0, pbn_b0_bt_2_115200 }, +  	/*  	 * Commtech, Inc. Fastcom adapters  	 */ diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 35d9ab95c5c..b3455a970a1 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c @@ -429,6 +429,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)  {  	struct uart_8250_port uart;  	int ret, line, flags = dev_id->driver_data; +	struct resource *res = NULL;  	if (flags & UNKNOWN_DEV) {  		ret = serial_pnp_guess_board(dev); @@ -439,11 +440,12 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)  	memset(&uart, 0, sizeof(uart));  	if (pnp_irq_valid(dev, 0))  		uart.port.irq = pnp_irq(dev, 0); -	if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) { -		uart.port.iobase = pnp_port_start(dev, 2); -		uart.port.iotype = UPIO_PORT; -	} else if (pnp_port_valid(dev, 0)) { -		uart.port.iobase = pnp_port_start(dev, 0); +	if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) +		res = pnp_get_resource(dev, IORESOURCE_IO, 2); +	else if (pnp_port_valid(dev, 0)) +		res = pnp_get_resource(dev, IORESOURCE_IO, 0); +	if (pnp_resource_enabled(res)) { +		uart.port.iobase = res->start;  		uart.port.iotype = UPIO_PORT;  	} else if (pnp_mem_valid(dev, 0)) {  		uart.port.mapbase = pnp_mem_start(dev, 0); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 2ef9537bcb2..80fe91e64a5 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -33,6 +33,23 @@ config SERIAL_8250  	  Most people will say Y or M here, so that they can use serial mice,  	  modems and similar devices connecting to the standard serial ports. +config SERIAL_8250_DEPRECATED_OPTIONS +	bool "Support 8250_core.* kernel options (DEPRECATED)" +	depends on SERIAL_8250 +	default y +	---help--- +	  In 3.7 we renamed 8250 to 8250_core by mistake, so now we have to +	  accept kernel parameters in both forms like 8250_core.nr_uarts=4 and +	  8250.nr_uarts=4. We now renamed the module back to 8250, but if +	  anybody noticed in 3.7 and changed their userspace we still have to +	  keep the 8350_core.* options around until they revert the changes +	  they already did. + +	  If 8250 is built as a module, this adds 8250_core alias instead.  + +	  If you did not notice yet and/or you have userspace from pre-3.7, it +	  is safe (and recommended) to say N here. +  config SERIAL_8250_PNP  	bool "8250/16550 PNP device support" if EXPERT  	depends on SERIAL_8250 && PNP diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index a23838a4d53..36d68d05430 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -2,10 +2,10 @@  # Makefile for the 8250 serial device drivers.  # -obj-$(CONFIG_SERIAL_8250)		+= 8250_core.o -8250_core-y				:= 8250.o -8250_core-$(CONFIG_SERIAL_8250_PNP)	+= 8250_pnp.o -8250_core-$(CONFIG_SERIAL_8250_DMA)	+= 8250_dma.o +obj-$(CONFIG_SERIAL_8250)		+= 8250.o +8250-y					:= 8250_core.o +8250-$(CONFIG_SERIAL_8250_PNP)		+= 8250_pnp.o +8250-$(CONFIG_SERIAL_8250_DMA)		+= 8250_dma.o  obj-$(CONFIG_SERIAL_8250_GSC)		+= 8250_gsc.o  obj-$(CONFIG_SERIAL_8250_PCI)		+= 8250_pci.o  obj-$(CONFIG_SERIAL_8250_HP300)		+= 8250_hp300.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index cf9210db9fa..7e7006fd404 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -211,14 +211,14 @@ config SERIAL_SAMSUNG  config SERIAL_SAMSUNG_UARTS_4  	bool  	depends on PLAT_SAMSUNG -	default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) +	default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442)  	help  	  Internal node for the common case of 4 Samsung compatible UARTs  config SERIAL_SAMSUNG_UARTS  	int  	depends on PLAT_SAMSUNG -	default 6 if ARCH_S5P6450 +	default 6 if CPU_S5P6450  	default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416  	default 3  	help diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index d4a7c241b75..3467462869c 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -158,7 +158,7 @@ struct atmel_uart_port {  };  static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; -static unsigned long atmel_ports_in_use; +static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART);  #ifdef SUPPORT_SYSRQ  static struct console atmel_console; @@ -1769,15 +1769,14 @@ static int atmel_serial_probe(struct platform_device *pdev)  	if (ret < 0)  		/* port id not found in platform data nor device-tree aliases:  		 * auto-enumerate it */ -		ret = find_first_zero_bit(&atmel_ports_in_use, -				sizeof(atmel_ports_in_use)); +		ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART); -	if (ret > ATMEL_MAX_UART) { +	if (ret >= ATMEL_MAX_UART) {  		ret = -ENODEV;  		goto err;  	} -	if (test_and_set_bit(ret, &atmel_ports_in_use)) { +	if (test_and_set_bit(ret, atmel_ports_in_use)) {  		/* port already in use */  		ret = -EBUSY;  		goto err; @@ -1857,7 +1856,7 @@ static int atmel_serial_remove(struct platform_device *pdev)  	/* "port" is allocated statically, so we shouldn't free it */ -	clear_bit(port->line, &atmel_ports_in_use); +	clear_bit(port->line, atmel_ports_in_use);  	clk_put(atmel_port->clk); diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 719594e5fc2..52a3ecd4042 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -235,7 +235,7 @@ static const char *bcm_uart_type(struct uart_port *port)   */  static void bcm_uart_do_rx(struct uart_port *port)  { -	struct tty_port *port = &port->state->port; +	struct tty_port *tty_port = &port->state->port;  	unsigned int max_count;  	/* limit number of char read in interrupt, should not be @@ -260,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port)  			bcm_uart_writel(port, val, UART_CTL_REG);  			port->icount.overrun++; -			tty_insert_flip_char(port, 0, TTY_OVERRUN); +			tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);  		}  		if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) @@ -299,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port)  		if ((cstat & port->ignore_status_mask) == 0) -			tty_insert_flip_char(port, c, flag); +			tty_insert_flip_char(tty_port, c, flag);  	} while (--max_count); -	tty_flip_buffer_push(port); +	tty_flip_buffer_push(tty_port);  }  /* diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index c0e1fad51be..018bad92255 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -550,7 +550,7 @@ static int mpc512x_psc_clock(struct uart_port *port, int enable)  		return 0;  	psc_num = (port->mapbase & 0xf00) >> 8; -	snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num); +	snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);  	psc_clk = clk_get(port->dev, clk_name);  	if (IS_ERR(psc_clk)) {  		dev_err(port->dev, "Failed to get PSC clock entry!\n"); diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index d5874605682..b025d543827 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -241,6 +241,12 @@ static struct of_device_id of_platform_serial_table[] = {  	{ .compatible = "ns16850",  .data = (void *)PORT_16850, },  	{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },  	{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, +	{ .compatible = "altr,16550-FIFO32", +		.data = (void *)PORT_ALTR_16550_F32, }, +	{ .compatible = "altr,16550-FIFO64", +		.data = (void *)PORT_ALTR_16550_F64, }, +	{ .compatible = "altr,16550-FIFO128", +		.data = (void *)PORT_ALTR_16550_F128, },  #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL  	{ .compatible = "ibm,qpace-nwp-serial",  		.data = (void *)PORT_NWPSERIAL, }, diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index e343d667085..451687cb968 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -968,6 +968,7 @@ static struct uart_ops sunsu_pops = {  #define UART_NR	4  static struct uart_sunsu_port sunsu_ports[UART_NR]; +static int nr_inst; /* Number of already registered ports */  #ifdef CONFIG_SERIO @@ -1337,13 +1338,8 @@ static int __init sunsu_console_setup(struct console *co, char *options)  	printk("Console: ttyS%d (SU)\n",  	       (sunsu_reg.minor - 64) + co->index); -	/* -	 * Check whether an invalid uart number has been specified, and -	 * if so, search for the first available port that does have -	 * console support. -	 */ -	if (co->index >= UART_NR) -		co->index = 0; +	if (co->index > nr_inst) +		return -ENODEV;  	port = &sunsu_ports[co->index].port;  	/* @@ -1408,7 +1404,6 @@ static enum su_type su_get_type(struct device_node *dp)  static int su_probe(struct platform_device *op)  { -	static int inst;  	struct device_node *dp = op->dev.of_node;  	struct uart_sunsu_port *up;  	struct resource *rp; @@ -1418,16 +1413,16 @@ static int su_probe(struct platform_device *op)  	type = su_get_type(dp);  	if (type == SU_PORT_PORT) { -		if (inst >= UART_NR) +		if (nr_inst >= UART_NR)  			return -EINVAL; -		up = &sunsu_ports[inst]; +		up = &sunsu_ports[nr_inst];  	} else {  		up = kzalloc(sizeof(*up), GFP_KERNEL);  		if (!up)  			return -ENOMEM;  	} -	up->port.line = inst; +	up->port.line = nr_inst;  	spin_lock_init(&up->port.lock); @@ -1461,6 +1456,8 @@ static int su_probe(struct platform_device *op)  		}  		dev_set_drvdata(&op->dev, up); +		nr_inst++; +  		return 0;  	} @@ -1488,7 +1485,7 @@ static int su_probe(struct platform_device *op)  	dev_set_drvdata(&op->dev, up); -	inst++; +	nr_inst++;  	return 0; diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index a3f9dd5c9df..705240e6c4e 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -611,14 +611,7 @@ static int vt8500_serial_probe(struct platform_device *pdev)  	vt8500_port->uart.dev = &pdev->dev;  	vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; -	vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); -	if (!IS_ERR(vt8500_port->clk)) { -		vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); -	} else { -		/* use the default of 24Mhz if not specified and warn */ -		pr_warn("%s: serial clock source not specified\n", __func__); -		vt8500_port->uart.uartclk = 24000000; -	} +	vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);  	snprintf(vt8500_port->name, sizeof(vt8500_port->name),  		 "VT8500 UART%d", pdev->id); diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index ba451c7209f..f36bbba1ac8 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -578,6 +578,8 @@ static int xuartps_startup(struct uart_port *port)  	/* Receive Timeout register is enabled with value of 10 */  	xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); +	/* Clear out any pending interrupts before enabling them */ +	xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET);  	/* Set the Interrupt Registers with desired interrupts */  	xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY | diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index bb119934e76..578aa7594b1 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -425,7 +425,7 @@ static void flush_to_ldisc(struct work_struct *work)  	struct tty_ldisc *disc;  	tty = port->itty; -	if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n")) +	if (tty == NULL)  		return;  	disc = tty_ldisc_ref(tty); diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index e4ca345873c..d7799deacb2 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -93,7 +93,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll)  static struct vcs_poll_data *  vcs_poll_data_get(struct file *file)  { -	struct vcs_poll_data *poll = file->private_data; +	struct vcs_poll_data *poll = file->private_data, *kill = NULL;  	if (poll)  		return poll; @@ -122,10 +122,12 @@ vcs_poll_data_get(struct file *file)  		file->private_data = poll;  	} else {  		/* someone else raced ahead of us */ -		vcs_poll_data_free(poll); +		kill = poll;  		poll = file->private_data;  	}  	spin_unlock(&file->f_lock); +	if (kill) +		vcs_poll_data_free(kill);  	return poll;  }  |