Skip to contentSkip to conversation

TTY/serial driver patches for 3.2

PATCH In review Greg KH 6 participants 87 messages Oct 26, 2011

Subsystems (28)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 TTY/serial driver patches for 3.2

Here is the tty/serial driver patchset for the 3.2 tree.

Nothing major here, with a lot of good cleanup of the tty layer from Jiri Slaby, and some driver updates and additions.

Note, you will get a merge error in the following files when merging with your tree:

	drivers/tty/serial/8250_pci.c
	drivers/tty/serial/atmel_serial.c

The one in 8250_pci.c is trivial to fix, the atmel_serial one isn't as easy, but I'm sure you can figure it out :) If you want me to do the merge for it, I'll be glad to do so, just let me know.

Please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next

All of these patches have been in the -mm and -next trees for a while.

Patches will be sent to the linux-serial mailing list, if anyone wants to see them.

thanks,

greg k-h

------------

 Documentation/devicetree/bindings/serial/rs485.txt |   31 +
 .../devicetree/bindings/tty/serial/atmel-usart.txt |   27 +
 .../bindings/tty/serial/snps-dw-apb-uart.txt       |   25 +
 Documentation/serial/serial-rs485.txt              |    8 +
 arch/arm/Kconfig                                   |    1 -
 arch/arm/mach-s3c64xx/dev-uart.c                   |   60 +--
 arch/arm/mach-s3c64xx/include/mach/irqs.h          |   30 -
 arch/arm/mach-s3c64xx/irq.c                        |   25 -
 arch/arm/plat-s5p/Kconfig                          |    1 -
 arch/arm/plat-s5p/dev-uart.c                       |   84 +--
 arch/arm/plat-s5p/include/plat/irqs.h              |   35 -
 arch/arm/plat-s5p/irq.c                            |   34 -
 arch/arm/plat-samsung/Kconfig                      |    5 -
 arch/arm/plat-samsung/Makefile                     |    1 -
 arch/arm/plat-samsung/include/plat/regs-serial.h   |    5 +
 arch/arm/plat-samsung/irq-uart.c                   |   96 ---
 arch/h8300/Kconfig                                 |    2 +-
 arch/mips/pmc-sierra/msp71xx/msp_serial.c          |   73 ++-
 arch/powerpc/include/asm/udbg.h                    |    1 +
 arch/powerpc/kernel/udbg.c                         |    2 +
 arch/x86/platform/mrst/mrst.c                      |    3 +
 drivers/isdn/i4l/isdn_tty.c                        |    2 +-
 drivers/parport/parport_pc.c                       |    3 +
 drivers/staging/Kconfig                            |    2 +
 drivers/staging/Makefile                           |    1 +
 drivers/{tty => staging}/serial/68360serial.c      |    0
 drivers/staging/serial/Kconfig                     |   16 +
 drivers/staging/serial/Makefile                    |    1 +
 drivers/staging/serial/TODO                        |    6 +
 drivers/tty/Kconfig                                |   34 +
 drivers/tty/Makefile                               |    1 +
 drivers/tty/amiserial.c                            |   12 +-
 drivers/tty/cyclades.c                             |   14 +-
 drivers/tty/ehv_bytechan.c                         |  881 ++++++++++++++++++++
 drivers/tty/hvc/hvc_console.c                      |    9 +-
 drivers/tty/hvc/hvc_irq.c                          |    2 +-
 drivers/tty/hvc/hvcs.c                             |    4 +-
 drivers/tty/hvc/hvsi.c                             |    2 +-
 drivers/tty/isicom.c                               |    2 +-
 drivers/tty/mxser.c                                |   13 +-
 drivers/tty/n_gsm.c                                |   64 +-
 drivers/tty/pty.c                                  |   26 +-
 drivers/tty/serial/68328serial.c                   |   37 +-
 drivers/tty/serial/68328serial.h                   |    1 -
 drivers/tty/serial/8250.c                          |  132 ++--
 drivers/tty/serial/8250_dw.c                       |  194 +++++
 drivers/tty/serial/8250_pci.c                      |   42 +
 drivers/tty/serial/Kconfig                         |   30 +-
 drivers/tty/serial/Makefile                        |    4 +-
 drivers/tty/serial/altera_jtaguart.c               |    2 +-
 drivers/tty/serial/altera_uart.c                   |    2 +-
 drivers/tty/serial/apbuart.c                       |    1 +
 drivers/tty/serial/atmel_serial.c                  |  129 +++-
 drivers/tty/serial/bfin_sport_uart.c               |    2 +-
 drivers/tty/serial/{bfin_5xx.c => bfin_uart.c}     |   65 +-
 drivers/tty/serial/cpm_uart/cpm_uart_core.c        |    1 +
 drivers/tty/serial/crisv10.c                       |   30 +-
 drivers/tty/serial/dz.c                            |    1 +
 drivers/tty/serial/icom.c                          |    2 +-
 drivers/tty/serial/imx.c                           |   10 +-
 drivers/tty/serial/ioc3_serial.c                   |    1 +
 drivers/tty/serial/ioc4_serial.c                   |    1 +
 drivers/tty/serial/jsm/jsm.h                       |   10 -
 drivers/tty/serial/jsm/jsm_driver.c                |   19 -
 drivers/tty/serial/jsm/jsm_neo.c                   |   29 +-
 drivers/tty/serial/jsm/jsm_tty.c                   |   94 +--
 drivers/tty/serial/lantiq.c                        |    6 +-
 drivers/tty/serial/m32r_sio.c                      |    1 +
 drivers/tty/serial/max3100.c                       |    2 +
 drivers/tty/serial/max3107.c                       |    2 +
 drivers/tty/serial/mcf.c                           |    2 +-
 drivers/tty/serial/mfd.c                           |   49 ++-
 drivers/tty/serial/mpc52xx_uart.c                  |    3 +-
 drivers/tty/serial/mrst_max3110.c                  |  115 ++--
 drivers/tty/serial/mrst_max3110.h                  |    1 +
 drivers/tty/serial/msm_serial.c                    |    2 -
 drivers/tty/serial/msm_serial_hs.c                 |    2 +
 drivers/tty/serial/mux.c                           |    2 +
 drivers/tty/serial/nwpserial.c                     |    1 +
 drivers/tty/serial/pch_uart.c                      |    2 +
 drivers/tty/serial/pxa.c                           |   20 +
 drivers/tty/serial/samsung.c                       |  107 +++-
 drivers/tty/serial/samsung.h                       |    1 +
 drivers/tty/serial/sb1250-duart.c                  |    1 +
 drivers/tty/serial/serial_core.c                   |   72 +--
 drivers/tty/serial/serial_ks8695.c                 |    9 +-
 drivers/tty/serial/serial_txx9.c                   |    2 +
 drivers/tty/serial/sh-sci.c                        |    2 +-
 drivers/tty/serial/sn_console.c                    |    3 +-
 drivers/tty/serial/timbuart.c                      |    2 +
 drivers/tty/serial/uartlite.c                      |    1 +
 drivers/tty/serial/ucc_uart.c                      |    4 +-
 drivers/tty/serial/xilinx_uartps.c                 |    4 +-
 drivers/tty/serial/zs.c                            |    1 +
 drivers/tty/synclink.c                             |    1 -
 drivers/tty/synclinkmp.c                           |    6 +-
 drivers/tty/tty_io.c                               |   50 +-
 drivers/tty/tty_ioctl.c                            |   17 +
 drivers/tty/tty_ldisc.c                            |    1 -
 drivers/tty/tty_mutex.c                            |   12 -
 drivers/tty/tty_port.c                             |    2 +-
 drivers/tty/vt/keyboard.c                          |    3 +-
 drivers/tty/vt/selection.c                         |    4 +-
 drivers/tty/vt/vt.c                                |    2 +-
 include/linux/serial.h                             |    1 +
 include/linux/serial_8250.h                        |    2 +
 include/linux/serial_core.h                        |   10 +-
 include/linux/serial_reg.h                         |    1 +
 include/linux/tty.h                                |   26 +-
 net/irda/ircomm/ircomm_tty.c                       |    2 +-
 110 files changed, 2102 insertions(+), 940 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/serial/rs485.txt
 create mode 100644 Documentation/devicetree/bindings/tty/serial/atmel-usart.txt
 create mode 100644 Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt
 delete mode 100644 arch/arm/plat-samsung/irq-uart.c
 rename drivers/{tty => staging}/serial/68360serial.c (100%)
 create mode 100644 drivers/staging/serial/Kconfig
 create mode 100644 drivers/staging/serial/Makefile
 create mode 100644 drivers/staging/serial/TODO
 create mode 100644 drivers/tty/ehv_bytechan.c
 create mode 100644 drivers/tty/serial/8250_dw.c
 rename drivers/tty/serial/{bfin_5xx.c => bfin_uart.c} (97%)

---------------

Alan Cox (3):
n_gsm: update TODO list
n_gsm: Send CLD command on exit
max3110: Fix up port->tty backreferencing

Alexander Shishkin (1):
max3110: add sysrq support

Andi Kleen (1):
serial: mfd: Initconst section fixes

Bernhard Roth (1):
atmel_serial: RS485: receiving enabled when sending data

Dan Carpenter (1):
TTY: snyclinkmp: forever loop in tx_load_dma_buffer()

Dirk Brandewie (1):
max3110: wake up fixes

Doug Anderson (1):
TTY: serial_core: Fix crash if DCD drop during suspend

Edwin van Vliet (1):
drivers/tty/synclink: remove double comment

Feng Tang (1):
x86/mrst: Add platform data for Max3110 devices

Geert Uytterhoeven (1):
keyboard: Do not include <linux/irq.>

Greg Kroah-Hartman (3):
Revert "tty: of_serial: add support for the DesignWare 8250" Revert "tty: serial8250: add helpers for the DesignWare 8250" Revert "TTY: call tty_driver_lookup_tty unconditionally"

Hui Wang (1):
serial/imx: support to handle break character

Jamie Iles (9):
tty: serial: allow ports to override the irq handler
tty: serial8250: allow platforms to override irq handler
mips: msp71xx/serial: convert to pr_foo() helpers
mips: msp71xx/serial: add workaround for DW UART
tty: serial8250: remove UPIO_DWAPB{,32}
tty: serial8250: add helpers for the DesignWare 8250
tty: of_serial: add support for the DesignWare 8250
tty: 8250: export serial8250_handle_irq
tty: add a DesignWare 8250 driver

Jiri Kosina (1):
parport_pc: release IO region properly if unsupported ITE887x card is found

Jiri Slaby (18):
TTY: serial, remove BTM from wait_until_sent
TTY: msm_serial, remove unneeded console set
TTY: serial, remove tasklet for tty_wakeup
TTY: ami_serial, remove BTM from wait_until_sent
TTY: remove tty_locked
TTY: mxser+cyclades remove wait_until_sent debug code
TTY: serial, use ASYNCB_CLOSING in uart_close
TTY: serial, move locking in uart_close
TTY: define tty_wait_until_sent_from_close
TTY: use tty_wait_until_sent_from_close in tty_port_close_start
TTY: use tty_wait_until_sent_from_close in other drivers
TTY: serial, remove dead code from 68328
TTY: serial, fix includes in some drivers
TTY: serial, move 68360 driver to staging
TTY: drop driver reference in tty_open fail path
TTY: make tty_add_file non-failing
TTY: pty, release tty in all ptmx_open fail paths
TTY: call tty_driver_lookup_tty unconditionally

Konrad Rzeszutek Wilk (1):
8250: ratelimit LSR safety check engaged warning.

Kristen Carlson Accardi (1):
hsu: add runtime pm support

Kukjin Kim (1):
tty: Add support serial for EXYNOS4212 SoC

Marcus Folkesson (1):
serial: pxa: work around for errata #20

Mathias Krause (1):
tty: clearify structure initializer in notify_write()

Miche Baker-Harvey (1):
hvc_console: display printk messages on console.

Mikhail Kshevetskiy (2):
tty/n_gsm: fix a bug in gsm_dlci_data_output (adaption = 2 case) tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output

Nicolas Ferre (6):
tty/serial: RS485 bindings for device tree
tty/serial: atmel_serial: change platform_data variable name tty/serial: atmel_serial: whitespace and braces modifications tty/serial: atmel_serial: auto-enumerate ports tty/serial: atmel_serial: add device tree support tty/serial: atmel_serial: bootconsole removed from auto-enumerates

Nikola Diklic-Perin (1):
tty/n_gsm: fix bug in tiocmset

Ning Jiang (1):
serial-core: power up uart port early before we do set_termios when resuming

Nobuhiro Iwamatsu (1):
TTY: serial: Move mutex_unlock in uart_close function

Paul Bolle (1):
h8300: drivers/serial/Kconfig was moved

Sonic Zhang (3):
serial:blackfin: Correct coding style in bfin serial driver. serial:blackfin: rename Blackfin serial driver to bfin_uart.c serial:bfin_uart: Put TX IRQ in individual platform resource.

Søren Holm (1):
serial: Support the EFR-register of XR1715x uarts.

Thadeu Lima de Souza Cascardo (3):
jsm: remove remaining flip buffer code
jsm: remove buggy write queue
jsm: print byte we are dequeing

Thomas Abraham (2):
serial: samsung: Add unified interrupt handler for s3c64xx and later SoC's
ARM: SAMSUNG: Remove uart irq handling from plaform code

Thomas Meyer (1):
tty: Support compat_ioctl get/set termios_locked

Timur Tabi (3):
tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver tty/powerpc: fix build break with ehv_bytechan.c on allyesconfig drivers/tty: don't use the byte channel handle as a parameter in ehv_bytechan.c

Tomoya MORINAGA (1):
8250_pci: Fix kernel panic when pch_uart is disabled

WANG Cong (2):
cris: fix a build error in drivers/tty/serial/crisv10.c
cris: lower the printk level in cris serial driver

Yong Zhang (1):
TTY: irq: Remove IRQF_DISABLED

#1 lore raw

PATCH 1/79 tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver

From: Timur Tabi <[email protected]>

The ePAPR embedded hypervisor specification provides an API for "byte channels", which are serial-like virtual devices for sending and receiving streams of bytes. This driver provides Linux kernel support for byte channels via three distinct interfaces:

1) An early-console (udbg) driver. This provides early console output through a byte channel. The byte channel handle must be specified in a Kconfig option.

2) A normal console driver. Output is sent to the byte channel designated for stdout in the device tree. The console driver is for handling kernel printk calls.

3) A tty driver, which is used to handle user-space input and output. The byte channel used for the console is designated as the default tty.

---
 arch/powerpc/include/asm/udbg.h |    1 +
 arch/powerpc/kernel/udbg.c      |    2 +
 drivers/tty/Kconfig             |   34 ++
 drivers/tty/Makefile            |    1 +
 drivers/tty/ehv_bytechan.c      |  888 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 926 insertions(+), 0 deletions(-)
 create mode 100644 drivers/tty/ehv_bytechan.c
arch/powerpc/include/asm/udbg.h +1 -0
index 93e05d1..5354ae9 100644
@@ -54,6 +54,7 @@ extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
 extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_ehv_bc(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
arch/powerpc/kernel/udbg.c +2 -0
index faa82c1..b4607a9 100644
@@ -67,6 +67,8 @@ void __init udbg_early_init(void)
 	udbg_init_usbgecko();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
 	udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
+	udbg_init_ehv_bc();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
drivers/tty/Kconfig +34 -0
index bd7cc05..f1ea59b 100644
@@ -350,3 +350,37 @@ config TRACE_SINK
 
 	  If you select this option, you need to select
 	  "Trace data router for MIPI P1149.7 cJTAG standard".
+
+config PPC_EPAPR_HV_BYTECHAN
+	tristate "ePAPR hypervisor byte channel driver"
+	depends on PPC
+	help
+	  This driver creates /dev entries for each ePAPR hypervisor byte
+	  channel, thereby allowing applications to communicate with byte
+	  channels as if they were serial ports.
+
+config PPC_EARLY_DEBUG_EHV_BC
+	bool "Early console (udbg) support for ePAPR hypervisors"
+	depends on PPC_EPAPR_HV_BYTECHAN
+	help
+	  Select this option to enable early console (a.k.a. "udbg") support
+	  via an ePAPR byte channel.  You also need to choose the byte channel
+	  handle below.
+
+config PPC_EARLY_DEBUG_EHV_BC_HANDLE
+	int "Byte channel handle for early console (udbg)"
+	depends on PPC_EARLY_DEBUG_EHV_BC
+	default 0
+	help
+	  If you want early console (udbg) output through a byte channel,
+	  specify the handle of the byte channel to use.
+
+	  For this to work, the byte channel driver must be compiled
+	  in-kernel, not as a module.
+
+	  Note that only one early console driver can be enabled, so don't
+	  enable any others if you enable this one.
+
+	  If the number you specify is not a valid byte channel handle, then
+	  there simply will be no early console output.  This is true also
+	  if you don't boot under a hypervisor at all.
drivers/tty/Makefile +1 -0
index ea89b0b..2953059 100644
@@ -26,5 +26,6 @@ obj-$(CONFIG_ROCKETPORT)	+= rocket.o
 obj-$(CONFIG_SYNCLINK_GT)	+= synclink_gt.o
 obj-$(CONFIG_SYNCLINKMP)	+= synclinkmp.o
 obj-$(CONFIG_SYNCLINK)		+= synclink.o
+obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
 
 obj-y += ipwireless/
drivers/tty/ehv_bytechan.c new file +888 -0

888 lines not on this page · raw message

Signature · 1 line
1.7.7
#2 lore raw

PATCH 2/79 drivers/tty/synclink: remove double comment

From: Edwin van Vliet <[email protected]>

Redundant comment line was removed

---
 drivers/tty/synclink.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/tty/synclink.c +0 -1
index 272e417..e67fb20 100644
@@ -2124,7 +2124,6 @@ static int mgsl_write(struct tty_struct * tty,
 	if ( info->params.mode == MGSL_MODE_HDLC ||
 			info->params.mode == MGSL_MODE_RAW ) {
 		/* operating in synchronous (frame oriented) mode */
-		/* operating in synchronous (frame oriented) mode */
 		if (info->tx_active) {
 
 			if ( info->params.mode == MGSL_MODE_HDLC ) {
Signature · 1 line
1.7.7
#3 lore raw

PATCH 3/79 TTY: serial, remove BTM from wait_until_sent

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

During the BKL removal process, the BKL was switched to tty_lock (BTM). Now we should start pruning the BTM further. Let's start with wait_until_sent of the serial layer. This will allow us to switch to the tty port helpers and thus clean it up much.

In wait_until_sent there are some uport members accessed, but neither of them is protected by BTM at the location they are set ('=>' means function call):
* uport->fifosize (set in tty_ioctl => uart_ioctl => uart_set_info)
* uport->type (set in add_one_port prior to tty_register_device)
* uport->timeout (set usually in tty_ioctl => tty_mode_ioctl => tty_set_termios => uart_set_termios => uart_change_speed => uport->ops->set_termios => uart_update_timeout)
* call to uport->ops->tx_empty()

If the tx_empty hook needs some lock to protect accesses to registers, it should take &uport->lock spinlock like 8250 does. Otherwise there still might be races e.g. with ISRs.

This should also fix the issue Andreas is seeing (BTM in comparison to BKL doesn't have any hidden functionality like unlocking during sleeping).

References: https://lkml.org/lkml/2011/5/25/562

---
 drivers/tty/serial/serial_core.c |   30 +++++++-----------------------
 1 files changed, 7 insertions(+), 23 deletions(-)
drivers/tty/serial/serial_core.c +7 -23
index db7912c..2cbf1bd 100644
@@ -57,7 +57,7 @@ static struct lock_class_key port_lock_key;
 
 static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
 					struct ktermios *old_termios);
-static void __uart_wait_until_sent(struct uart_port *port, int timeout);
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
 static void uart_change_pm(struct uart_state *state, int pm_state);
 
 /*
@@ -1304,16 +1304,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	tty->closing = 1;
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
-		/*
-		 * hack: open-coded tty_wait_until_sent to avoid
-		 * recursive tty_lock
-		 */
-		long timeout = msecs_to_jiffies(port->closing_wait);
-		if (wait_event_interruptible_timeout(tty->write_wait,
-				!tty_chars_in_buffer(tty), timeout) >= 0)
-			__uart_wait_until_sent(uport, timeout);
-	}
+	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
 
 	/*
 	 * At this point, we stop accepting input.  To do this, we
@@ -1329,7 +1321,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 		 * has completely drained; this is especially
 		 * important if there is a transmit FIFO!
 		 */
-		__uart_wait_until_sent(uport, uport->timeout);
+		uart_wait_until_sent(tty, uport->timeout);
 	}
 
 	uart_shutdown(tty, state);
@@ -1363,8 +1355,10 @@ done:
 	mutex_unlock(&port->mutex);
 }
 
-static void __uart_wait_until_sent(struct uart_port *port, int timeout)
+static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
 {
+	struct uart_state *state = tty->driver_data;
+	struct uart_port *port = state->uart_port;
 	unsigned long char_time, expire;
 
 	if (port->type == PORT_UNKNOWN || port->fifosize == 0)
@@ -1416,16 +1410,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout)
 	}
 }
 
-static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->uart_port;
-
-	tty_lock();
-	__uart_wait_until_sent(port, timeout);
-	tty_unlock();
-}
-
 /*
  * This is called with the BKL held in
  *  linux/drivers/char/tty_io.c:do_tty_hangup()
Signature · 1 line
1.7.7
#4 lore raw

PATCH 4/79 TTY: msm_serial, remove unneeded console set

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

It doesn't make sense to set console to uart_port in console->setup. At that time the console is set by uart_add_one_port already.

The call chain looked like:
uart_add_one_port()
uport->cons = drv->cons; <= once
uart_configure_port()

    register_console()
     console->setup()
       port->cons = co;      <= second time
---
 drivers/tty/serial/msm_serial.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/tty/serial/msm_serial.c +0 -2
index e6ba838..29cbfd8 100644
@@ -804,8 +804,6 @@ static int __init msm_console_setup(struct console *co, char *options)
 	if (unlikely(!port->membase))
 		return -ENXIO;
 
-	port->cons = co;
-
 	msm_init_clock(port);
 
 	if (options)
Signature · 1 line
1.7.7
#5 lore raw

PATCH 5/79 TTY: serial, remove tasklet for tty_wakeup

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

tty_wakeup can be called from any context. So there is no need to have an extra tasklet for calling that. Hence save some space and remove the tasklet completely.

---
 drivers/tty/serial/serial_core.c |   20 +-------------------
 include/linux/serial_core.h      |    1 -
 2 files changed, 1 insertions(+), 20 deletions(-)
drivers/tty/serial/serial_core.c +1 -19
index 2cbf1bd..4786232 100644
@@ -72,7 +72,7 @@ void uart_write_wakeup(struct uart_port *port)
 	 * closed.  No cookie for you.
 	 */
 	BUG_ON(!state);
-	tasklet_schedule(&state->tlet);
+	tty_wakeup(state->port.tty);
 }
 
 static void uart_stop(struct tty_struct *tty)
@@ -107,12 +107,6 @@ static void uart_start(struct tty_struct *tty)
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static void uart_tasklet_action(unsigned long data)
-{
-	struct uart_state *state = (struct uart_state *)data;
-	tty_wakeup(state->port.tty);
-}
-
 static inline void
 uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
 {
@@ -250,11 +244,6 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
 	}
 
 	/*
-	 * kill off our tasklet
-	 */
-	tasklet_kill(&state->tlet);
-
-	/*
 	 * Free the transmit buffer page.
 	 */
 	if (state->xmit.buf) {
@@ -2277,8 +2266,6 @@ int uart_register_driver(struct uart_driver *drv)
 		port->ops = &uart_port_ops;
 		port->close_delay     = 500;	/* .5 seconds */
 		port->closing_wait    = 30000;	/* 30 seconds */
-		tasklet_init(&state->tlet, uart_tasklet_action,
-			     (unsigned long)state);
 	}
 
 	retval = tty_register_driver(normal);
@@ -2439,11 +2426,6 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 	 */
 	uport->type = PORT_UNKNOWN;
 
-	/*
-	 * Kill the tasklet, and free resources.
-	 */
-	tasklet_kill(&state->tlet);
-
 	state->uart_port = NULL;
 	mutex_unlock(&port_mutex);
 
include/linux/serial_core.h +0 -1
index a5c3114..76e1103 100644
@@ -384,7 +384,6 @@ struct uart_state {
 	int			pm_state;
 	struct circ_buf		xmit;
 
-	struct tasklet_struct	tlet;
 	struct uart_port	*uart_port;
 };
 
Signature · 1 line
1.7.7
#6 lore raw

PATCH 6/79 TTY: ami_serial, remove BTM from wait_until_sent

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

The same as in "TTY: serial, remove BTM from wait_until_sent" we don't need to take BTM in wait_until_sent of ami_serial. Exactly the same as serial, ami_serial accesses some "info" members (xmit_fifo_size, timeout), but their assignment on other places in the code is not protected by BTM anyway.

So the BTM protects nothing here. This removal helps us to get rid of tty_locked() and __big_tty_mutex_owner in the following patch. This was suggested by Arnd.

---
 drivers/tty/amiserial.c |   10 +---------
 1 files changed, 1 insertions(+), 9 deletions(-)
drivers/tty/amiserial.c +1 -9
index 2205795..6d43f55 100644
@@ -1529,7 +1529,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 {
 	struct async_struct * info = tty->driver_data;
 	unsigned long orig_jiffies, char_time;
-	int tty_was_locked = tty_locked();
 	int lsr;
 
 	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
@@ -1541,12 +1540,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 	orig_jiffies = jiffies;
 
 	/*
-	 * tty_wait_until_sent is called from lots of places,
-	 * with or without the BTM.
-	 */
-	if (!tty_was_locked)
-		tty_lock();
-	/*
 	 * Set the check interval to be 1/5 of the estimated time to
 	 * send a single character, and make it at least 1.  The check
 	 * interval should also be less than the timeout.
@@ -1586,8 +1579,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
 			break;
 	}
 	__set_current_state(TASK_RUNNING);
-	if (!tty_was_locked)
-		tty_unlock();
+
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
 #endif
Signature · 1 line
1.7.7
#7 lore raw

PATCH 7/79 TTY: remove tty_locked

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

We used it really only serial and ami_serial. The rest of the callsites were BUG/WARN_ONs to check if BTM is held. Now that we pruned tty_locked from both of the real users, we can get rid of tty_lock along with __big_tty_mutex_owner.

---
 drivers/tty/serial/serial_core.c |    4 ----
 drivers/tty/tty_ldisc.c          |    1 -
 drivers/tty/tty_mutex.c          |   12 ------------
 drivers/tty/vt/selection.c       |    4 ++--
 include/linux/tty.h              |    2 --
 5 files changed, 2 insertions(+), 21 deletions(-)
drivers/tty/serial/serial_core.c +0 -4
index 4786232..44c2963 100644
@@ -1245,8 +1245,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	struct uart_port *uport;
 	unsigned long flags;
 
-	BUG_ON(!tty_locked());
-
 	if (!state)
 		return;
 
@@ -1411,7 +1409,6 @@ static void uart_hangup(struct tty_struct *tty)
 	struct tty_port *port = &state->port;
 	unsigned long flags;
 
-	BUG_ON(!tty_locked());
 	pr_debug("uart_hangup(%d)\n", state->uart_port->line);
 
 	mutex_lock(&port->mutex);
@@ -1498,7 +1495,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
 	struct tty_port *port;
 	int retval, line = tty->index;
 
-	BUG_ON(!tty_locked());
 	pr_debug("uart_open(%d) called\n", line);
 
 	/*
drivers/tty/tty_ldisc.c +0 -1
index ef925d5..512c49f 100644
@@ -450,7 +450,6 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
 	if (ld->ops->open) {
 		int ret;
                 /* BTM here locks versus a hangup event */
-		WARN_ON(!tty_locked());
 		ret = ld->ops->open(tty);
 		if (ret)
 			clear_bit(TTY_LDISC_OPEN, &tty->flags);
drivers/tty/tty_mutex.c +0 -12
index 3b2bb77..9ff986c 100644
@@ -15,30 +15,18 @@
  * Don't use in new code.
  */
 static DEFINE_MUTEX(big_tty_mutex);
-struct task_struct *__big_tty_mutex_owner;
-EXPORT_SYMBOL_GPL(__big_tty_mutex_owner);
 
 /*
  * Getting the big tty mutex.
  */
 void __lockfunc tty_lock(void)
 {
-	struct task_struct *task = current;
-
-	WARN_ON(__big_tty_mutex_owner == task);
-
 	mutex_lock(&big_tty_mutex);
-	__big_tty_mutex_owner = task;
 }
 EXPORT_SYMBOL(tty_lock);
 
 void __lockfunc tty_unlock(void)
 {
-	struct task_struct *task = current;
-
-	WARN_ON(__big_tty_mutex_owner != task);
-	__big_tty_mutex_owner = NULL;
-
 	mutex_unlock(&big_tty_mutex);
 }
 EXPORT_SYMBOL(tty_unlock);
drivers/tty/vt/selection.c +2 -2
index fb864e7..7a0a12a 100644
@@ -301,6 +301,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
 /* Insert the contents of the selection buffer into the
  * queue of the tty associated with the current console.
  * Invoked by ioctl().
+ *
+ * Locking: always called with BTM from vt_ioctl
  */
 int paste_selection(struct tty_struct *tty)
 {
@@ -310,8 +312,6 @@ int paste_selection(struct tty_struct *tty)
 	struct  tty_ldisc *ld;
 	DECLARE_WAITQUEUE(wait, current);
 
-	/* always called with BTM from vt_ioctl */
-	WARN_ON(!tty_locked());
 
 	console_lock();
 	poke_blanked_console();
include/linux/tty.h +0 -2
index 44bc0c5..6d5eceb 100644
@@ -600,8 +600,6 @@ extern long vt_compat_ioctl(struct tty_struct *tty,
 /* functions for preparation of BKL removal */
 extern void __lockfunc tty_lock(void) __acquires(tty_lock);
 extern void __lockfunc tty_unlock(void) __releases(tty_lock);
-extern struct task_struct *__big_tty_mutex_owner;
-#define tty_locked()		(current == __big_tty_mutex_owner)
 
 /*
  * wait_event_interruptible_tty -- wait for a condition with the tty lock held
Signature · 1 line
1.7.7
#8 lore raw

PATCH 8/79 TTY: mxser+cyclades remove wait_until_sent debug code

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

It makes the code really ugly. And since it can be enabled only before building and only in the source files, it can be barely used by users. That said, I've not seen anybody to use it in the past few years.

This crap is copied to some more drivers over the tty tree. Since I'm not their maintainer, I'm not sure if I should remove them too?

---
 drivers/tty/cyclades.c |   12 +-----------
 drivers/tty/mxser.c    |   13 +------------
 2 files changed, 2 insertions(+), 23 deletions(-)
drivers/tty/cyclades.c +1 -11
index c0e8f2e..5beef49 100644
@@ -45,7 +45,6 @@
 #undef	CY_DEBUG_IO
 #undef	CY_DEBUG_COUNT
 #undef	CY_DEBUG_DTR
-#undef	CY_DEBUG_WAIT_UNTIL_SENT
 #undef	CY_DEBUG_INTERRUPTS
 #undef	CY_16Y_HACK
 #undef	CY_ENABLE_MONITORING
@@ -1678,16 +1677,10 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
 	 */
 	if (!timeout || timeout > 2 * info->timeout)
 		timeout = 2 * info->timeout;
-#ifdef CY_DEBUG_WAIT_UNTIL_SENT
-	printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...",
-		timeout, char_time, jiffies);
-#endif
+
 	card = info->card;
 	if (!cy_is_Z(card)) {
 		while (cyy_readb(info, CySRER) & CyTxRdy) {
-#ifdef CY_DEBUG_WAIT_UNTIL_SENT
-			printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
-#endif
 			if (msleep_interruptible(jiffies_to_msecs(char_time)))
 				break;
 			if (timeout && time_after(jiffies, orig_jiffies +
@@ -1697,9 +1690,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
 	}
 	/* Run one more char cycle */
 	msleep_interruptible(jiffies_to_msecs(char_time * 5));
-#ifdef CY_DEBUG_WAIT_UNTIL_SENT
-	printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
-#endif
 }
 
 static void cy_flush_buffer(struct tty_struct *tty)
drivers/tty/mxser.c +1 -12
index 7fc8c02..8998d52 100644
@@ -2005,16 +2005,9 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
 	 */
 	if (!timeout || timeout > 2 * info->timeout)
 		timeout = 2 * info->timeout;
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...",
-		timeout, char_time);
-	printk("jiff=%lu...", jiffies);
-#endif
+
 	spin_lock_irqsave(&info->slock, flags);
 	while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) {
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
-#endif
 		spin_unlock_irqrestore(&info->slock, flags);
 		schedule_timeout_interruptible(char_time);
 		spin_lock_irqsave(&info->slock, flags);
@@ -2025,10 +2018,6 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
 	}
 	spin_unlock_irqrestore(&info->slock, flags);
 	set_current_state(TASK_RUNNING);
-
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
-#endif
 }
 
 /*
Signature · 1 line
1.7.7
#9 lore raw

PATCH 9/79 serial:blackfin: Correct coding style in bfin serial driver.

In reply to Greg Kroah-Hartman

From: Sonic Zhang <[email protected]>

---
 drivers/tty/serial/bfin_5xx.c |   25 ++++++++++++++++---------
 1 files changed, 16 insertions(+), 9 deletions(-)
drivers/tty/serial/bfin_5xx.c +16 -9
index ff69791..e08bc04 100644
@@ -234,8 +234,8 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 	status = UART_GET_LSR(uart);
 	UART_CLEAR_LSR(uart);
 
- 	ch = UART_GET_CHAR(uart);
- 	uart->port.icount.rx++;
+	ch = UART_GET_CHAR(uart);
+	uart->port.icount.rx++;
 
 #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
 	defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
@@ -739,9 +739,8 @@ static int bfin_serial_startup(struct uart_port *port)
 			pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n");
 		}
 	}
-	if (uart->rts_pin >= 0) {
+	if (uart->rts_pin >= 0)
 		gpio_direction_output(uart->rts_pin, 0);
-	}
 #endif
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
 	if (uart->cts_pin >= 0 && request_irq(uart->status_irq,
@@ -1091,10 +1090,18 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
 				*parity = 'o';
 		}
 		switch (lcr & 0x03) {
-			case 0:	*bits = 5; break;
-			case 1:	*bits = 6; break;
-			case 2:	*bits = 7; break;
-			case 3:	*bits = 8; break;
+		case 0:
+			*bits = 5;
+			break;
+		case 1:
+			*bits = 6;
+			break;
+		case 2:
+			*bits = 7;
+			break;
+		case 3:
+			*bits = 8;
+			break;
 		}
 		/* Set DLAB in LCR to Access DLL and DLH */
 		UART_SET_DLAB(uart);
@@ -1183,7 +1190,7 @@ static struct console bfin_serial_console = {
 	.index		= -1,
 	.data		= &bfin_serial_reg,
 };
-#define BFIN_SERIAL_CONSOLE	&bfin_serial_console
+#define BFIN_SERIAL_CONSOLE	(&bfin_serial_console)
 #else
 #define BFIN_SERIAL_CONSOLE	NULL
 #endif /* CONFIG_SERIAL_BFIN_CONSOLE */
Signature · 1 line
1.7.7
#10 lore raw

PATCH 10/79 serial:blackfin: rename Blackfin serial driver to bfin_uart.c

In reply to Greg Kroah-Hartman

From: Sonic Zhang <[email protected]>

bfin_5xx.c is not a general name for all Blackfin chips.

---
 drivers/tty/serial/Kconfig                     |    2 +-
 drivers/tty/serial/Makefile                    |    2 +-
 drivers/tty/serial/{bfin_5xx.c => bfin_uart.c} |    0
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/tty/serial/{bfin_5xx.c => bfin_uart.c} (100%)
drivers/tty/serial/Kconfig +1 -1
index 4dcb37b..a9b307f 100644
@@ -722,7 +722,7 @@ config SERIAL_BFIN
 	  Add support for the built-in UARTs on the Blackfin.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called bfin_5xx.
+	  module is named bfin_uart.ko.
 
 config SERIAL_BFIN_CONSOLE
 	bool "Console on Blackfin serial port"
drivers/tty/serial/Makefile +1 -1
index 83b4da6..7874813 100644
@@ -35,7 +35,7 @@ obj-$(CONFIG_SERIAL_PXA) += pxa.o
 obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
 obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
 obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
-obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
+obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o
 obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
 obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
 obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
drivers/tty/serial/bfin_uart.c renamed from drivers/tty/serial/bfin_5xx.c +0 -0
similarity index 100%
rename from drivers/tty/serial/bfin_5xx.c
rename to drivers/tty/serial/bfin_uart.c
Signature · 1 line
1.7.7
#11 lore raw

PATCH 11/79 tty: clearify structure initializer in notify_write()

In reply to Greg Kroah-Hartman

From: Mathias Krause <[email protected]>

Even though this is valid C we should not mix C99 initializers with obfuscated ANSI C. Stick to C99 and initialize c by its name.

Found by clang:
drivers/tty/vt/vt.c:262:55: warning: explicitly assigning a variable of type 'unsigned int' to itself [-Wself-assign]

    struct vt_notifier_param param = { .vc = vc, unicode = unicode };
                                                 ~~~~~~~ ^ ~~~~~~~
---
 drivers/tty/vt/vt.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/vt/vt.c +1 -1
index b3915b7..e716839 100644
@@ -259,7 +259,7 @@ EXPORT_SYMBOL_GPL(unregister_vt_notifier);
 
 static void notify_write(struct vc_data *vc, unsigned int unicode)
 {
-	struct vt_notifier_param param = { .vc = vc, unicode = unicode };
+	struct vt_notifier_param param = { .vc = vc, .c = unicode };
 	atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
 }
 
Signature · 1 line
1.7.7
#12 lore raw

PATCH 12/79 serial:bfin_uart: Put TX IRQ in individual platform resource.

In reply to Greg Kroah-Hartman

From: Sonic Zhang <[email protected]>

Serial TX IRQ is not RX IRQ plus 1 in some blackfin chips. Give individual platform resources to both TX and RX irqs.

---
 drivers/tty/serial/bfin_uart.c |   36 ++++++++++++++++++++++--------------
 1 files changed, 22 insertions(+), 14 deletions(-)
drivers/tty/serial/bfin_uart.c +22 -14
index e08bc04..c7e592d 100644
@@ -667,17 +667,17 @@ static int bfin_serial_startup(struct uart_port *port)
 		kgdboc_break_enabled = 0;
 	else {
 # endif
-	if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
+	if (request_irq(uart->rx_irq, bfin_serial_rx_int, IRQF_DISABLED,
 	     "BFIN_UART_RX", uart)) {
 		printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
 		return -EBUSY;
 	}
 
 	if (request_irq
-	    (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED,
+	    (uart->tx_irq, bfin_serial_tx_int, IRQF_DISABLED,
 	     "BFIN_UART_TX", uart)) {
 		printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n");
-		free_irq(uart->port.irq, uart);
+		free_irq(uart->rx_irq, uart);
 		return -EBUSY;
 	}
 
@@ -692,7 +692,7 @@ static int bfin_serial_startup(struct uart_port *port)
 		 */
 		unsigned uart_dma_ch_rx, uart_dma_ch_tx;
 
-		switch (uart->port.irq) {
+		switch (uart->rx_irq) {
 		case IRQ_UART3_RX:
 			uart_dma_ch_rx = CH_UART3_RX;
 			uart_dma_ch_tx = CH_UART3_TX;
@@ -709,16 +709,16 @@ static int bfin_serial_startup(struct uart_port *port)
 		if (uart_dma_ch_rx &&
 			request_dma(uart_dma_ch_rx, "BFIN_UART_RX") < 0) {
 			printk(KERN_NOTICE"Fail to attach UART interrupt\n");
-			free_irq(uart->port.irq, uart);
-			free_irq(uart->port.irq + 1, uart);
+			free_irq(uart->rx_irq, uart);
+			free_irq(uart->tx_irq, uart);
 			return -EBUSY;
 		}
 		if (uart_dma_ch_tx &&
 			request_dma(uart_dma_ch_tx, "BFIN_UART_TX") < 0) {
 			printk(KERN_NOTICE "Fail to attach UART interrupt\n");
 			free_dma(uart_dma_ch_rx);
-			free_irq(uart->port.irq, uart);
-			free_irq(uart->port.irq + 1, uart);
+			free_irq(uart->rx_irq, uart);
+			free_irq(uart->tx_irq, uart);
 			return -EBUSY;
 		}
 	}
@@ -785,8 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port)
 		break;
 	};
 #endif
-	free_irq(uart->port.irq, uart);
-	free_irq(uart->port.irq+1, uart);
+	free_irq(uart->rx_irq, uart);
+	free_irq(uart->tx_irq, uart);
 #endif
 
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
@@ -1319,14 +1319,22 @@ static int bfin_serial_probe(struct platform_device *pdev)
 		}
 		uart->port.mapbase = res->start;
 
-		uart->port.irq = platform_get_irq(pdev, 0);
-		if (uart->port.irq < 0) {
-			dev_err(&pdev->dev, "No uart RX/TX IRQ specified\n");
+		uart->tx_irq = platform_get_irq(pdev, 0);
+		if (uart->tx_irq < 0) {
+			dev_err(&pdev->dev, "No uart TX IRQ specified\n");
 			ret = -ENOENT;
 			goto out_error_unmap;
 		}
 
-		uart->status_irq = platform_get_irq(pdev, 1);
+		uart->rx_irq = platform_get_irq(pdev, 1);
+		if (uart->rx_irq < 0) {
+			dev_err(&pdev->dev, "No uart RX IRQ specified\n");
+			ret = -ENOENT;
+			goto out_error_unmap;
+		}
+		uart->port.irq = uart->rx_irq;
+
+		uart->status_irq = platform_get_irq(pdev, 2);
 		if (uart->status_irq < 0) {
 			dev_err(&pdev->dev, "No uart status IRQ specified\n");
 			ret = -ENOENT;
Signature · 1 line
1.7.7
#13 lore raw

PATCH 13/79 serial: samsung: Add unified interrupt handler for s3c64xx and later SoC's

In reply to Greg Kroah-Hartman

From: Thomas Abraham <[email protected]>

s3c64xx and later SoC's include the interrupt mask and pending registers in the uart controller, unlike the s3c24xx SoC's which have these registers in the interrupt controller. When the mask and pending registers are part of the uart controller, a unified interrupt handler can handle the tx/rx interrupt. With this, the static reservation of interrupt numbers for the uart tx/rx/err interrupts in the linux irq space is not required and simplifies adding device tree support.

---
 drivers/tty/serial/samsung.c |  107 +++++++++++++++++++++++++++++++++++++-----
 drivers/tty/serial/samsung.h |    1 +
 2 files changed, 96 insertions(+), 12 deletions(-)
drivers/tty/serial/samsung.c +95 -12
index afc6294..9b84654 100644
@@ -83,6 +83,16 @@ static int s3c24xx_serial_txempty_nofifo(struct uart_port *port)
 	return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE);
 }
 
+/*
+ * s3c64xx and later SoC's include the interrupt mask and status registers in
+ * the controller itself, unlike the s3c24xx SoC's which have these registers
+ * in the interrupt controller. Check if the port type is s3c64xx or higher.
+ */
+static int s3c24xx_serial_has_interrupt_mask(struct uart_port *port)
+{
+	return to_ourport(port)->info->type == PORT_S3C6400;
+}
+
 static void s3c24xx_serial_rx_enable(struct uart_port *port)
 {
 	unsigned long flags;
@@ -126,7 +136,11 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 	if (tx_enabled(port)) {
-		disable_irq_nosync(ourport->tx_irq);
+		if (s3c24xx_serial_has_interrupt_mask(port))
+			__set_bit(S3C64XX_UINTM_TXD,
+				portaddrl(port, S3C64XX_UINTM));
+		else
+			disable_irq_nosync(ourport->tx_irq);
 		tx_enabled(port) = 0;
 		if (port->flags & UPF_CONS_FLOW)
 			s3c24xx_serial_rx_enable(port);
@@ -141,19 +155,26 @@ static void s3c24xx_serial_start_tx(struct uart_port *port)
 		if (port->flags & UPF_CONS_FLOW)
 			s3c24xx_serial_rx_disable(port);
 
-		enable_irq(ourport->tx_irq);
+		if (s3c24xx_serial_has_interrupt_mask(port))
+			__clear_bit(S3C64XX_UINTM_TXD,
+				portaddrl(port, S3C64XX_UINTM));
+		else
+			enable_irq(ourport->tx_irq);
 		tx_enabled(port) = 1;
 	}
 }
 
-
 static void s3c24xx_serial_stop_rx(struct uart_port *port)
 {
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 	if (rx_enabled(port)) {
 		dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
-		disable_irq_nosync(ourport->rx_irq);
+		if (s3c24xx_serial_has_interrupt_mask(port))
+			__set_bit(S3C64XX_UINTM_RXD,
+				portaddrl(port, S3C64XX_UINTM));
+		else
+			disable_irq_nosync(ourport->rx_irq);
 		rx_enabled(port) = 0;
 	}
 }
@@ -320,6 +341,28 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 	return IRQ_HANDLED;
 }
 
+/* interrupt handler for s3c64xx and later SoC's.*/
+static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
+{
+	struct s3c24xx_uart_port *ourport = id;
+	struct uart_port *port = &ourport->port;
+	unsigned int pend = rd_regl(port, S3C64XX_UINTP);
+	unsigned long flags;
+	irqreturn_t ret = IRQ_HANDLED;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (pend & S3C64XX_UINTM_RXD_MSK) {
+		ret = s3c24xx_serial_rx_chars(irq, id);
+		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
+	}
+	if (pend & S3C64XX_UINTM_TXD_MSK) {
+		ret = s3c24xx_serial_tx_chars(irq, id);
+		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+	return ret;
+}
+
 static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
 {
 	struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
@@ -377,18 +420,25 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 	if (ourport->tx_claimed) {
-		free_irq(ourport->tx_irq, ourport);
+		if (!s3c24xx_serial_has_interrupt_mask(port))
+			free_irq(ourport->tx_irq, ourport);
 		tx_enabled(port) = 0;
 		ourport->tx_claimed = 0;
 	}
 
 	if (ourport->rx_claimed) {
-		free_irq(ourport->rx_irq, ourport);
+		if (!s3c24xx_serial_has_interrupt_mask(port))
+			free_irq(ourport->rx_irq, ourport);
 		ourport->rx_claimed = 0;
 		rx_enabled(port) = 0;
 	}
-}
 
+	/* Clear pending interrupts and mask all interrupts */
+	if (s3c24xx_serial_has_interrupt_mask(port)) {
+		wr_regl(port, S3C64XX_UINTP, 0xf);
+		wr_regl(port, S3C64XX_UINTM, 0xf);
+	}
+}
 
 static int s3c24xx_serial_startup(struct uart_port *port)
 {
@@ -436,6 +486,33 @@ static int s3c24xx_serial_startup(struct uart_port *port)
 	return ret;
 }
 
+static int s3c64xx_serial_startup(struct uart_port *port)
+{
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+	int ret;
+
+	dbg("s3c64xx_serial_startup: port=%p (%08lx,%p)\n",
+	    port->mapbase, port->membase);
+
+	ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED,
+			  s3c24xx_serial_portname(port), ourport);
+	if (ret) {
+		printk(KERN_ERR "cannot get irq %d\n", port->irq);
+		return ret;
+	}
+
+	/* For compatibility with s3c24xx Soc's */
+	rx_enabled(port) = 1;
+	ourport->rx_claimed = 1;
+	tx_enabled(port) = 0;
+	ourport->tx_claimed = 1;
+
+	/* Enable Rx Interrupt */
+	__clear_bit(S3C64XX_UINTM_RXD, portaddrl(port, S3C64XX_UINTM));
+	dbg("s3c64xx_serial_startup ok\n");
+	return ret;
+}
+
 /* power power management control */
 
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -879,7 +956,6 @@ static struct uart_ops s3c24xx_serial_ops = {
 	.verify_port	= s3c24xx_serial_verify_port,
 };
 
-
 static struct uart_driver s3c24xx_uart_drv = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "s3c2410_serial",
@@ -895,7 +971,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
 		.port = {
 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
 			.iotype		= UPIO_MEM,
-			.irq		= IRQ_S3CUART_RX0,
 			.uartclk	= 0,
 			.fifosize	= 16,
 			.ops		= &s3c24xx_serial_ops,
@@ -907,7 +982,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
 		.port = {
 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
 			.iotype		= UPIO_MEM,
-			.irq		= IRQ_S3CUART_RX1,
 			.uartclk	= 0,
 			.fifosize	= 16,
 			.ops		= &s3c24xx_serial_ops,
@@ -921,7 +995,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
 		.port = {
 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
 			.iotype		= UPIO_MEM,
-			.irq		= IRQ_S3CUART_RX2,
 			.uartclk	= 0,
 			.fifosize	= 16,
 			.ops		= &s3c24xx_serial_ops,
@@ -935,7 +1008,6 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
 		.port = {
 			.lock		= __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),
 			.iotype		= UPIO_MEM,
-			.irq		= IRQ_S3CUART_RX3,
 			.uartclk	= 0,
 			.fifosize	= 16,
 			.ops		= &s3c24xx_serial_ops,
@@ -1077,6 +1149,10 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 	port->dev	= &platdev->dev;
 	ourport->info	= info;
 
+	/* Startup sequence is different for s3c64xx and higher SoC's */
+	if (s3c24xx_serial_has_interrupt_mask(port))
+		s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
+
 	/* copy the info in from provided structure */
 	ourport->port.fifosize = info->fifosize;
 
@@ -1116,6 +1192,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 
 	ourport->clk	= clk_get(&platdev->dev, "uart");
 
+	/* Keep all interrupts masked and cleared */
+	if (s3c24xx_serial_has_interrupt_mask(port)) {
+		wr_regl(port, S3C64XX_UINTM, 0xf);
+		wr_regl(port, S3C64XX_UINTP, 0xf);
+		wr_regl(port, S3C64XX_UINTSP, 0xf);
+	}
+
 	dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n",
 	    port->mapbase, port->membase, port->irq,
 	    ourport->rx_irq, ourport->tx_irq, port->uartclk);
drivers/tty/serial/samsung.h +1 -0
index a69d9a5..8e87b78 100644
@@ -61,6 +61,7 @@ struct s3c24xx_uart_port {
 /* register access controls */
 
 #define portaddr(port, reg) ((port)->membase + (reg))
+#define portaddrl(port, reg) ((unsigned long *)((port)->membase + (reg)))
 
 #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
 #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
Signature · 1 line
1.7.7
#14 lore raw

PATCH 14/79 ARM: SAMSUNG: Remove uart irq handling from plaform code

In reply to Greg Kroah-Hartman

From: Thomas Abraham <[email protected]>

With uart tx/rx/err interrupt handling moved into the driver for s3c64xx and later SoC's, the uart interrupt handling in plaform code can be removed. The uart device irq resources is reduced to one and the related unused macros are removed.

---
 arch/arm/Kconfig                                 |    1 -
 arch/arm/mach-s3c64xx/dev-uart.c                 |   60 ++------------
 arch/arm/mach-s3c64xx/include/mach/irqs.h        |   30 -------
 arch/arm/mach-s3c64xx/irq.c                      |   25 ------
 arch/arm/plat-s5p/Kconfig                        |    1 -
 arch/arm/plat-s5p/dev-uart.c                     |   84 +++----------------
 arch/arm/plat-s5p/include/plat/irqs.h            |   35 --------
 arch/arm/plat-s5p/irq.c                          |   34 --------
 arch/arm/plat-samsung/Kconfig                    |    5 -
 arch/arm/plat-samsung/Makefile                   |    1 -
 arch/arm/plat-samsung/include/plat/regs-serial.h |    5 +
 arch/arm/plat-samsung/irq-uart.c                 |   96 ----------------------
 12 files changed, 25 insertions(+), 352 deletions(-)
 delete mode 100644 arch/arm/plat-samsung/irq-uart.c
arch/arm/Kconfig +0 -1
index 5ebc5d9..325d2f5 100644
@@ -722,7 +722,6 @@ config ARCH_S3C64XX
 	select ARCH_REQUIRE_GPIOLIB
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_IRQ_VIC_TIMER
-	select SAMSUNG_IRQ_UART
 	select S3C_GPIO_TRACK
 	select S3C_GPIO_PULL_UPDOWN
 	select S3C_GPIO_CFG_S3C24XX
arch/arm/mach-s3c64xx/dev-uart.c +8 -52

86 lines not on this page · raw message

arch/arm/mach-s3c64xx/include/mach/irqs.h +0 -30
index c026f67..443f85b 100644
@@ -27,36 +27,6 @@
 #define IRQ_VIC0_BASE	S3C_IRQ(0)
 #define IRQ_VIC1_BASE	S3C_IRQ(32)
 
-/* UART interrupts, each UART has 4 intterupts per channel so
- * use the space between the ISA and S3C main interrupts. Note, these
- * are not in the same order as the S3C24XX series! */
-
-#define IRQ_S3CUART_BASE0	(16)
-#define IRQ_S3CUART_BASE1	(20)
-#define IRQ_S3CUART_BASE2	(24)
-#define IRQ_S3CUART_BASE3	(28)
-
-#define UART_IRQ_RXD		(0)
-#define UART_IRQ_ERR		(1)
-#define UART_IRQ_TXD		(2)
-#define UART_IRQ_MODEM		(3)
-
-#define IRQ_S3CUART_RX0		(IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX0		(IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR0	(IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX1		(IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX1		(IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR1	(IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX2		(IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX2		(IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR2	(IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
-
-#define IRQ_S3CUART_RX3		(IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
-#define IRQ_S3CUART_TX3		(IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
-#define IRQ_S3CUART_ERR3	(IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
-
 /* VIC based IRQs */
 
 #define S3C64XX_IRQ_VIC0(x)	(IRQ_VIC0_BASE + (x))
arch/arm/mach-s3c64xx/irq.c +0 -25
index 75d9a0e..b07357e 100644
@@ -25,29 +25,6 @@
 #include <plat/irq-uart.h>
 #include <plat/cpu.h>
 
-static struct s3c_uart_irq uart_irqs[] = {
-	[0] = {
-		.regs		= S3C_VA_UART0,
-		.base_irq	= IRQ_S3CUART_BASE0,
-		.parent_irq	= IRQ_UART0,
-	},
-	[1] = {
-		.regs		= S3C_VA_UART1,
-		.base_irq	= IRQ_S3CUART_BASE1,
-		.parent_irq	= IRQ_UART1,
-	},
-	[2] = {
-		.regs		= S3C_VA_UART2,
-		.base_irq	= IRQ_S3CUART_BASE2,
-		.parent_irq	= IRQ_UART2,
-	},
-	[3] = {
-		.regs		= S3C_VA_UART3,
-		.base_irq	= IRQ_S3CUART_BASE3,
-		.parent_irq	= IRQ_UART3,
-	},
-};
-
 /* setup the sources the vic should advertise resume for, even though it
  * is not doing the wake (set_irq_wake needs to be valid) */
 #define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
@@ -67,6 +44,4 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
 
 	/* add the timer sub-irqs */
 	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
-
-	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
 }
arch/arm/plat-s5p/Kconfig +0 -1
index 9843c95..9a197e5 100644
@@ -22,7 +22,6 @@ config PLAT_S5P
 	select PLAT_SAMSUNG
 	select SAMSUNG_CLKSRC
 	select SAMSUNG_IRQ_VIC_TIMER
-	select SAMSUNG_IRQ_UART
 	help
 	  Base platform code for Samsung's S5P series SoC.
 
arch/arm/plat-s5p/dev-uart.c +12 -72

122 lines not on this page · raw message

arch/arm/plat-s5p/include/plat/irqs.h +0 -35
index ba9121c..144dbfc 100644
@@ -37,41 +37,6 @@
 #define IRQ_VIC1_BASE		S5P_VIC1_BASE
 #define IRQ_VIC2_BASE		S5P_VIC2_BASE
 
-/* UART interrupts, each UART has 4 intterupts per channel so
- * use the space between the ISA and S3C main interrupts. Note, these
- * are not in the same order as the S3C24XX series! */
-
-#define IRQ_S5P_UART_BASE0	(16)
-#define IRQ_S5P_UART_BASE1	(20)
-#define IRQ_S5P_UART_BASE2	(24)
-#define IRQ_S5P_UART_BASE3	(28)
-
-#define UART_IRQ_RXD		(0)
-#define UART_IRQ_ERR		(1)
-#define UART_IRQ_TXD		(2)
-
-#define IRQ_S5P_UART_RX0	(IRQ_S5P_UART_BASE0 + UART_IRQ_RXD)
-#define IRQ_S5P_UART_TX0	(IRQ_S5P_UART_BASE0 + UART_IRQ_TXD)
-#define IRQ_S5P_UART_ERR0	(IRQ_S5P_UART_BASE0 + UART_IRQ_ERR)
-
-#define IRQ_S5P_UART_RX1	(IRQ_S5P_UART_BASE1 + UART_IRQ_RXD)
-#define IRQ_S5P_UART_TX1	(IRQ_S5P_UART_BASE1 + UART_IRQ_TXD)
-#define IRQ_S5P_UART_ERR1	(IRQ_S5P_UART_BASE1 + UART_IRQ_ERR)
-
-#define IRQ_S5P_UART_RX2	(IRQ_S5P_UART_BASE2 + UART_IRQ_RXD)
-#define IRQ_S5P_UART_TX2	(IRQ_S5P_UART_BASE2 + UART_IRQ_TXD)
-#define IRQ_S5P_UART_ERR2	(IRQ_S5P_UART_BASE2 + UART_IRQ_ERR)
-
-#define IRQ_S5P_UART_RX3	(IRQ_S5P_UART_BASE3 + UART_IRQ_RXD)
-#define IRQ_S5P_UART_TX3	(IRQ_S5P_UART_BASE3 + UART_IRQ_TXD)
-#define IRQ_S5P_UART_ERR3	(IRQ_S5P_UART_BASE3 + UART_IRQ_ERR)
-
-/* S3C compatibilty defines */
-#define IRQ_S3CUART_RX0		IRQ_S5P_UART_RX0
-#define IRQ_S3CUART_RX1		IRQ_S5P_UART_RX1
-#define IRQ_S3CUART_RX2		IRQ_S5P_UART_RX2
-#define IRQ_S3CUART_RX3		IRQ_S5P_UART_RX3
-
 /* VIC based IRQs */
 
 #define S5P_IRQ_VIC0(x)		(S5P_VIC0_BASE + (x))
arch/arm/plat-s5p/irq.c +0 -34
index a97c089..afdaa10 100644
@@ -17,42 +17,10 @@
 
 #include <asm/hardware/vic.h>
 
-#include <linux/serial_core.h>
 #include <mach/map.h>
 #include <plat/regs-timer.h>
-#include <plat/regs-serial.h>
 #include <plat/cpu.h>
 #include <plat/irq-vic-timer.h>
-#include <plat/irq-uart.h>
-
-/*
- * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
- * are consecutive when looking up the interrupt in the demux routines.
- */
-static struct s3c_uart_irq uart_irqs[] = {
-	[0] = {
-		.regs		= S5P_VA_UART0,
-		.base_irq	= IRQ_S5P_UART_BASE0,
-		.parent_irq	= IRQ_UART0,
-	},
-	[1] = {
-		.regs		= S5P_VA_UART1,
-		.base_irq	= IRQ_S5P_UART_BASE1,
-		.parent_irq	= IRQ_UART1,
-	},
-	[2] = {
-		.regs		= S5P_VA_UART2,
-		.base_irq	= IRQ_S5P_UART_BASE2,
-		.parent_irq	= IRQ_UART2,
-	},
-#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
-	[3] = {
-		.regs		= S5P_VA_UART3,
-		.base_irq	= IRQ_S5P_UART_BASE3,
-		.parent_irq	= IRQ_UART3,
-	},
-#endif
-};
 
 void __init s5p_init_irq(u32 *vic, u32 num_vic)
 {
@@ -65,6 +33,4 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
 #endif
 
 	s3c_init_vic_timer_irq(5, IRQ_TIMER0);
-
-	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
 }
arch/arm/plat-samsung/Kconfig +0 -5
index b3e1065..dffa37b 100644
@@ -65,11 +65,6 @@ config SAMSUNG_IRQ_VIC_TIMER
        help
          Internal configuration to build the VIC timer interrupt code.
 
-config SAMSUNG_IRQ_UART
-       bool
-       help
-         Internal configuration to build the IRQ UART demux code.
-
 # options for gpio configuration support
 
 config SAMSUNG_GPIOLIB_4BIT
arch/arm/plat-samsung/Makefile +0 -1
index 853764b..1105922 100644
@@ -21,7 +21,6 @@ obj-y				+= dev-asocdma.o
 
 obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
 
-obj-$(CONFIG_SAMSUNG_IRQ_UART)	+= irq-uart.o
 obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
 
 # ADC
arch/arm/plat-samsung/include/plat/regs-serial.h +5 -0
index bac36fa..7207348 100644
@@ -186,6 +186,11 @@
 #define S3C64XX_UINTSP		0x34
 #define S3C64XX_UINTM		0x38
 
+#define S3C64XX_UINTM_RXD	(0)
+#define S3C64XX_UINTM_TXD	(2)
+#define S3C64XX_UINTM_RXD_MSK	(1 << S3C64XX_UINTM_RXD)
+#define S3C64XX_UINTM_TXD_MSK	(1 << S3C64XX_UINTM_TXD)
+
 /* Following are specific to S5PV210 */
 #define S5PV210_UCON_CLKMASK	(1<<10)
 #define S5PV210_UCON_PCLK	(0<<10)
arch/arm/plat-samsung/irq-uart.c deleted +0 -96

96 lines not on this page · raw message

Signature · 1 line
1.7.7
#15 lore raw

PATCH 15/79 tty: serial: allow ports to override the irq handler

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

Some serial ports may have unusal requirements for interrupt handling (e.g. the Synopsys DesignWare 8250-alike port and it's busy detect interrupt). Add a .handle_irq callback that can be used for platforms to override the interrupt behaviour in a similar fashion to the .serial_out and .serial_in callbacks.

---
 include/linux/serial_core.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
include/linux/serial_core.h +1 -0
index 76e1103..c31ae43 100644
@@ -300,6 +300,7 @@ struct uart_port {
 	void			(*set_termios)(struct uart_port *,
 				               struct ktermios *new,
 				               struct ktermios *old);
+	int			(*handle_irq)(struct uart_port *);
 	void			(*pm)(struct uart_port *, unsigned int state,
 				      unsigned int old);
 	unsigned int		irq;			/* irq number */
Signature · 1 line
1.7.7
#16 lore raw

PATCH 16/79 tty: serial8250: allow platforms to override irq handler

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

Some ports (e.g. Synopsys DesignWare 8250) have special requirements for handling the interrupts. Allow these platforms to specify their own interrupt handler that will override the default. serial8250_handle_irq() is provided so that platforms can extend the IRQ handler rather than completely replacing it.

---
 drivers/tty/serial/8250.c   |   39 +++++++++++++++++++++++++++++++++++----
 include/linux/serial_8250.h |    2 ++
 2 files changed, 37 insertions(+), 4 deletions(-)
drivers/tty/serial/8250.c +35 -4
index f2dfec8..833e011 100644
@@ -509,6 +509,8 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
 	outb(value, p->iobase + offset);
 }
 
+static int serial8250_default_handle_irq(struct uart_port *port);
+
 static void set_io_from_upio(struct uart_port *p)
 {
 	struct uart_8250_port *up =
@@ -557,6 +559,7 @@ static void set_io_from_upio(struct uart_port *p)
 	}
 	/* Remember loaded iotype */
 	up->cur_iotype = p->iotype;
+	p->handle_irq = serial8250_default_handle_irq;
 }
 
 static void
@@ -1621,6 +1624,28 @@ static void serial8250_handle_port(struct uart_8250_port *up)
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
+int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+{
+	struct uart_8250_port *up =
+		container_of(port, struct uart_8250_port, port);
+
+	if (!(iir & UART_IIR_NO_INT)) {
+		serial8250_handle_port(up);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int serial8250_default_handle_irq(struct uart_port *port)
+{
+	struct uart_8250_port *up =
+		container_of(port, struct uart_8250_port, port);
+	unsigned int iir = serial_in(up, UART_IIR);
+
+	return serial8250_handle_irq(port, iir);
+}
+
 /*
  * This is the serial driver's interrupt routine.
  *
@@ -1648,13 +1673,12 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 	l = i->head;
 	do {
 		struct uart_8250_port *up;
-		unsigned int iir;
+		struct uart_port *port;
 
 		up = list_entry(l, struct uart_8250_port, list);
+		port = &up->port;
 
-		iir = serial_in(up, UART_IIR);
-		if (!(iir & UART_IIR_NO_INT)) {
-			serial8250_handle_port(up);
+		if (port->handle_irq(port)) {
 
 			handled = 1;
 
@@ -3048,6 +3072,10 @@ int __init early_serial_setup(struct uart_port *port)
 		p->serial_in = port->serial_in;
 	if (port->serial_out)
 		p->serial_out = port->serial_out;
+	if (port->handle_irq)
+		p->handle_irq = port->handle_irq;
+	else
+		p->handle_irq = serial8250_default_handle_irq;
 
 	return 0;
 }
@@ -3116,6 +3144,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 		port.type		= p->type;
 		port.serial_in		= p->serial_in;
 		port.serial_out		= p->serial_out;
+		port.handle_irq		= p->handle_irq;
 		port.set_termios	= p->set_termios;
 		port.pm			= p->pm;
 		port.dev		= &dev->dev;
@@ -3281,6 +3310,8 @@ int serial8250_register_port(struct uart_port *port)
 			uart->port.serial_in = port->serial_in;
 		if (port->serial_out)
 			uart->port.serial_out = port->serial_out;
+		if (port->handle_irq)
+			uart->port.handle_irq = port->handle_irq;
 		/*  Possibly override set_termios call */
 		if (port->set_termios)
 			uart->port.set_termios = port->set_termios;
include/linux/serial_8250.h +2 -0
index 97f5b45..1f05bbe 100644
@@ -35,6 +35,7 @@ struct plat_serial8250_port {
 	void		(*set_termios)(struct uart_port *,
 			               struct ktermios *new,
 			               struct ktermios *old);
+	int		(*handle_irq)(struct uart_port *);
 	void		(*pm)(struct uart_port *, unsigned int state,
 			      unsigned old);
 };
@@ -80,6 +81,7 @@ extern void serial8250_do_set_termios(struct uart_port *port,
 		struct ktermios *termios, struct ktermios *old);
 extern void serial8250_do_pm(struct uart_port *port, unsigned int state,
 			     unsigned int oldstate);
+int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
 
 extern void serial8250_set_isa_configurator(void (*v)
 					(int port, struct uart_port *up,
Signature · 1 line
1.7.7
#17 lore raw

PATCH 17/79 mips: msp71xx/serial: convert to pr_foo() helpers

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

Convert to pr_foo() helpers rather than printk(KERN_.*).

---
 arch/mips/pmc-sierra/msp71xx/msp_serial.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
arch/mips/pmc-sierra/msp71xx/msp_serial.c +2 -2
index f726162..c3247b5 100644
@@ -65,7 +65,7 @@ void __init msp_serial_setup(void)
 	up.line         = 0;
 	up.private_data		= (void*)UART0_STATUS_REG;
 	if (early_serial_setup(&up))
-		printk(KERN_ERR "Early serial init of port 0 failed\n");
+		pr_err("Early serial init of port 0 failed\n");
 
 	/* Initialize the second serial port, if one exists */
 	switch (mips_machtype) {
@@ -89,5 +89,5 @@ void __init msp_serial_setup(void)
 	up.line         = 1;
 	up.private_data		= (void*)UART1_STATUS_REG;
 	if (early_serial_setup(&up))
-		printk(KERN_ERR "Early serial init of port 1 failed\n");
+		pr_err("Early serial init of port 1 failed\n");
 }
Signature · 1 line
1.7.7
#18 lore raw

PATCH 18/79 mips: msp71xx/serial: add workaround for DW UART

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

The Synopsys DesignWare UART in pmc-sierra msp71xx has an extra feature where the UART detects a write attempt to the LCR whilst busy and raises an interrupt. The driver needs to clear the interrupt and rewrite the LCR. Move this into platform code and out of the 8250 driver.

---
 arch/mips/pmc-sierra/msp71xx/msp_serial.c |   69 +++++++++++++++++++++++++++--
 1 files changed, 65 insertions(+), 4 deletions(-)
arch/mips/pmc-sierra/msp71xx/msp_serial.c +65 -4
index c3247b5..a1c7c7d 100644
@@ -27,6 +27,7 @@
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
+#include <linux/slab.h>
 
 #include <asm/bootinfo.h>
 #include <asm/io.h>
@@ -38,6 +39,55 @@
 #include <msp_int.h>
 #include <msp_regs.h>
 
+struct msp_uart_data {
+	int	last_lcr;
+};
+
+static void msp_serial_out(struct uart_port *p, int offset, int value)
+{
+	struct msp_uart_data *d = p->private_data;
+
+	if (offset == UART_LCR)
+		d->last_lcr = value;
+
+	offset <<= p->regshift;
+	writeb(value, p->membase + offset);
+}
+
+static unsigned int msp_serial_in(struct uart_port *p, int offset)
+{
+	offset <<= p->regshift;
+
+	return readb(p->membase + offset);
+}
+
+static int msp_serial_handle_irq(struct uart_port *p)
+{
+	struct msp_uart_data *d = p->private_data;
+	unsigned int iir = readb(p->membase + (UART_IIR << p->regshift));
+
+	if (serial8250_handle_irq(p, iir)) {
+		return 1;
+	} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
+		/*
+		 * The DesignWare APB UART has an Busy Detect (0x07) interrupt
+		 * meaning an LCR write attempt occurred while the UART was
+		 * busy. The interrupt must be cleared by reading the UART
+		 * status register (USR) and the LCR re-written.
+		 *
+		 * Note: MSP reserves 0x20 bytes of address space for the UART
+		 * and the USR is mapped in a separate block at an offset of
+		 * 0xc0 from the start of the UART.
+		 */
+		(void)readb(p->membase + 0xc0);
+		writeb(d->last_lcr, p->membase + (UART_LCR << p->regshift));
+
+		return 1;
+	}
+
+	return 0;
+}
+
 void __init msp_serial_setup(void)
 {
 	char    *s;
@@ -59,13 +109,22 @@ void __init msp_serial_setup(void)
 	up.irq          = MSP_INT_UART0;
 	up.uartclk      = uartclk;
 	up.regshift     = 2;
-	up.iotype       = UPIO_DWAPB; /* UPIO_MEM like */
+	up.iotype       = UPIO_MEM;
 	up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
 	up.type         = PORT_16550A;
 	up.line         = 0;
-	up.private_data		= (void*)UART0_STATUS_REG;
-	if (early_serial_setup(&up))
+	up.serial_out	= msp_serial_out;
+	up.serial_in	= msp_serial_in;
+	up.handle_irq	= msp_serial_handle_irq;
+	up.private_data	= kzalloc(sizeof(struct msp_uart_data), GFP_KERNEL);
+	if (!up.private_data) {
+		pr_err("failed to allocate uart private data\n");
+		return;
+	}
+	if (early_serial_setup(&up)) {
+		kfree(up.private_data);
 		pr_err("Early serial init of port 0 failed\n");
+	}
 
 	/* Initialize the second serial port, if one exists */
 	switch (mips_machtype) {
@@ -88,6 +147,8 @@ void __init msp_serial_setup(void)
 	up.irq          = MSP_INT_UART1;
 	up.line         = 1;
 	up.private_data		= (void*)UART1_STATUS_REG;
-	if (early_serial_setup(&up))
+	if (early_serial_setup(&up)) {
+		kfree(up.private_data);
 		pr_err("Early serial init of port 1 failed\n");
+	}
 }
Signature · 1 line
1.7.7
#19 lore raw

PATCH 19/79 tty: serial8250: remove UPIO_DWAPB{,32}

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

Now that platforms can override the port IRQ handler and the only user of these UPIO modes has been converted over, kill off UPIO_DWAPB and UPIO_DWAPB32.

---
 drivers/tty/serial/8250.c        |   68 --------------------------------------
 drivers/tty/serial/serial_core.c |    4 --
 include/linux/serial_core.h      |    4 +--
 3 files changed, 1 insertions(+), 75 deletions(-)
drivers/tty/serial/8250.c +0 -68
index 833e011..6f594d2 100644
@@ -461,42 +461,6 @@ static void tsi_serial_out(struct uart_port *p, int offset, int value)
 		writeb(value, p->membase + offset);
 }
 
-/* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
-static inline void dwapb_save_out_value(struct uart_port *p, int offset,
-					int value)
-{
-	struct uart_8250_port *up =
-		container_of(p, struct uart_8250_port, port);
-
-	if (offset == UART_LCR)
-		up->lcr = value;
-}
-
-/* Read the IER to ensure any interrupt is cleared before returning from ISR. */
-static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
-{
-	if (offset == UART_TX || offset == UART_IER)
-		p->serial_in(p, UART_IER);
-}
-
-static void dwapb_serial_out(struct uart_port *p, int offset, int value)
-{
-	int save_offset = offset;
-	offset = map_8250_out_reg(p, offset) << p->regshift;
-	dwapb_save_out_value(p, save_offset, value);
-	writeb(value, p->membase + offset);
-	dwapb_check_clear_ier(p, save_offset);
-}
-
-static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
-{
-	int save_offset = offset;
-	offset = map_8250_out_reg(p, offset) << p->regshift;
-	dwapb_save_out_value(p, save_offset, value);
-	writel(value, p->membase + offset);
-	dwapb_check_clear_ier(p, save_offset);
-}
-
 static unsigned int io_serial_in(struct uart_port *p, int offset)
 {
 	offset = map_8250_in_reg(p, offset) << p->regshift;
@@ -542,16 +506,6 @@ static void set_io_from_upio(struct uart_port *p)
 		p->serial_out = tsi_serial_out;
 		break;
 
-	case UPIO_DWAPB:
-		p->serial_in = mem_serial_in;
-		p->serial_out = dwapb_serial_out;
-		break;
-
-	case UPIO_DWAPB32:
-		p->serial_in = mem32_serial_in;
-		p->serial_out = dwapb32_serial_out;
-		break;
-
 	default:
 		p->serial_in = io_serial_in;
 		p->serial_out = io_serial_out;
@@ -570,8 +524,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
 	case UPIO_MEM:
 	case UPIO_MEM32:
 	case UPIO_AU:
-	case UPIO_DWAPB:
-	case UPIO_DWAPB32:
 		p->serial_out(p, offset, value);
 		p->serial_in(p, UART_LCR);	/* safe, no side-effects */
 		break;
@@ -1679,23 +1631,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
 		port = &up->port;
 
 		if (port->handle_irq(port)) {
-
 			handled = 1;
-
-			end = NULL;
-		} else if ((up->port.iotype == UPIO_DWAPB ||
-			    up->port.iotype == UPIO_DWAPB32) &&
-			  (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
-			/* The DesignWare APB UART has an Busy Detect (0x07)
-			 * interrupt meaning an LCR write attempt occurred while the
-			 * UART was busy. The interrupt must be cleared by reading
-			 * the UART status register (USR) and the LCR re-written. */
-			unsigned int status;
-			status = *(volatile u32 *)up->port.private_data;
-			serial_out(up, UART_LCR, up->lcr);
-
-			handled = 1;
-
 			end = NULL;
 		} else if (end == NULL)
 			end = l;
@@ -2592,8 +2528,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
 	case UPIO_TSI:
 	case UPIO_MEM32:
 	case UPIO_MEM:
-	case UPIO_DWAPB:
-	case UPIO_DWAPB32:
 		if (!up->port.mapbase)
 			break;
 
@@ -2630,8 +2564,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
 	case UPIO_TSI:
 	case UPIO_MEM32:
 	case UPIO_MEM:
-	case UPIO_DWAPB:
-	case UPIO_DWAPB32:
 		if (!up->port.mapbase)
 			break;
 
drivers/tty/serial/serial_core.c +0 -4
index 44c2963..3844980 100644
@@ -2032,8 +2032,6 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
 	case UPIO_MEM32:
 	case UPIO_AU:
 	case UPIO_TSI:
-	case UPIO_DWAPB:
-	case UPIO_DWAPB32:
 		snprintf(address, sizeof(address),
 			 "MMIO 0x%llx", (unsigned long long)port->mapbase);
 		break;
@@ -2446,8 +2444,6 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2)
 	case UPIO_MEM32:
 	case UPIO_AU:
 	case UPIO_TSI:
-	case UPIO_DWAPB:
-	case UPIO_DWAPB32:
 		return (port1->mapbase == port2->mapbase);
 	}
 	return 0;
include/linux/serial_core.h +1 -3
index c31ae43..493773e 100644
@@ -318,9 +318,7 @@ struct uart_port {
 #define UPIO_MEM32		(3)
 #define UPIO_AU			(4)			/* Au1x00 type IO */
 #define UPIO_TSI		(5)			/* Tsi108/109 type IO */
-#define UPIO_DWAPB		(6)			/* DesignWare APB UART */
-#define UPIO_RM9000		(7)			/* RM9000 type IO */
-#define UPIO_DWAPB32		(8)			/* DesignWare APB UART (32 bit accesses) */
+#define UPIO_RM9000		(6)			/* RM9000 type IO */
 
 	unsigned int		read_status_mask;	/* driver specific */
 	unsigned int		ignore_status_mask;	/* driver specific */
Signature · 1 line
1.7.7
#20 lore raw

PATCH 20/79 tty: serial8250: add helpers for the DesignWare 8250

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

The Synopsys DesignWare 8250 is an 8250 that has an extra interrupt that gets raised when writing to the LCR when busy. To handle this we need special serial_out, serial_in and handle_irq methods. Add a new function serial8250_use_designware_io() that configures a uart_port with these accessors.

---
 drivers/tty/serial/8250_dw.c |   99 ++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/serial/Kconfig   |    7 +++
 drivers/tty/serial/Makefile  |    1 +
 include/linux/serial_8250.h  |    8 +++
 4 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 drivers/tty/serial/8250_dw.c
drivers/tty/serial/8250_dw.c new file +99 -0
new file mode 100644
index 0000000..e25782a
@@ -0,0 +1,99 @@
+/*
+ * Synopsys DesignWare specific 8250 operations.
+ *
+ * Copyright 2011 Picochip, Jamie Iles.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
+ * LCR is written whilst busy.  If it is, then a busy detect interrupt is
+ * raised, the LCR needs to be rewritten and the uart status register read.
+ */
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/slab.h>
+
+struct dw8250_data {
+	int	last_lcr;
+};
+
+static void dw8250_serial_out(struct uart_port *p, int offset, int value)
+{
+	struct dw8250_data *d = p->private_data;
+
+	if (offset == UART_LCR)
+		d->last_lcr = value;
+
+	offset <<= p->regshift;
+	writeb(value, p->membase + offset);
+}
+
+static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
+{
+	offset <<= p->regshift;
+
+	return readb(p->membase + offset);
+}
+
+static void dw8250_serial_out32(struct uart_port *p, int offset,
+				int value)
+{
+	struct dw8250_data *d = p->private_data;
+
+	if (offset == UART_LCR)
+		d->last_lcr = value;
+
+	offset <<= p->regshift;
+	writel(value, p->membase + offset);
+}
+
+static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
+{
+	offset <<= p->regshift;
+
+	return readl(p->membase + offset);
+}
+
+/* Offset for the DesignWare's UART Status Register. */
+#define UART_USR	0x1f
+
+static int dw8250_handle_irq(struct uart_port *p)
+{
+	struct dw8250_data *d = p->private_data;
+	unsigned int iir = p->serial_in(p, UART_IIR);
+
+	if (serial8250_handle_irq(p, iir)) {
+		return 1;
+	} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
+		/* Clear the USR and write the LCR again. */
+		(void)p->serial_in(p, UART_USR);
+		p->serial_out(p, d->last_lcr, UART_LCR);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+int serial8250_use_designware_io(struct uart_port *up)
+{
+	up->private_data = kzalloc(sizeof(struct dw8250_data), GFP_KERNEL);
+	if (!up->private_data)
+		return -ENOMEM;
+
+	if (up->iotype == UPIO_MEM32) {
+		up->serial_out = dw8250_serial_out32;
+		up->serial_in = dw8250_serial_in32;
+	} else {
+		up->serial_out = dw8250_serial_out;
+		up->serial_in = dw8250_serial_in;
+	}
+	up->handle_irq = dw8250_handle_irq;
+
+	return 0;
+}
drivers/tty/serial/Kconfig +7 -0
index a9b307f..d2d1cc2 100644
@@ -267,6 +267,13 @@ config SERIAL_8250_RM9K
 	  port hardware found on MIPS RM9122 and similar processors.
 	  If unsure, say N.
 
+config SERIAL_8250_DW
+	bool "Support for Synopsys DesignWare 8250 quirks"
+	depends on SERIAL_8250
+	help
+	  Selecting this option will enable handling of the extra features
+	  present in the Synopsys DesignWare APB UART.
+
 comment "Non-8250 serial port support"
 
 config SERIAL_AMBA_PL010
drivers/tty/serial/Makefile +1 -0
index 7874813..7b59958 100644
@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
 obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
 obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
include/linux/serial_8250.h +8 -0
index 1f05bbe..09e2dbc 100644
@@ -86,5 +86,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
 extern void serial8250_set_isa_configurator(void (*v)
 					(int port, struct uart_port *up,
 						unsigned short *capabilities));
+#ifndef SERIAL_8250_DW
+extern int serial8250_use_designware_io(struct uart_port *up);
+#else
+static inline int serial8250_use_designware_io(struct uart_port *up)
+{
+	return -EIO;
+}
+#endif
 
 #endif
Signature · 1 line
1.7.7
#21 lore raw

PATCH 21/79 tty: of_serial: add support for the DesignWare 8250

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

Support the DesignWare 8250 by a new compatible string and registering the DesignWare helpers. If the registration of the helpers fails, then continue as a normal 8250 as we may still get some useful debug out.

---
 .../devicetree/bindings/tty/serial/of-serial.txt   |    1 +
 drivers/tty/serial/of_serial.c                     |    7 +++++++
 2 files changed, 8 insertions(+), 0 deletions(-)
Documentation/devicetree/bindings/tty/serial/of-serial.txt +1 -0
index b8b27b0..b7ceaaa 100644
@@ -3,6 +3,7 @@
 Required properties:
 - compatible : one of:
 	- "ns8250"
+	- "ns8250dw"
 	- "ns16450"
 	- "ns16550a"
 	- "ns16550"
drivers/tty/serial/of_serial.c +7 -0
index e58cece..024926c 100644
@@ -78,6 +78,12 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
 		}
 	}
 
+	if (of_device_is_compatible(np, "ns8250dw")) {
+		ret = serial8250_use_designware_io(port);
+		if (ret)
+			dev_warn(&ofdev->dev, "unable to register DesignWare 8250 helpers, continuing as a normal 8250\n");
+	}
+
 	port->type = type;
 	port->uartclk = clk;
 	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
@@ -176,6 +182,7 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
  */
 static struct of_device_id __devinitdata of_platform_serial_table[] = {
 	{ .compatible = "ns8250",   .data = (void *)PORT_8250, },
+	{ .compatible = "ns8250dw", .data = (void *)PORT_8250, },
 	{ .compatible = "ns16450",  .data = (void *)PORT_16450, },
 	{ .compatible = "ns16550a", .data = (void *)PORT_16550A, },
 	{ .compatible = "ns16550",  .data = (void *)PORT_16550, },
Signature · 1 line
1.7.7
#22 lore raw

PATCH 22/79 Revert "tty: of_serial: add support for the DesignWare 8250"

In reply to Greg Kroah-Hartman

This reverts commit 14a8d47d4e9f51372996914c16bdbf1c34e209b5.

It causes a build error that needs to be resolved differently.

Cc Alan Cox <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Jamie Iles <[email protected]>
---
 .../devicetree/bindings/tty/serial/of-serial.txt   |    1 -
 drivers/tty/serial/of_serial.c                     |    7 -------
 2 files changed, 0 insertions(+), 8 deletions(-)
Documentation/devicetree/bindings/tty/serial/of-serial.txt +0 -1
index b7ceaaa..b8b27b0 100644
@@ -3,7 +3,6 @@
 Required properties:
 - compatible : one of:
 	- "ns8250"
-	- "ns8250dw"
 	- "ns16450"
 	- "ns16550a"
 	- "ns16550"
drivers/tty/serial/of_serial.c +0 -7
index 024926c..e58cece 100644
@@ -78,12 +78,6 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
 		}
 	}
 
-	if (of_device_is_compatible(np, "ns8250dw")) {
-		ret = serial8250_use_designware_io(port);
-		if (ret)
-			dev_warn(&ofdev->dev, "unable to register DesignWare 8250 helpers, continuing as a normal 8250\n");
-	}
-
 	port->type = type;
 	port->uartclk = clk;
 	port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
@@ -182,7 +176,6 @@ static int of_platform_serial_remove(struct platform_device *ofdev)
  */
 static struct of_device_id __devinitdata of_platform_serial_table[] = {
 	{ .compatible = "ns8250",   .data = (void *)PORT_8250, },
-	{ .compatible = "ns8250dw", .data = (void *)PORT_8250, },
 	{ .compatible = "ns16450",  .data = (void *)PORT_16450, },
 	{ .compatible = "ns16550a", .data = (void *)PORT_16550A, },
 	{ .compatible = "ns16550",  .data = (void *)PORT_16550, },
Signature · 1 line
1.7.7
#23 lore raw

PATCH 23/79 Revert "tty: serial8250: add helpers for the DesignWare 8250"

In reply to Greg Kroah-Hartman

This reverts commit 6b1a98d1c4851235d9b6764b3f7b7db7909fc760.

It causes a build error that needs to be resolved differently.

Cc Alan Cox <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Jamie Iles <[email protected]>
---
 drivers/tty/serial/8250_dw.c |   99 ------------------------------------------
 drivers/tty/serial/Kconfig   |    7 ---
 drivers/tty/serial/Makefile  |    1 -
 include/linux/serial_8250.h  |    8 ---
 4 files changed, 0 insertions(+), 115 deletions(-)
 delete mode 100644 drivers/tty/serial/8250_dw.c
drivers/tty/serial/8250_dw.c deleted +0 -99
deleted file mode 100644
index e25782a..0000000
@@ -1,99 +0,0 @@
-/*
- * Synopsys DesignWare specific 8250 operations.
- *
- * Copyright 2011 Picochip, Jamie Iles.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
- * LCR is written whilst busy.  If it is, then a busy detect interrupt is
- * raised, the LCR needs to be rewritten and the uart status register read.
- */
-#include <linux/io.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-#include <linux/slab.h>
-
-struct dw8250_data {
-	int	last_lcr;
-};
-
-static void dw8250_serial_out(struct uart_port *p, int offset, int value)
-{
-	struct dw8250_data *d = p->private_data;
-
-	if (offset == UART_LCR)
-		d->last_lcr = value;
-
-	offset <<= p->regshift;
-	writeb(value, p->membase + offset);
-}
-
-static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
-{
-	offset <<= p->regshift;
-
-	return readb(p->membase + offset);
-}
-
-static void dw8250_serial_out32(struct uart_port *p, int offset,
-				int value)
-{
-	struct dw8250_data *d = p->private_data;
-
-	if (offset == UART_LCR)
-		d->last_lcr = value;
-
-	offset <<= p->regshift;
-	writel(value, p->membase + offset);
-}
-
-static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
-{
-	offset <<= p->regshift;
-
-	return readl(p->membase + offset);
-}
-
-/* Offset for the DesignWare's UART Status Register. */
-#define UART_USR	0x1f
-
-static int dw8250_handle_irq(struct uart_port *p)
-{
-	struct dw8250_data *d = p->private_data;
-	unsigned int iir = p->serial_in(p, UART_IIR);
-
-	if (serial8250_handle_irq(p, iir)) {
-		return 1;
-	} else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
-		/* Clear the USR and write the LCR again. */
-		(void)p->serial_in(p, UART_USR);
-		p->serial_out(p, d->last_lcr, UART_LCR);
-
-		return 1;
-	}
-
-	return 0;
-}
-
-int serial8250_use_designware_io(struct uart_port *up)
-{
-	up->private_data = kzalloc(sizeof(struct dw8250_data), GFP_KERNEL);
-	if (!up->private_data)
-		return -ENOMEM;
-
-	if (up->iotype == UPIO_MEM32) {
-		up->serial_out = dw8250_serial_out32;
-		up->serial_in = dw8250_serial_in32;
-	} else {
-		up->serial_out = dw8250_serial_out;
-		up->serial_in = dw8250_serial_in;
-	}
-	up->handle_irq = dw8250_handle_irq;
-
-	return 0;
-}
drivers/tty/serial/Kconfig +0 -7
index d2d1cc2..a9b307f 100644
@@ -267,13 +267,6 @@ config SERIAL_8250_RM9K
 	  port hardware found on MIPS RM9122 and similar processors.
 	  If unsure, say N.
 
-config SERIAL_8250_DW
-	bool "Support for Synopsys DesignWare 8250 quirks"
-	depends on SERIAL_8250
-	help
-	  Selecting this option will enable handling of the extra features
-	  present in the Synopsys DesignWare APB UART.
-
 comment "Non-8250 serial port support"
 
 config SERIAL_AMBA_PL010
drivers/tty/serial/Makefile +0 -1
index 7b59958..7874813 100644
@@ -28,7 +28,6 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
 obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
 obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
-obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
include/linux/serial_8250.h +0 -8
index 09e2dbc..1f05bbe 100644
@@ -86,13 +86,5 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
 extern void serial8250_set_isa_configurator(void (*v)
 					(int port, struct uart_port *up,
 						unsigned short *capabilities));
-#ifndef SERIAL_8250_DW
-extern int serial8250_use_designware_io(struct uart_port *up);
-#else
-static inline int serial8250_use_designware_io(struct uart_port *up)
-{
-	return -EIO;
-}
-#endif
 
 #endif
Signature · 1 line
1.7.7
#24 lore raw

PATCH 24/79 serial/imx: support to handle break character

In reply to Greg Kroah-Hartman

From: Hui Wang <[email protected]>

The imx UART hardware controller can identify BREAK character and the imx_set_termios() can accept BRKINT set by users, but current existing imx_rxint() can't pass BREAK character and TTY_BREAK to the tty layer as other serial drivers do (8250.c omap_serial.c).

Here add code to handle BREAK character and pass it to tty layer.

To detect error occurrence, i use URXD_ERR to replace (URXD_OVRRUN | URXD_FRMERR | ...) because any kind of error occurs, URXD_ERR will always be set to 1.

I put the URXD_BRK to the first place to check since when BREAK error occurs, not only URXD_BRK is set to 1, but also URXD_PRERR and URXD_FRMERR are all set to 1. This arrangement can filter out fake parity and frame errors when BREAK error occurs.

---
 drivers/tty/serial/imx.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)
drivers/tty/serial/imx.c +7 -3
index 7e91b3d..54ffdc6 100644
@@ -508,8 +508,10 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
 		if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
 			continue;
 
-		if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
-			if (rx & URXD_PRERR)
+		if (unlikely(rx & URXD_ERR)) {
+			if (rx & URXD_BRK)
+				sport->port.icount.brk++;
+			else if (rx & URXD_PRERR)
 				sport->port.icount.parity++;
 			else if (rx & URXD_FRMERR)
 				sport->port.icount.frame++;
@@ -524,7 +526,9 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
 
 			rx &= sport->port.read_status_mask;
 
-			if (rx & URXD_PRERR)
+			if (rx & URXD_BRK)
+				flg = TTY_BREAK;
+			else if (rx & URXD_PRERR)
 				flg = TTY_PARITY;
 			else if (rx & URXD_FRMERR)
 				flg = TTY_FRAME;
Signature · 1 line
1.7.7
#25 lore raw

PATCH 25/79 atmel_serial: RS485: receiving enabled when sending data

In reply to Greg Kroah-Hartman

From: Bernhard Roth <[email protected]>

By default the atmel_serial driver in RS485 mode disables receiving data until all data in the send buffer has been sent. This flag allows to receive data even whilst sending data.

---
 Documentation/serial/serial-rs485.txt |    3 +++
 drivers/tty/serial/atmel_serial.c     |    9 ++++++---
 include/linux/serial.h                |    1 +
 3 files changed, 10 insertions(+), 3 deletions(-)
Documentation/serial/serial-rs485.txt +3 -0
index a493238..c8878f8 100644
@@ -104,6 +104,9 @@
 	rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
 	rs485conf.delay_rts_after_send = ...;
 
+	/* Set this flag if you want to receive data even whilst sending data */
+	rs485conf.flags |= SER_RS485_RX_DURING_TX;
+
 	if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
 		/* Error handling. See errno. */
 	}
drivers/tty/serial/atmel_serial.c +6 -3
index af9b781..c7232a9 100644
@@ -339,7 +339,8 @@ static void atmel_stop_tx(struct uart_port *port)
 	/* Disable interrupts */
 	UART_PUT_IDR(port, atmel_port->tx_done_mask);
 
-	if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+	if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
+	    !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX))
 		atmel_start_rx(port);
 }
 
@@ -356,7 +357,8 @@ static void atmel_start_tx(struct uart_port *port)
 			   really need this.*/
 			return;
 
-		if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+		if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
+		    !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX))
 			atmel_stop_rx(port);
 
 		/* re-enable PDC transmit */
@@ -680,7 +682,8 @@ static void atmel_tx_dma(struct uart_port *port)
 		/* Enable interrupts */
 		UART_PUT_IER(port, atmel_port->tx_done_mask);
 	} else {
-		if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+		if ((atmel_port->rs485.flags & SER_RS485_ENABLED) &&
+		    !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) {
 			/* DMA done, stop TX, start RX for RS485 */
 			atmel_start_rx(port);
 		}
include/linux/serial.h +1 -0
index ef91406..97ff8e2 100644
@@ -211,6 +211,7 @@ struct serial_rs485 {
 #define SER_RS485_RTS_ON_SEND		(1 << 1)
 #define SER_RS485_RTS_AFTER_SEND	(1 << 2)
 #define SER_RS485_RTS_BEFORE_SEND	(1 << 3)
+#define SER_RS485_RX_DURING_TX		(1 << 4)
 	__u32	delay_rts_before_send;	/* Milliseconds */
 	__u32	delay_rts_after_send;	/* Milliseconds */
 	__u32	padding[5];		/* Memory is cheap, new structs
Signature · 1 line
1.7.7
#26 lore raw

PATCH 26/79 tty: Add support serial for EXYNOS4212 SoC

In reply to Greg Kroah-Hartman

From: Kukjin Kim <[email protected]>

According to add support EXYNOS4212 SoC, we need to enable SERIAL_S5PV210 on EXYNOS4212.

---
 drivers/tty/serial/Kconfig |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/Kconfig +2 -2
index a9b307f..10babe2 100644
@@ -522,8 +522,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 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
+	select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
 	default y
 	help
 	  Serial port support for Samsung's S5P Family of SoC's
Signature · 1 line
1.7.7
#27 lore raw

PATCH 27/79 jsm: remove remaining flip buffer code

In reply to Greg Kroah-Hartman

From: Thadeu Lima de Souza Cascardo <[email protected]>

The flip buffer is not used anymore. Remove its allocation and declaration in the board structure.

---
 drivers/tty/serial/jsm/jsm.h        |    3 ---
 drivers/tty/serial/jsm/jsm_driver.c |   18 ------------------
 2 files changed, 0 insertions(+), 21 deletions(-)
drivers/tty/serial/jsm/jsm.h +0 -3
index b704c8c..cd53bdd 100644
@@ -88,7 +88,6 @@ enum {
 
 /* 4 extra for alignment play space */
 #define WRITEBUFLEN	((4096) + 4)
-#define MYFLIPLEN	N_TTY_BUF_SIZE
 
 #define JSM_VERSION	"jsm: 1.2-1-INKERNEL"
 #define JSM_PARTNUM	"40002438_A-INKERNEL"
@@ -150,7 +149,6 @@ struct jsm_board
 	u32		bd_uart_offset;	/* Space between each UART */
 
 	struct jsm_channel *channels[MAXPORTS]; /* array of pointers to our channels. */
-	char		*flipbuf;	/* Our flip buffer, alloced if board is found */
 
 	u32		bd_dividend;	/* Board/UARTs specific dividend */
 
@@ -177,7 +175,6 @@ struct jsm_board
 #define CH_TX_FIFO_LWM	0x0800		/* TX Fifo is below Low Water	*/
 #define CH_BREAK_SENDING 0x1000		/* Break is being sent		*/
 #define CH_LOOPBACK 0x2000		/* Channel is in lookback mode	*/
-#define CH_FLIPBUF_IN_USE 0x4000	/* Channel's flipbuf is in use	*/
 #define CH_BAUD0	0x08000		/* Used for checking B0 transitions */
 
 /* Our Read/Error/Write queue sizes */
drivers/tty/serial/jsm/jsm_driver.c +0 -18
index 96da178..1cc8cf6 100644
@@ -160,27 +160,10 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
 	dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n",
 			adapter_count, brd->rev, brd->irq);
 
-	/*
-	 * allocate flip buffer for board.
-	 *
-	 * Okay to malloc with GFP_KERNEL, we are not at interrupt
-	 * context, and there are no locks held.
-	 */
-	brd->flipbuf = kzalloc(MYFLIPLEN, GFP_KERNEL);
-	if (!brd->flipbuf) {
-		/* XXX: leaking all resources from jsm_tty_init and
-		 	jsm_uart_port_init here! */
-		dev_err(&pdev->dev, "memory allocation for flipbuf failed\n");
-		rc = -ENOMEM;
-		goto out_free_uart;
-	}
-
 	pci_set_drvdata(pdev, brd);
 	pci_save_state(pdev);
 
 	return 0;
- out_free_uart:
-	jsm_remove_uart_port(brd);
  out_free_irq:
 	jsm_remove_uart_port(brd);
 	free_irq(brd->irq, brd);
@@ -218,7 +201,6 @@ static void __devexit jsm_remove_one(struct pci_dev *pdev)
 
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
-	kfree(brd->flipbuf);
 	kfree(brd);
 }
 
Signature · 1 line
1.7.7
#28 lore raw

PATCH 28/79 jsm: remove buggy write queue

In reply to Greg Kroah-Hartman

From: Thadeu Lima de Souza Cascardo <[email protected]>

jsm uses a write queue that copies from uart_core circular buffer. This copying however has some bugs, like not wrapping the head counter. Since this write queue is also a circular buffer, the consumer function is ready to use the uart_core circular buffer directly.

This buggy copying function was making some bytes be dropped when transmitting to a raw tty, doing something like this.

[root@hostname ~]$ cat /dev/ttyn1 > cascardo/dump &
[1] 2658
[root@hostname ~]$ cat /proc/tty/drivers > /dev/ttyn0 [root@hostname ~]$ 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
jsm                  /dev/ttyn     250 0-31 serial
serial               /dev/ttyS       4 64-95 serial
hvc                  /dev/hvc      229 0-7 system
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
[root@hostname ~]$ cat cascardo/dump
/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:vtmaste[root@hostname ~]$

This patch drops the driver write queue entirely, using the circular buffer from uart_core only.

---
 drivers/tty/serial/jsm/jsm.h        |    7 ---
 drivers/tty/serial/jsm/jsm_driver.c |    1 -
 drivers/tty/serial/jsm/jsm_neo.c    |   29 ++++++-----
 drivers/tty/serial/jsm/jsm_tty.c    |   94 +++++------------------------------
 4 files changed, 28 insertions(+), 103 deletions(-)
drivers/tty/serial/jsm/jsm.h +0 -7
index cd53bdd..529bec6 100644
@@ -180,10 +180,8 @@ struct jsm_board
 /* Our Read/Error/Write queue sizes */
 #define RQUEUEMASK	0x1FFF		/* 8 K - 1 */
 #define EQUEUEMASK	0x1FFF		/* 8 K - 1 */
-#define WQUEUEMASK	0x0FFF		/* 4 K - 1 */
 #define RQUEUESIZE	(RQUEUEMASK + 1)
 #define EQUEUESIZE	RQUEUESIZE
-#define WQUEUESIZE	(WQUEUEMASK + 1)
 
 
 /************************************************************************
@@ -223,10 +221,6 @@ struct jsm_channel {
 	u16		ch_e_head;	/* Head location of the error queue */
 	u16		ch_e_tail;	/* Tail location of the error queue */
 
-	u8		*ch_wqueue;	/* Our write queue buffer - malloc'ed */
-	u16		ch_w_head;	/* Head location of the write queue */
-	u16		ch_w_tail;	/* Tail location of the write queue */
-
 	u64		ch_rxcount;	/* total of data received so far */
 	u64		ch_txcount;	/* total of data transmitted so far */
 
@@ -375,7 +369,6 @@ extern int	jsm_debug;
  * Prototypes for non-static functions used in more than one module
  *
  *************************************************************************/
-int jsm_tty_write(struct uart_port *port);
 int jsm_tty_init(struct jsm_board *);
 int jsm_uart_port_init(struct jsm_board *);
 int jsm_remove_uart_port(struct jsm_board *);
drivers/tty/serial/jsm/jsm_driver.c +0 -1
index 1cc8cf6..648b6a3 100644
@@ -194,7 +194,6 @@ static void __devexit jsm_remove_one(struct pci_dev *pdev)
 		if (brd->channels[i]) {
 			kfree(brd->channels[i]->ch_rqueue);
 			kfree(brd->channels[i]->ch_equeue);
-			kfree(brd->channels[i]->ch_wqueue);
 			kfree(brd->channels[i]);
 		}
 	}
drivers/tty/serial/jsm/jsm_neo.c +15 -14
index 4538c3e..bd6e846 100644
@@ -496,12 +496,15 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 	int s;
 	int qlen;
 	u32 len_written = 0;
+	struct circ_buf *circ;
 
 	if (!ch)
 		return;
 
+	circ = &ch->uart_port.state->xmit;
+
 	/* No data to write to the UART */
-	if (ch->ch_w_tail == ch->ch_w_head)
+	if (uart_circ_empty(circ))
 		return;
 
 	/* If port is "stopped", don't send any data to the UART */
@@ -517,11 +520,10 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 		if (ch->ch_cached_lsr & UART_LSR_THRE) {
 			ch->ch_cached_lsr &= ~(UART_LSR_THRE);
 
-			writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx);
+			writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx);
 			jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev,
-					"Tx data: %x\n", ch->ch_wqueue[ch->ch_w_head]);
-			ch->ch_w_tail++;
-			ch->ch_w_tail &= WQUEUEMASK;
+					"Tx data: %x\n", circ->buf[circ->head]);
+			circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1);
 			ch->ch_txcount++;
 		}
 		return;
@@ -536,36 +538,36 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 	n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel;
 
 	/* cache head and tail of queue */
-	head = ch->ch_w_head & WQUEUEMASK;
-	tail = ch->ch_w_tail & WQUEUEMASK;
-	qlen = (head - tail) & WQUEUEMASK;
+	head = circ->head & (UART_XMIT_SIZE - 1);
+	tail = circ->tail & (UART_XMIT_SIZE - 1);
+	qlen = uart_circ_chars_pending(circ);
 
 	/* Find minimum of the FIFO space, versus queue length */
 	n = min(n, qlen);
 
 	while (n > 0) {
 
-		s = ((head >= tail) ? head : WQUEUESIZE) - tail;
+		s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail;
 		s = min(s, n);
 
 		if (s <= 0)
 			break;
 
-		memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s);
+		memcpy_toio(&ch->ch_neo_uart->txrxburst, circ->buf + tail, s);
 		/* Add and flip queue if needed */
-		tail = (tail + s) & WQUEUEMASK;
+		tail = (tail + s) & (UART_XMIT_SIZE - 1);
 		n -= s;
 		ch->ch_txcount += s;
 		len_written += s;
 	}
 
 	/* Update the final tail */
-	ch->ch_w_tail = tail & WQUEUEMASK;
+	circ->tail = tail & (UART_XMIT_SIZE - 1);
 
 	if (len_written >= ch->ch_t_tlevel)
 		ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 
-	if (!jsm_tty_write(&ch->uart_port))
+	if (uart_circ_empty(circ))
 		uart_write_wakeup(&ch->uart_port);
 }
 
@@ -946,7 +948,6 @@ static void neo_param(struct jsm_channel *ch)
 	if ((ch->ch_c_cflag & (CBAUD)) == 0) {
 		ch->ch_r_head = ch->ch_r_tail = 0;
 		ch->ch_e_head = ch->ch_e_tail = 0;
-		ch->ch_w_head = ch->ch_w_tail = 0;
 
 		neo_flush_uart_write(ch);
 		neo_flush_uart_read(ch);
drivers/tty/serial/jsm/jsm_tty.c +13 -81

115 lines not on this page · raw message

Signature · 1 line
1.7.7
#29 lore raw

PATCH 29/79 jsm: print byte we are dequeing

In reply to Greg Kroah-Hartman

From: Thadeu Lima de Souza Cascardo <[email protected]>

Instead of printing the head of the buffer, we should print the tail, which is the byte we are sending to the device.

---
 drivers/tty/serial/jsm/jsm_neo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/serial/jsm/jsm_neo.c +1 -1
index bd6e846..81dfafa 100644
@@ -522,7 +522,7 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 
 			writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx);
 			jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev,
-					"Tx data: %x\n", circ->buf[circ->head]);
+					"Tx data: %x\n", circ->buf[circ->tail]);
 			circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1);
 			ch->ch_txcount++;
 		}
Signature · 1 line
1.7.7
#30 lore raw

PATCH 30/79 TTY: serial, use ASYNCB_CLOSING in uart_close

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

We need to move port->mutex locking after wait_until_sent in uart_close (for rationale see next patches). But if we did it now, we would introduce a race between close and open. This is exactly why port->mutex is locked at the top of uart_close.

To avoid the race, we add ASYNCB_CLOSING to uart_close. Like every other sane TTY driver. Thanks to tty_port_block_til_ready used in uart_open we will have this for free. Then we can move the port->mutex lock.

Also note that this will make the conversion to tty_port helpers easier. They are currently handling ASYNC_CLOSING flag correctly.

---
 drivers/tty/serial/serial_core.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/tty/serial/serial_core.c +3 -0
index 3844980..849bd0d 100644
@@ -1288,6 +1288,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	 * the line discipline to only process XON/XOFF characters by
 	 * setting tty->closing.
 	 */
+	set_bit(ASYNCB_CLOSING, &port->flags);
 	tty->closing = 1;
 	spin_unlock_irqrestore(&port->lock, flags);
 
@@ -1335,8 +1336,10 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	 * Wake up anyone trying to open this port.
 	 */
 	clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
+	clear_bit(ASYNCB_CLOSING, &port->flags);
 	spin_unlock_irqrestore(&port->lock, flags);
 	wake_up_interruptible(&port->open_wait);
+	wake_up_interruptible(&port->close_wait);
 
 done:
 	mutex_unlock(&port->mutex);
Signature · 1 line
1.7.7
#31 lore raw

PATCH 31/79 TTY: serial, move locking in uart_close

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

So now, when we handle CLOSING flag, there is no point to hold port->mutex over the start of uart_close.

Yes, there are still several things to reason about:
* port->count etc is and always was protected by a spinlock
* ->stop_rx is protected by a spinlock. Otherwise it would race with interrupts.
* uart_wait_until_sent -- that one is already called without port->mutex from set_termios and tty_set_ldisc. Should anything be protected there, it would be tx_empty. And by a spinlock. 8250 does this internally...

This step is needed to fix system stalls. To not create an AB-BA lock dependency (see next patches).

---
 drivers/tty/serial/serial_core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/serial/serial_core.c +1 -1
index 849bd0d..0464360 100644
@@ -1253,7 +1253,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 
 	pr_debug("uart_close(%d) called\n", uport->line);
 
-	mutex_lock(&port->mutex);
 	spin_lock_irqsave(&port->lock, flags);
 
 	if (tty_hung_up_p(filp)) {
@@ -1312,6 +1311,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 		uart_wait_until_sent(tty, uport->timeout);
 	}
 
+	mutex_lock(&port->mutex);
 	uart_shutdown(tty, state);
 	uart_flush_buffer(tty);
 
Signature · 1 line
1.7.7
#32 lore raw

PATCH 32/79 TTY: define tty_wait_until_sent_from_close

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

We need this helper to fix system stalls. The issue is that the rest of the system TTYs wait for us to finish waiting. This wasn't an issue with BKL. BKL used to unlock implicitly.

This is based on the Arnd suggestion.

---
 include/linux/tty.h |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
include/linux/tty.h +18 -0
index 6d5eceb..0ad6888 100644
@@ -602,6 +602,24 @@ extern void __lockfunc tty_lock(void) __acquires(tty_lock);
 extern void __lockfunc tty_unlock(void) __releases(tty_lock);
 
 /*
+ * this shall be called only from where BTM is held (like close)
+ *
+ * We need this to ensure nobody waits for us to finish while we are waiting.
+ * Without this we were encountering system stalls.
+ *
+ * This should be indeed removed with BTM removal later.
+ *
+ * Locking: BTM required. Nobody is allowed to hold port->mutex.
+ */
+static inline void tty_wait_until_sent_from_close(struct tty_struct *tty,
+		long timeout)
+{
+	tty_unlock(); /* tty->ops->close holds the BTM, drop it while waiting */
+	tty_wait_until_sent(tty, timeout);
+	tty_lock();
+}
+
+/*
  * wait_event_interruptible_tty -- wait for a condition with the tty lock held
  *
  * The condition we are waiting for might take a long time to
Signature · 1 line
1.7.7
#33 lore raw

PATCH 33/79 TTY: use tty_wait_until_sent_from_close in tty_port_close_start

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

Let's use the newly added helper to avoid stalls in drivers which are already ported to tty_port helpers.

We have to ensure here, that there is no user of tty_port_close_start and tty_port_close which holds port->mutex (or other) lock over them. And sure, there is none.

---
 drivers/tty/tty_port.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/tty_port.c +1 -1
index 33d37d2..ef9dd62 100644
@@ -350,7 +350,7 @@ int tty_port_close_start(struct tty_port *port,
 		tty_driver_flush_buffer(tty);
 	if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
 			port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, port->closing_wait);
+		tty_wait_until_sent_from_close(tty, port->closing_wait);
 	if (port->drain_delay) {
 		unsigned int bps = tty_get_baud_rate(tty);
 		long timeout;
Signature · 1 line
1.7.7
#34 lore raw

PATCH 34/79 TTY: use tty_wait_until_sent_from_close in other drivers

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

Let's use the newly added helper to avoid stalls in drivers which are not yet ported to tty_port helpers.

Those which are broken (call tty_wait_until_sent with irqs disabled) are left untouched. They are in a deeper trouble than we are trying to solve here. This includes amiserial, 68328serial, 68360serial and crisv10.

---
 drivers/isdn/i4l/isdn_tty.c      |    2 +-
 drivers/tty/hvc/hvc_console.c    |    2 +-
 drivers/tty/hvc/hvcs.c           |    2 +-
 drivers/tty/serial/serial_core.c |    3 ++-
 net/irda/ircomm/ircomm_tty.c     |    2 +-
 5 files changed, 6 insertions(+), 5 deletions(-)
drivers/isdn/i4l/isdn_tty.c +1 -1
index d850427..e5546cb 100644
@@ -1693,7 +1693,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 	 * line status register.
 	 */
 	if (info->flags & ISDN_ASYNC_INITIALIZED) {
-		tty_wait_until_sent(tty, 3000);	/* 30 seconds timeout */
+		tty_wait_until_sent_from_close(tty, 3000);	/* 30 seconds timeout */
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
 		 * has completely drained; this is especially
drivers/tty/hvc/hvc_console.c +1 -1
index e1aaf4f..b6b2d18 100644
@@ -388,7 +388,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
 		 * there is no buffered data otherwise sleeps on a wait queue
 		 * waking periodically to check chars_in_buffer().
 		 */
-		tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
+		tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT);
 	} else {
 		if (hp->count < 0)
 			printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
drivers/tty/hvc/hvcs.c +1 -1
index 4c8b665..e523773 100644
@@ -1237,7 +1237,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 		irq = hvcsd->vdev->irq;
 		spin_unlock_irqrestore(&hvcsd->lock, flags);
 
-		tty_wait_until_sent(tty, HVCS_CLOSE_WAIT);
+		tty_wait_until_sent_from_close(tty, HVCS_CLOSE_WAIT);
 
 		/*
 		 * This line is important because it tells hvcs_open that this
drivers/tty/serial/serial_core.c +2 -1
index 0464360..1d3780c 100644
@@ -1292,7 +1292,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
+		tty_wait_until_sent_from_close(tty,
+				msecs_to_jiffies(port->closing_wait));
 
 	/*
 	 * At this point, we stop accepting input.  To do this, we
net/irda/ircomm/ircomm_tty.c +1 -1
index b3cc8b3..253695d 100644
@@ -551,7 +551,7 @@ static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 	 */
 	tty->closing = 1;
 	if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, self->closing_wait);
+		tty_wait_until_sent_from_close(tty, self->closing_wait);
 
 	ircomm_tty_shutdown(self);
 
Signature · 1 line
1.7.7
#35 lore raw

PATCH 35/79 hsu: add runtime pm support

In reply to Greg Kroah-Hartman

From: Kristen Carlson Accardi <[email protected]>

Doesn't appear to be much to do here, however having the suspend/resume functions will allow the d3/d0 transitions to be sent by the pci core.

---
 drivers/tty/serial/mfd.c |   47 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)
drivers/tty/serial/mfd.c +47 -0
index cab52f4..cfa7501 100644
@@ -38,6 +38,7 @@
 #include <linux/pci.h>
 #include <linux/io.h>
 #include <linux/debugfs.h>
+#include <linux/pm_runtime.h>
 
 #define HSU_DMA_BUF_SIZE	2048
 
@@ -764,6 +765,8 @@ static int serial_hsu_startup(struct uart_port *port)
 		container_of(port, struct uart_hsu_port, port);
 	unsigned long flags;
 
+	pm_runtime_get_sync(up->dev);
+
 	/*
 	 * Clear the FIFO buffers and disable them.
 	 * (they will be reenabled in set_termios())
@@ -871,6 +874,8 @@ static void serial_hsu_shutdown(struct uart_port *port)
 				  UART_FCR_CLEAR_RCVR |
 				  UART_FCR_CLEAR_XMIT);
 	serial_out(up, UART_FCR, 0);
+
+	pm_runtime_put(up->dev);
 }
 
 static void
@@ -1249,6 +1254,39 @@ static int serial_hsu_resume(struct pci_dev *pdev)
 #define serial_hsu_resume	NULL
 #endif
 
+#ifdef CONFIG_PM_RUNTIME
+static int serial_hsu_runtime_idle(struct device *dev)
+{
+	int err;
+
+	err = pm_schedule_suspend(dev, 500);
+	if (err)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int serial_hsu_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int serial_hsu_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+#else
+#define serial_hsu_runtime_idle		NULL
+#define serial_hsu_runtime_suspend	NULL
+#define serial_hsu_runtime_resume	NULL
+#endif
+
+static const struct dev_pm_ops serial_hsu_pm_ops = {
+	.runtime_suspend = serial_hsu_runtime_suspend,
+	.runtime_resume = serial_hsu_runtime_resume,
+	.runtime_idle = serial_hsu_runtime_idle,
+};
+
 /* temp global pointer before we settle down on using one or four PCI dev */
 static struct hsu_port *phsu;
 
@@ -1315,6 +1353,9 @@ static int serial_hsu_probe(struct pci_dev *pdev,
 		pci_set_drvdata(pdev, uport);
 	}
 
+	pm_runtime_put_noidle(&pdev->dev);
+	pm_runtime_allow(&pdev->dev);
+
 	return 0;
 
 err_disable:
@@ -1411,6 +1452,9 @@ static void serial_hsu_remove(struct pci_dev *pdev)
 	if (!priv)
 		return;
 
+	pm_runtime_forbid(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
+
 	/* For port 0/1/2, priv is the address of uart_hsu_port */
 	if (pdev->device != 0x081E) {
 		up = priv;
@@ -1438,6 +1482,9 @@ static struct pci_driver hsu_pci_driver = {
 	.remove =	__devexit_p(serial_hsu_remove),
 	.suspend =	serial_hsu_suspend,
 	.resume	=	serial_hsu_resume,
+	.driver = {
+		.pm = &serial_hsu_pm_ops,
+	},
 };
 
 static int __init hsu_pci_init(void)
Signature · 1 line
1.7.7
#36 lore raw

PATCH 36/79 n_gsm: update TODO list

In reply to Greg Kroah-Hartman

From: Alan Cox <[email protected]>

This is now out of date so fix it

---
 drivers/tty/n_gsm.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/tty/n_gsm.c +0 -1
index 8a50e4e..ed42908 100644
@@ -21,7 +21,6 @@
  *	Mostly done:	ioctls for setting modes/timing
  *	Partly done:	hooks so you can pull off frames to non tty devs
  *	Restart DLCI 0 when it closes ?
- *	Test basic encoding
  *	Improve the tx engine
  *	Resolve tx side locking by adding a queue_head and routing
  *		all control traffic via it
Signature · 1 line
1.7.7
#37 lore raw

PATCH 37/79 n_gsm: Send CLD command on exit

In reply to Greg Kroah-Hartman

From: Alan Cox <[email protected]>

A DISC on DLCI 0 should close down the mux but Michael Lauer reports this is not the case for some modems. Send a CLD as well.

Tested-by Michael Lauer
---
 drivers/tty/n_gsm.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
drivers/tty/n_gsm.c +8 -0
index ed42908..8d7766b 100644
@@ -2003,6 +2003,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm)
 	int i;
 	struct gsm_dlci *dlci = gsm->dlci[0];
 	struct gsm_msg *txq;
+	struct gsm_control *gc;
 
 	gsm->dead = 1;
 
@@ -2016,6 +2017,13 @@ void gsm_cleanup_mux(struct gsm_mux *gsm)
 	spin_unlock(&gsm_mux_lock);
 	WARN_ON(i == MAX_MUX);
 
+	/* In theory disconnecting DLCI 0 is sufficient but for some
+	   modems this is apparently not the case. */
+	if (dlci) {
+		gc = gsm_control_send(gsm, CMD_CLD, NULL, 0);
+		if (gc)
+			gsm_control_wait(gsm, gc);
+	}
 	del_timer_sync(&gsm->t2_timer);
 	/* Now we are sure T2 has stopped */
 	if (dlci) {
Signature · 1 line
1.7.7
#38 lore raw

PATCH 38/79 max3110: wake up fixes

In reply to Greg Kroah-Hartman

From: Dirk Brandewie <[email protected]>

The main thread is waiting on on a wait_queue but wake_up_process() is used to wake the thread. This reads weirdly. Change wake_up_process() to wake_up().

Tested on the Moorestown tablet build

---
 drivers/tty/serial/mrst_max3110.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
drivers/tty/serial/mrst_max3110.c +7 -4
index a764bf9..c8f9868 100644
@@ -207,7 +207,7 @@ static void serial_m3110_con_write(struct console *co,
 	uart_console_write(&pmax->port, s, count, serial_m3110_con_putchar);
 
 	if (!test_and_set_bit(CON_TX_NEEDED, &pmax->uart_flags))
-		wake_up_process(pmax->main_thread);
+		wake_up(&pmax->wq);
 }
 
 static int __init
@@ -301,6 +301,7 @@ static void send_circ_buf(struct uart_max3110 *max,
 			}
 
 			/* Fail to send msg to console is not very critical */
+
 			ret = max3110_write_then_read(max, obuf, ibuf, blen, 0);
 			if (ret)
 				pr_warning(PR_FMT "%s(): get err msg %d\n",
@@ -349,7 +350,7 @@ static void serial_m3110_start_tx(struct uart_port *port)
 		container_of(port, struct uart_max3110, port);
 
 	if (!test_and_set_bit(UART_TX_NEEDED, &max->uart_flags))
-		wake_up_process(max->main_thread);
+		wake_up(&max->wq);
 }
 
 static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
@@ -424,7 +425,8 @@ static int max3110_main_thread(void *_max)
 	pr_info(PR_FMT "start main thread\n");
 
 	do {
-		wait_event_interruptible(*wq, max->uart_flags || kthread_should_stop());
+		wait_event_interruptible(*wq,
+				max->uart_flags || kthread_should_stop());
 
 		mutex_lock(&max->thread_mutex);
 
@@ -452,8 +454,9 @@ static irqreturn_t serial_m3110_irq(int irq, void *dev_id)
 
 	/* max3110's irq is a falling edge, not level triggered,
 	 * so no need to disable the irq */
+
 	if (!test_and_set_bit(BIT_IRQ_PENDING, &max->uart_flags))
-		wake_up_process(max->main_thread);
+		wake_up(&max->wq);
 
 	return IRQ_HANDLED;
 }
Signature · 1 line
1.7.7
#39 lore raw

PATCH 39/79 x86/mrst: Add platform data for Max3110 devices

In reply to Greg Kroah-Hartman

From: Feng Tang <[email protected]>

Those info will be used when spi controller driver setup max3110 as a slave device

---
 arch/x86/platform/mrst/mrst.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
arch/x86/platform/mrst/mrst.c +3 -0
index 7000e74..b8da1b9 100644
@@ -14,6 +14,8 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/scatterlist.h>
 #include <linux/sfi.h>
 #include <linux/intel_pmic_gpio.h>
 #include <linux/spi/spi.h>
@@ -392,6 +394,7 @@ static void __init *max3111_platform_data(void *info)
 	struct spi_board_info *spi_info = info;
 	int intr = get_gpio_by_name("max3111_int");
 
+	spi_info->mode = SPI_MODE_0;
 	if (intr == -1)
 		return NULL;
 	spi_info->irq = intr + MRST_IRQ_OFFSET;
Signature · 1 line
1.7.7
#40 lore raw

PATCH 40/79 max3110: add sysrq support

In reply to Greg Kroah-Hartman

From: Alexander Shishkin <[email protected]>

This patch moves several occurences of similar code inside receive_chars(), which now also takes care of checking for break and calling sysrq handling code.

---
 drivers/tty/serial/mrst_max3110.c |   99 ++++++++++++++++---------------------
 drivers/tty/serial/mrst_max3110.h |    1 +
 2 files changed, 44 insertions(+), 56 deletions(-)
drivers/tty/serial/mrst_max3110.c +43 -56
index c8f9868..42aa439 100644
@@ -27,6 +27,10 @@
  *    interrupt for a low speed UART device
  */
 
+#ifdef CONFIG_MAGIC_SYSRQ
+#define SUPPORT_SYSRQ
+#endif
+
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -73,9 +77,9 @@ struct uart_max3110 {
 /* global data structure, may need be removed */
 static struct uart_max3110 *pmax;
 
-static void receive_chars(struct uart_max3110 *max,
-				unsigned char *str, int len);
-static int max3110_read_multi(struct uart_max3110 *max, u8 *buf);
+static int receive_chars(struct uart_max3110 *max,
+				unsigned short *str, int len);
+static int max3110_read_multi(struct uart_max3110 *max);
 static void max3110_con_receive(struct uart_max3110 *max);
 
 static int max3110_write_then_read(struct uart_max3110 *max,
@@ -108,7 +112,6 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
 {
 	void *buf;
 	u16 *obuf, *ibuf;
-	u8  ch;
 	int ret;
 
 	buf = kzalloc(8, GFP_KERNEL | GFP_DMA);
@@ -125,11 +128,7 @@ static int max3110_out(struct uart_max3110 *max, const u16 out)
 		goto exit;
 	}
 
-	/* If some valid data is read back */
-	if (*ibuf & MAX3110_READ_DATA_AVAILABLE) {
-		ch = *ibuf & 0xff;
-		receive_chars(max, &ch, 1);
-	}
+	receive_chars(max, ibuf, 1);
 
 exit:
 	kfree(buf);
@@ -142,12 +141,11 @@ exit:
  *
  * Return how many valide bytes are read back
  */
-static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf)
+static int max3110_read_multi(struct uart_max3110 *max)
 {
 	void *buf;
 	u16 *obuf, *ibuf;
-	u8 *pbuf, valid_str[M3110_RX_FIFO_DEPTH];
-	int i, j, blen;
+	int ret, blen;
 
 	blen = M3110_RX_FIFO_DEPTH * sizeof(u16);
 	buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA);
@@ -165,19 +163,10 @@ static int max3110_read_multi(struct uart_max3110 *max, u8 *rxbuf)
 		return 0;
 	}
 
-	/* If caller doesn't provide a buffer, then handle received char */
-	pbuf = rxbuf ? rxbuf : valid_str;
-
-	for (i = 0, j = 0; i < M3110_RX_FIFO_DEPTH; i++) {
-		if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
-			pbuf[j++] = ibuf[i] & 0xff;
-	}
-
-	if (j && (pbuf == valid_str))
-		receive_chars(max, valid_str, j);
+	ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH);
 
 	kfree(buf);
-	return j;
+	return ret;
 }
 
 static void serial_m3110_con_putchar(struct uart_port *port, int ch)
@@ -276,8 +265,7 @@ static void send_circ_buf(struct uart_max3110 *max,
 {
 	void *buf;
 	u16 *obuf, *ibuf;
-	u8 valid_str[WORDS_PER_XFER];
-	int i, j, len, blen, dma_size, left, ret = 0;
+	int i, len, blen, dma_size, left, ret = 0;
 
 
 	dma_size = WORDS_PER_XFER * sizeof(u16) * 2;
@@ -307,13 +295,7 @@ static void send_circ_buf(struct uart_max3110 *max,
 				pr_warning(PR_FMT "%s(): get err msg %d\n",
 						__func__, ret);
 
-			for (i = 0, j = 0; i < len; i++) {
-				if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
-					valid_str[j++] = ibuf[i] & 0xff;
-			}
-
-			if (j)
-				receive_chars(max, valid_str, j);
+			receive_chars(max, ibuf, len);
 
 			max->port.icount.tx += len;
 			left -= len;
@@ -353,30 +335,48 @@ static void serial_m3110_start_tx(struct uart_port *port)
 		wake_up(&max->wq);
 }
 
-static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
+static int
+receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
 {
 	struct uart_port *port = &max->port;
 	struct tty_struct *tty;
-	int usable;
+	char buf[M3110_RX_FIFO_DEPTH];
+	int r, w, usable;
 
 	/* If uart is not opened, just return */
 	if (!port->state)
-		return;
+		return 0;
 
 	tty = port->state->port.tty;
 	if (!tty)
-		return;
+		return 0;
+
+	for (r = 0, w = 0; r < len; r++) {
+		if (str[r] & MAX3110_BREAK &&
+		    uart_handle_break(port))
+			continue;
+
+		if (str[r] & MAX3110_READ_DATA_AVAILABLE) {
+			if (uart_handle_sysrq_char(port, str[r] & 0xff))
+				continue;
+
+			buf[w++] = str[r] & 0xff;
+		}
+	}
 
-	while (len) {
-		usable = tty_buffer_request_room(tty, len);
+	if (!w)
+		return 0;
+
+	for (r = 0; w; r += usable, w -= usable) {
+		usable = tty_buffer_request_room(tty, w);
 		if (usable) {
-			tty_insert_flip_string(tty, str, usable);
-			str += usable;
+			tty_insert_flip_string(tty, buf + r, usable);
 			port->icount.rx += usable;
 		}
-		len -= usable;
 	}
 	tty_flip_buffer_push(tty);
+
+	return r;
 }
 
 /*
@@ -391,28 +391,15 @@ static void receive_chars(struct uart_max3110 *max, unsigned char *str, int len)
  */
 static void max3110_con_receive(struct uart_max3110 *max)
 {
-	int loop = 1, num, total = 0;
-	u8 recv_buf[512], *pbuf;
+	int loop = 1, num;
 
-	pbuf = recv_buf;
 	do {
-		num = max3110_read_multi(max, pbuf);
+		num = max3110_read_multi(max);
 
 		if (num) {
 			loop = 5;
-			pbuf += num;
-			total += num;
-
-			if (total >= 504) {
-				receive_chars(max, recv_buf, total);
-				pbuf = recv_buf;
-				total = 0;
-			}
 		}
 	} while (--loop);
-
-	if (total)
-		receive_chars(max, recv_buf, total);
 }
 
 static int max3110_main_thread(void *_max)
drivers/tty/serial/mrst_max3110.h +1 -0
index c37ea48..35af073 100644
@@ -7,6 +7,7 @@
 /* status bits for all 4 MAX3110 operate modes */
 #define MAX3110_READ_DATA_AVAILABLE	(1 << 15)
 #define MAX3110_WRITE_BUF_EMPTY		(1 << 14)
+#define MAX3110_BREAK			(1 << 10)
 
 #define WC_TAG			(3 << 14)
 #define RC_TAG			(1 << 14)
Signature · 1 line
1.7.7
#41 lore raw

PATCH 41/79 max3110: Fix up port->tty backreferencing

In reply to Greg Kroah-Hartman

From: Alan Cox <[email protected]>

We want to keep refcounts properly on this against hangup.

---
 drivers/tty/serial/mrst_max3110.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)
drivers/tty/serial/mrst_max3110.c +5 -2
index 42aa439..1aa2c3c 100644
@@ -347,7 +347,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
 	if (!port->state)
 		return 0;
 
-	tty = port->state->port.tty;
+	tty = tty_port_tty_get(&port->state->port);
 	if (!tty)
 		return 0;
 
@@ -364,8 +364,10 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
 		}
 	}
 
-	if (!w)
+	if (!w) {
+		tty_kref_put(tty);
 		return 0;
+	}
 
 	for (r = 0; w; r += usable, w -= usable) {
 		usable = tty_buffer_request_room(tty, w);
@@ -375,6 +377,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len)
 		}
 	}
 	tty_flip_buffer_push(tty);
+	tty_kref_put(tty);
 
 	return r;
 }
Signature · 1 line
1.7.7
#42 lore raw

PATCH 42/79 tty/powerpc: fix build break with ehv_bytechan.c on allyesconfig

In reply to Greg Kroah-Hartman

From: Timur Tabi <[email protected]>

The ePAPR hypervisor byte channel driver is supposed to work on all ePAPR-compliant embedded PowerPC systems, but it had a reference to the MSR_GS bit, which is available only on Book-E systems.

Also fix a couple integer-to-pointer typecast problems.

---
 drivers/tty/ehv_bytechan.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)
drivers/tty/ehv_bytechan.c +2 -6
index e67f70b..f733718 100644
@@ -226,10 +226,6 @@ void __init udbg_init_ehv_bc(void)
 	unsigned int rx_count, tx_count;
 	unsigned int ret;
 
-	/* Check if we're running as a guest of a hypervisor */
-	if (!(mfmsr() & MSR_GS))
-		return;
-
 	/* Verify the byte channel handle */
 	ret = ev_byte_channel_poll(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE,
 				   &rx_count, &tx_count);
@@ -286,7 +282,7 @@ static int ehv_bc_console_byte_channel_send(unsigned int handle, const char *s,
 static void ehv_bc_console_write(struct console *co, const char *s,
 				 unsigned int count)
 {
-	unsigned int handle = (unsigned int)co->data;
+	unsigned int handle = (uintptr_t)co->data;
 	char s2[EV_BYTE_CHANNEL_MAX_BYTES];
 	unsigned int i, j = 0;
 	char c;
@@ -352,7 +348,7 @@ static int __init ehv_bc_console_init(void)
 			   CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
 #endif
 
-	ehv_bc_console.data = (void *)stdout_bc;
+	ehv_bc_console.data = (void *)(uintptr_t)stdout_bc;
 
 	/* add_preferred_console() must be called before register_console(),
 	   otherwise it won't work.  However, we don't want to enumerate all the
Signature · 1 line
1.7.7
#43 lore raw

PATCH 43/79 tty: 8250: export serial8250_handle_irq

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

Allow modules to use the normal 8250 irq handler inside their own.

---
 drivers/tty/serial/8250.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/tty/serial/8250.c +1 -0
index 6f594d2..435ce14 100644
@@ -1588,6 +1588,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(serial8250_handle_irq);
 
 static int serial8250_default_handle_irq(struct uart_port *port)
 {
Signature · 1 line
1.7.7
#44 lore raw

PATCH 44/79 tty: add a DesignWare 8250 driver

In reply to Greg Kroah-Hartman

From: Jamie Iles <[email protected]>

The Synopsys DesignWare 8250 is an 8250 that has an extra interrupt that gets raised when writing to the LCR when busy. To handle this we need special serial_out, serial_in and handle_irq methods. Add a new platform driver that uses these accessors.

---
 .../bindings/tty/serial/snps-dw-apb-uart.txt       |   25 +++
 drivers/tty/serial/8250_dw.c                       |  194 ++++++++++++++++++++
 drivers/tty/serial/Kconfig                         |    7 +
 drivers/tty/serial/Makefile                        |    1 +
 4 files changed, 227 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt
 create mode 100644 drivers/tty/serial/8250_dw.c
Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt new file +25 -0
new file mode 100644
index 0000000..f13f1c5
@@ -0,0 +1,25 @@
+* Synopsys DesignWare ABP UART
+
+Required properties:
+- compatible : "snps,dw-apb-uart"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain uart interrupt.
+- clock-frequency : the input clock frequency for the UART.
+
+Optional properties:
+- reg-shift : quantity to shift the register offsets by.  If this property is
+  not present then the register offsets are not shifted.
+- reg-io-width : the size (in bytes) of the IO accesses that should be
+  performed on the device.  If this property is not present then single byte
+  accesses are used.
+
+Example:
+
+	uart@80230000 {
+		compatible = "snps,dw-apb-uart";
+		reg = <0x80230000 0x100>;
+		clock-frequency = <3686400>;
+		interrupts = <10>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+	};
drivers/tty/serial/8250_dw.c new file +194 -0

194 lines not on this page · raw message

drivers/tty/serial/Kconfig +7 -0
index 10babe2..8ee3a66 100644
@@ -267,6 +267,13 @@ config SERIAL_8250_RM9K
 	  port hardware found on MIPS RM9122 and similar processors.
 	  If unsure, say N.
 
+config SERIAL_8250_DW
+	tristate "Support for Synopsys DesignWare 8250 quirks"
+	depends on SERIAL_8250 && OF
+	help
+	  Selecting this option will enable handling of the extra features
+	  present in the Synopsys DesignWare APB UART.
+
 comment "Non-8250 serial port support"
 
 config SERIAL_AMBA_PL010
drivers/tty/serial/Makefile +1 -0
index 7874813..7b59958 100644
@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
 obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o
 obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
 obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
Signature · 1 line
1.7.7
#45 lore raw

PATCH 45/79 serial: pxa: work around for errata #20

In reply to Greg Kroah-Hartman

From: Marcus Folkesson <[email protected]>

Errata E20: UART: Character Timeout interrupt remains set under certain software conditions.

Implication: The software servicing the UART can be trapped in an infinite loop.

---
 drivers/tty/serial/pxa.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)
drivers/tty/serial/pxa.c +20 -0
index 531931c..5c8e3bb 100644
@@ -100,6 +100,16 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status)
 	int max_count = 256;
 
 	do {
+		/* work around Errata #20 according to
+		 * Intel(R) PXA27x Processor Family
+		 * Specification Update (May 2005)
+		 *
+		 * Step 2
+		 * Disable the Reciever Time Out Interrupt via IER[RTOEI]
+		 */
+		up->ier &= ~UART_IER_RTOIE;
+		serial_out(up, UART_IER, up->ier);
+
 		ch = serial_in(up, UART_RX);
 		flag = TTY_NORMAL;
 		up->port.icount.rx++;
@@ -156,6 +166,16 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status)
 		*status = serial_in(up, UART_LSR);
 	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
 	tty_flip_buffer_push(tty);
+
+	/* work around Errata #20 according to
+	 * Intel(R) PXA27x Processor Family
+	 * Specification Update (May 2005)
+	 *
+	 * Step 6:
+	 * No more data in FIFO: Re-enable RTO interrupt via IER[RTOIE]
+	 */
+	up->ier |= UART_IER_RTOIE;
+	serial_out(up, UART_IER, up->ier);
 }
 
 static void transmit_chars(struct uart_pxa_port *up)
Signature · 1 line
1.7.7
#46 lore raw

PATCH 46/79 TTY: serial: Move mutex_unlock in uart_close function

In reply to Greg Kroah-Hartman

From: Nobuhiro Iwamatsu <[email protected]>

When mutex_lock is not called, mutex_unlock is sometimes called. This deletes unnecessary goto and makes modifications so that mutex_unlock is called.

[    8.304000] WARNING: at kernel/muex-debug.c:78
[    8.304000] Modules linked in:
[    8.304000]
[    8.304000] Pid : 114, Comm:                 modprobe
[    8.304000] CPU : 0                  Not tainted  (3.1.0-rc3-next-20110826 #810)
[    8.304000]
[    8.304000] PC is at debug_mutex_unlock+0xf4/0x120
[    8.304000] PR is at debug_mutex_unlock+0xe6/0x120
[    8.304000] PC  : 80051114 SP  : 9f02de58 SR  : 400081f1 TEA : 295cf4f2
[    8.304000] R0  : 00000001 R1  : 00000000 R2  : 0000000f R3  : 00000000
[    8.304000] R4  : 9fc63158 R5  : 00000000 R6  : 00000001 R7  : 9fe1de78
[    8.304000] R8  : 805c6b2c R9  : 80003920 R10 : 00000000 R11 : 805c6b2c
[    8.304000] R12 : 80425ca0 R13 : 00000000 R14 : 9f02de58
[    8.304000] MACH: 00000003 MACL: 00000000 GBR : 296e1678 PR  : 80051106
[    8.304000]
[    8.304000] Call trace:
[    8.304000]  [<804236c6>] __mutex_unlock_slowpath+0x46/0x120
[    8.304000]  [<804237aa>] mutex_unlock+0xa/0x20
[    8.304000]  [<80240ed6>] uart_close+0x76/0x2c0
[    8.304000]  [<80223b98>] tty_release+0xf8/0x5c0
[    8.304000]  [<800a93a6>] lookup_object+0x26/0xa0
[    8.304000]  [<80063f6a>] call_rcu+0x8a/0xc0
[    8.304000]  [<800a944a>] put_object+0x2a/0x60
[    8.304000]  [<80003920>] arch_local_irq_restore+0x0/0x40
[    8.304000]  [<800af320>] fput+0x180/0x2c0
[    8.304000]  [<800af248>] fput+0xa8/0x2c0
[    8.304000]  [<800ab1a8>] filp_close+0x48/0xc0
[    8.304000]  [<800ab29a>] sys_close+0x7a/0x100
[    8.304000]  [<8000825a>] syscall_call+0xc/0x10
[    8.304000]  [<800ab220>] sys_close+0x0/0x100
[    8.304000]
[    8.304000] Code:
[    8.304000]   8005110e:  mov.l     @r1, r1
[    8.304000]   80051110:  tst       r1, r1
[    8.304000]   80051112:  bf        80051116
[    8.304000] ->80051114:  trapa     #62
[    8.304000]   80051116:  mov.l     @r8, r1
[    8.304000]   80051118:  tst       r1, r1
[    8.304000]   8005111a:  bt.s      8005104c
[    8.304000]   8005111c:  mov       #0, r1
[    8.304000]   8005111e:  bra       80051056
[    8.304000]
[    8.304000] ---[ end trace e8f8e04c313f429b ]---
---
 drivers/tty/serial/serial_core.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
drivers/tty/serial/serial_core.c +2 -3
index 1d3780c..a32dc43 100644
@@ -1257,7 +1257,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 
 	if (tty_hung_up_p(filp)) {
 		spin_unlock_irqrestore(&port->lock, flags);
-		goto done;
+		return;
 	}
 
 	if ((tty->count == 1) && (port->count != 1)) {
@@ -1279,7 +1279,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	}
 	if (port->count) {
 		spin_unlock_irqrestore(&port->lock, flags);
-		goto done;
+		return;
 	}
 
 	/*
@@ -1342,7 +1342,6 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	wake_up_interruptible(&port->open_wait);
 	wake_up_interruptible(&port->close_wait);
 
-done:
 	mutex_unlock(&port->mutex);
 }
 
Signature · 1 line
1.7.7
#47 lore raw

PATCH 47/79 TTY: serial, remove dead code from 68328

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

The code is dead at least since 2002. So remove it to not distort git grep output (about port.tty usage).

Remove the whole do_softirq tasklet as it's noop now.

---
 drivers/tty/serial/68328serial.c |   35 -----------------------------------
 drivers/tty/serial/68328serial.h |    1 -
 2 files changed, 0 insertions(+), 36 deletions(-)
drivers/tty/serial/68328serial.c +0 -35
index e0a7754..f549231 100644
@@ -235,22 +235,6 @@ static void batten_down_hatches(void)
 
 static void status_handle(struct m68k_serial *info, unsigned short status)
 {
-#if 0
-	if(status & DCD) {
-		if((info->port.tty->termios->c_cflag & CRTSCTS) &&
-		   ((info->curregs[3] & AUTO_ENAB)==0)) {
-			info->curregs[3] |= AUTO_ENAB;
-			info->pendregs[3] |= AUTO_ENAB;
-			write_zsreg(info->m68k_channel, 3, info->curregs[3]);
-		}
-	} else {
-		if((info->curregs[3] & AUTO_ENAB)) {
-			info->curregs[3] &= ~AUTO_ENAB;
-			info->pendregs[3] &= ~AUTO_ENAB;
-			write_zsreg(info->m68k_channel, 3, info->curregs[3]);
-		}
-	}
-#endif
 	/* If this is console input and this is a
 	 * 'break asserted' status change interrupt
 	 * see if we can drop into the debugger
@@ -340,9 +324,6 @@ static void transmit_chars(struct m68k_serial *info)
 	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
 	info->xmit_cnt--;
 
-	if (info->xmit_cnt < WAKEUP_CHARS)
-		schedule_work(&info->tqueue);
-
 	if(info->xmit_cnt <= 0) {
 		/* All done for now... TX ints off */
 		uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
@@ -378,21 +359,6 @@ irqreturn_t rs_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void do_softint(struct work_struct *work)
-{
-	struct m68k_serial	*info = container_of(work, struct m68k_serial, tqueue);
-	struct tty_struct	*tty;
-	
-	tty = info->tty;
-	if (!tty)
-		return;
-#if 0
-	if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		tty_wakeup(tty);
-	}
-#endif   
-}
-
 static int startup(struct m68k_serial * info)
 {
 	m68328_uart *uart = &uart_addr[info->line];
@@ -1324,7 +1290,6 @@ rs68328_init(void)
 	    info->event = 0;
 	    info->count = 0;
 	    info->blocked_open = 0;
-	    INIT_WORK(&info->tqueue, do_softint);
 	    init_waitqueue_head(&info->open_wait);
 	    init_waitqueue_head(&info->close_wait);
 	    info->line = i;
drivers/tty/serial/68328serial.h +0 -1
index 8c9c3c0..3d2faab 100644
@@ -158,7 +158,6 @@ struct m68k_serial {
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
-	struct work_struct	tqueue;
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
 };
Signature · 1 line
1.7.7
#48 lore raw

Re: [PATCH 47/79] TTY: serial, remove dead code from 68328

m68knommu => Greg

Quoted 99 lines · Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

The code is dead at least since 2002. So remove it to not distort git grep output (about port.tty usage).

Remove the whole do_softirq tasklet as it's noop now.

---
 drivers/tty/serial/68328serial.c |   35 ----------------------------------- drivers/tty/serial/68328serial.h |    1 -

 2 files changed, 0 insertions(+), 36 deletions(-)
drivers/tty/serial/68328serial.c +0 -35
index e0a7754..f549231 100644
@@ -235,22 +235,6 @@ static void batten_down_hatches(void)
 
  static void status_handle(struct m68k_serial *info, unsigned short status)
  {
-#if 0
-       if(status & DCD) {
-               if((info->port.tty->termios->c_cflag & CRTSCTS) &&
-                  ((info->curregs[3] & AUTO_ENAB)==0)) {
-                       info->curregs[3] |= AUTO_ENAB;
-                       info->pendregs[3] |= AUTO_ENAB;
-                       write_zsreg(info->m68k_channel, 3, info->curregs[3]);
-               }
-       } else {
-               if((info->curregs[3] & AUTO_ENAB)) {
-                       info->curregs[3] &= ~AUTO_ENAB;
-                       info->pendregs[3] &= ~AUTO_ENAB;
-                       write_zsreg(info->m68k_channel, 3, info->curregs[3]);
-               }
-       }
-#endif
        /* If this is console input and this is a
         * 'break asserted' status change interrupt
         * see if we can drop into the debugger
@@ -340,9 +324,6 @@ static void transmit_chars(struct m68k_serial *info)
        info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
        info->xmit_cnt--;
 
-       if (info->xmit_cnt < WAKEUP_CHARS)
-               schedule_work(&info->tqueue);
-
        if(info->xmit_cnt <= 0) {
                /* All done for now... TX ints off */
                uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
@@ -378,21 +359,6 @@ irqreturn_t rs_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
  }
 
-static void do_softint(struct work_struct *work)
-{
-       struct m68k_serial      *info = container_of(work, struct m68k_serial, tqueue);
-       struct tty_struct       *tty;
-
-       tty = info->tty;
-       if (!tty)
-               return;
-#if 0
-       if (clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-               tty_wakeup(tty);
-       }
-#endif
-}
-
  static int startup(struct m68k_serial * info)
  {
        m68328_uart *uart = &uart_addr[info->line];
@@ -1324,7 +1290,6 @@ rs68328_init(void)
            info->event = 0;
            info->count = 0;
            info->blocked_open = 0;
-           INIT_WORK(&info->tqueue, do_softint);
            init_waitqueue_head(&info->open_wait);
            init_waitqueue_head(&info->close_wait);
            info->line = i;
drivers/tty/serial/68328serial.h +0 -2
index 8c9c3c0..3d2faab 100644
@@ -158,7 +158,6 @@ struct m68k_serial {
        int                     xmit_head;
        int                     xmit_tail;
        int                     xmit_cnt;
-       struct work_struct      tqueue;
        wait_queue_head_t       open_wait;
        wait_queue_head_t       close_wait;
  };
--

1.7.7

Signature · 14 lines
Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#49 lore raw

PATCH 48/79 TTY: serial, fix includes in some drivers

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

linux/tty_flip.h is included in linux/serial_core.h. But this may (and
will) change in the future. Then we would get build errors such as:
.../tty/serial/max3107.c: In function ‘put_data_to_circ_buf’:
.../tty/serial/max3107.c:149:2: error: implicit declaration of function ‘tty_insert_flip_string’

So fix all the drviers which call tty flip buffer helpers to really include linux/tty_flip.h. And also make sure that those include linux/tty.h when operating with struct tty_struct.

---
 drivers/tty/serial/apbuart.c                |    1 +
 drivers/tty/serial/cpm_uart/cpm_uart_core.c |    1 +
 drivers/tty/serial/dz.c                     |    1 +
 drivers/tty/serial/ioc3_serial.c            |    1 +
 drivers/tty/serial/ioc4_serial.c            |    1 +
 drivers/tty/serial/m32r_sio.c               |    1 +
 drivers/tty/serial/max3100.c                |    2 ++
 drivers/tty/serial/max3107.c                |    2 ++
 drivers/tty/serial/mpc52xx_uart.c           |    1 +
 drivers/tty/serial/msm_serial_hs.c          |    2 ++
 drivers/tty/serial/mux.c                    |    2 ++
 drivers/tty/serial/nwpserial.c              |    1 +
 drivers/tty/serial/pch_uart.c               |    2 ++
 drivers/tty/serial/sb1250-duart.c           |    1 +
 drivers/tty/serial/serial_ks8695.c          |    1 +
 drivers/tty/serial/serial_txx9.c            |    2 ++
 drivers/tty/serial/sn_console.c             |    1 +
 drivers/tty/serial/timbuart.c               |    2 ++
 drivers/tty/serial/uartlite.c               |    1 +
 drivers/tty/serial/ucc_uart.c               |    4 +++-
 drivers/tty/serial/xilinx_uartps.c          |    4 +++-
 drivers/tty/serial/zs.c                     |    1 +
 22 files changed, 33 insertions(+), 2 deletions(-)
drivers/tty/serial/apbuart.c +1 -0
index 19a9436..77554fd 100644
@@ -16,6 +16,7 @@
 
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/serial.h>
drivers/tty/serial/cpm_uart/cpm_uart_core.c +1 -0
index 9488da7..b418947 100644
@@ -31,6 +31,7 @@
 
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/serial.h>
drivers/tty/serial/dz.c +1 -0
index ddc487a..e3699a8 100644
@@ -47,6 +47,7 @@
 #include <linux/serial_core.h>
 #include <linux/sysrq.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 
 #include <linux/atomic.h>
 #include <asm/bootinfo.h>
drivers/tty/serial/ioc3_serial.c +1 -0
index ee43efc..758ff310 100644
@@ -13,6 +13,7 @@
  */
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/circ_buf.h>
 #include <linux/serial_reg.h>
drivers/tty/serial/ioc4_serial.c +1 -0
index fcfe826..6b36c15 100644
@@ -14,6 +14,7 @@
  */
 #include <linux/errno.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
 #include <linux/circ_buf.h>
drivers/tty/serial/m32r_sio.c +1 -0
index 8e07517..0801893 100644
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/console.h>
drivers/tty/serial/max3100.c +2 -0
index 7b951ad..2af5aa5 100644
@@ -47,6 +47,8 @@
 #include <linux/serial.h>
 #include <linux/spi/spi.h>
 #include <linux/freezer.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 
 #include <linux/serial_max3100.h>
 
drivers/tty/serial/max3107.c +2 -0
index 750b4f6..47602a2 100644
@@ -31,6 +31,8 @@
 #include <linux/device.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/freezer.h>
drivers/tty/serial/mpc52xx_uart.c +1 -0
index a0bcd8a..c395520 100644
@@ -34,6 +34,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/sysrq.h>
 #include <linux/console.h>
drivers/tty/serial/msm_serial_hs.c +2 -0
index 624701f..60c6eb8 100644
@@ -30,6 +30,8 @@
 
 #include <linux/serial.h>
 #include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
drivers/tty/serial/mux.c +2 -0
index 9711e06..06f6aef 100644
@@ -21,6 +21,8 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/console.h>
 #include <linux/delay.h> /* for udelay */
 #include <linux/device.h>
drivers/tty/serial/nwpserial.c +1 -0
index de17367..9beaff1 100644
@@ -15,6 +15,7 @@
 #include <linux/serial_reg.h>
 #include <linux/serial_core.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/irqreturn.h>
 #include <linux/mutex.h>
 #include <linux/of_platform.h>
drivers/tty/serial/pch_uart.c +2 -0
index 846dfcd..ecc8506 100644
@@ -20,6 +20,8 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/dmi.h>
drivers/tty/serial/sb1250-duart.c +1 -0
index 6bc2e3f..0be8a2f 100644
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/sysrq.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/types.h>
 
 #include <linux/atomic.h>
drivers/tty/serial/serial_ks8695.c +1 -0
index 2430319..5551f7a 100644
@@ -13,6 +13,7 @@
  */
 #include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/serial.h>
drivers/tty/serial/serial_txx9.c +2 -0
index 8e3fc19..34bd345 100644
@@ -28,6 +28,8 @@
 #include <linux/pci.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 
 #include <asm/io.h>
 
drivers/tty/serial/sn_console.c +1 -0
index 377ae74..7320507 100644
@@ -39,6 +39,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/serial.h>
 #include <linux/console.h>
 #include <linux/module.h>
drivers/tty/serial/timbuart.c +2 -0
index 1f36b7e..a4b63bf 100644
@@ -23,6 +23,8 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
drivers/tty/serial/uartlite.c +1 -0
index 8af1ed8..b908615 100644
@@ -15,6 +15,7 @@
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
drivers/tty/serial/ucc_uart.c +3 -1
index c327218..97b6724 100644
@@ -20,8 +20,10 @@
 
 #include <linux/module.h>
 #include <linux/serial.h>
-#include <linux/slab.h>
 #include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/io.h>
 #include <linux/of_platform.h>
 #include <linux/dma-mapping.h>
drivers/tty/serial/xilinx_uartps.c +3 -1
index 19cc1e8..8c03b12 100644
@@ -12,9 +12,11 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/serial.h>
 #include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/console.h>
-#include <linux/serial.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/of.h>
drivers/tty/serial/zs.c +1 -0
index 0aebd71..b7455b5 100644
@@ -63,6 +63,7 @@
 #include <linux/spinlock.h>
 #include <linux/sysrq.h>
 #include <linux/tty.h>
+#include <linux/tty_flip.h>
 #include <linux/types.h>
 
 #include <linux/atomic.h>
Signature · 6 lines
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#50 lore raw

PATCH 49/79 cris: fix a build error in drivers/tty/serial/crisv10.c

In reply to Greg Kroah-Hartman

From: WANG Cong <[email protected]>

This patch fixes the following build error:

drivers/tty/serial/crisv10.c:4453: error: 'if_ser0' undeclared (first use in this function): 2 errors in 2 logs

        v3.1-rc4/cris/cris-allmodconfig v3.1-rc4/cris/cris-allyesconfig
drivers/tty/serial/crisv10.c:4453: error: (Each undeclared identifier is reported only once: 2 errors in 2 logs
        v3.1-rc4/cris/cris-allmodconfig v3.1-rc4/cris/cris-allyesconfig
drivers/tty/serial/crisv10.c:4453: error: for each function it appears in.): 2 errors in 2 logs
        v3.1-rc4/cris/cris-allmodconfig v3.1-rc4/cris/cris-allyesconfig

"if_ser0" is a typo, it should be "if_serial_0".

---
 drivers/tty/serial/crisv10.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/crisv10.c +2 -2
index 225123b..58be715 100644
@@ -4450,7 +4450,7 @@ static int __init rs_init(void)
 
 #if defined(CONFIG_ETRAX_RS485)
 #if defined(CONFIG_ETRAX_RS485_ON_PA)
-	if (cris_io_interface_allocate_pins(if_ser0, 'a', rs485_pa_bit,
+	if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit,
 			rs485_pa_bit)) {
 		printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
 			"RS485 pin\n");
@@ -4459,7 +4459,7 @@ static int __init rs_init(void)
 	}
 #endif
 #if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
-	if (cris_io_interface_allocate_pins(if_ser0, 'g', rs485_pa_bit,
+	if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit,
 			rs485_port_g_bit)) {
 		printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
 			"RS485 pin\n");
Signature · 1 line
1.7.7
#51 lore raw

PATCH 50/79 serial: Support the EFR-register of XR1715x uarts.

In reply to Greg Kroah-Hartman

From: Søren Holm <[email protected]>

The EFR (Enhenced-Features-Register) is located at a different offset than the other devices supporting UART_CAP_EFR. This change add a special setup quick to set UPF_EXAR_EFR on the port. UPF_EXAR_EFR is then used to the port type to PORT_XR17D15X since it is for sure a XR17D15X uart.

---
 drivers/tty/serial/8250.c     |   20 +++++++++++++++++++-
 drivers/tty/serial/8250_pci.c |   33 +++++++++++++++++++++++++++++++++
 include/linux/serial_core.h   |    4 +++-
 include/linux/serial_reg.h    |    1 +
 4 files changed, 56 insertions(+), 2 deletions(-)
drivers/tty/serial/8250.c +19 -1
index 435ce14..82ca71a 100644
@@ -309,6 +309,13 @@ static const struct serial8250_config uart_config[] = {
 				  UART_FCR_T_TRIG_01,
 		.flags		= UART_CAP_FIFO | UART_CAP_RTOIE,
 	},
+	[PORT_XR17D15X] = {
+		.name		= "XR17D15X",
+		.fifo_size	= 64,
+		.tx_loadsz	= 64,
+		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+		.flags		= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
+	},
 };
 
 #if defined(CONFIG_MIPS_ALCHEMY)
@@ -1075,6 +1082,14 @@ static void autoconfig_16550a(struct uart_8250_port *up)
 	serial_outp(up, UART_IER, iersave);
 
 	/*
+	 * Exar uarts have EFR in a weird location
+	 */
+	if (up->port.flags & UPF_EXAR_EFR) {
+		up->port.type = PORT_XR17D15X;
+		up->capabilities |= UART_CAP_AFE | UART_CAP_EFR;
+	}
+
+	/*
 	 * We distinguish between 16550A and U6 16550A by counting
 	 * how many bytes are in the FIFO.
 	 */
@@ -2417,7 +2432,10 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 			efr |= UART_EFR_CTS;
 
 		serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
-		serial_outp(up, UART_EFR, efr);
+		if (up->port.flags & UPF_EXAR_EFR)
+			serial_outp(up, UART_XR_EFR, efr);
+		else
+			serial_outp(up, UART_EFR, efr);
 	}
 
 #ifdef CONFIG_ARCH_OMAP
drivers/tty/serial/8250_pci.c +33 -0
index 6b887d9..a79caba 100644
@@ -1101,6 +1101,15 @@ static int pci_eg20t_init(struct pci_dev *dev)
 #endif
 }
 
+static int
+pci_xr17c154_setup(struct serial_private *priv,
+		  const struct pciserial_board *board,
+		  struct uart_port *port, int idx)
+{
+	port->flags |= UPF_EXAR_EFR;
+	return pci_default_setup(priv, board, port, idx);
+}
+
 /* This should be in linux/pci_ids.h */
 #define PCI_VENDOR_ID_SBSMODULARIO	0x124B
 #define PCI_SUBVENDOR_ID_SBSMODULARIO	0x124B
@@ -1506,6 +1515,30 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
 		.setup		= pci_timedia_setup,
 	},
 	/*
+	 * Exar cards
+	 */
+	{
+		.vendor = PCI_VENDOR_ID_EXAR,
+		.device = PCI_DEVICE_ID_EXAR_XR17C152,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.setup		= pci_xr17c154_setup,
+	},
+	{
+		.vendor = PCI_VENDOR_ID_EXAR,
+		.device = PCI_DEVICE_ID_EXAR_XR17C154,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.setup		= pci_xr17c154_setup,
+	},
+	{
+		.vendor = PCI_VENDOR_ID_EXAR,
+		.device = PCI_DEVICE_ID_EXAR_XR17C158,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.setup		= pci_xr17c154_setup,
+	},
+	/*
 	 * Xircom cards
 	 */
 	{
include/linux/serial_core.h +3 -1
index 493773e..eadf33d 100644
@@ -46,7 +46,8 @@
 #define PORT_AR7	18	/* Texas Instruments AR7 internal UART */
 #define PORT_U6_16550A	19	/* ST-Ericsson U6xxx internal UART */
 #define PORT_TEGRA	20	/* NVIDIA Tegra internal UART */
-#define PORT_MAX_8250	20	/* max port ID */
+#define PORT_XR17D15X	21	/* Exar XR17D15x UART */
+#define PORT_MAX_8250	21	/* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
@@ -349,6 +350,7 @@ struct uart_port {
 #define UPF_MAGIC_MULTIPLIER	((__force upf_t) (1 << 16))
 #define UPF_CONS_FLOW		((__force upf_t) (1 << 23))
 #define UPF_SHARE_IRQ		((__force upf_t) (1 << 24))
+#define UPF_EXAR_EFR		((__force upf_t) (1 << 25))
 /* The exact UART type is known and should not be probed.  */
 #define UPF_FIXED_TYPE		((__force upf_t) (1 << 27))
 #define UPF_BOOT_AUTOCONF	((__force upf_t) (1 << 28))
include/linux/serial_reg.h +1 -0
index c75bda3..8ce70d7 100644
@@ -152,6 +152,7 @@
  * LCR=0xBF (or DLAB=1 for 16C660)
  */
 #define UART_EFR	2	/* I/O: Extended Features Register */
+#define UART_XR_EFR	9	/* I/O: Extended Features Register (XR17D15x) */
 #define UART_EFR_CTS		0x80 /* CTS flow control */
 #define UART_EFR_RTS		0x40 /* RTS flow control */
 #define UART_EFR_SCD		0x20 /* Special character detect */
Signature · 6 lines
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#52 lore raw

PATCH 51/79 cris: lower the printk level in cris serial driver

In reply to Greg Kroah-Hartman

From: WANG Cong <[email protected]>

KERN_CRIT is too high, replace those KERN_CRIT with KERN_ERR or KERN_WARNING.

Cc Geert Uytterhoeven <[email protected]>
Cc Mikael Starvik <[email protected]>
Cc Jesper Nilsson <[email protected]>
---
 drivers/tty/serial/crisv10.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)
drivers/tty/serial/crisv10.c +6 -6
index 58be715..a931524 100644
@@ -1788,7 +1788,7 @@ static unsigned int handle_descr_data(struct e100_serial *info,
 	struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer;
 
 	if (info->recv_cnt + recvl > 65536) {
-		printk(KERN_CRIT
+		printk(KERN_WARNING
 		       "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __func__, recvl);
 		return 0;
 	}
@@ -3813,13 +3813,13 @@ rs_close(struct tty_struct *tty, struct file * filp)
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
-		printk(KERN_CRIT
+		printk(KERN_ERR
 		       "rs_close: bad serial port count; tty->count is 1, "
 		       "info->count is %d\n", info->count);
 		info->count = 1;
 	}
 	if (--info->count < 0) {
-		printk(KERN_CRIT "rs_close: bad serial port count for ttyS%d: %d\n",
+		printk(KERN_ERR "rs_close: bad serial port count for ttyS%d: %d\n",
 		       info->line, info->count);
 		info->count = 0;
 	}
@@ -4452,7 +4452,7 @@ static int __init rs_init(void)
 #if defined(CONFIG_ETRAX_RS485_ON_PA)
 	if (cris_io_interface_allocate_pins(if_serial_0, 'a', rs485_pa_bit,
 			rs485_pa_bit)) {
-		printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
+		printk(KERN_ERR "ETRAX100LX serial: Could not allocate "
 			"RS485 pin\n");
 		put_tty_driver(driver);
 		return -EBUSY;
@@ -4461,7 +4461,7 @@ static int __init rs_init(void)
 #if defined(CONFIG_ETRAX_RS485_ON_PORT_G)
 	if (cris_io_interface_allocate_pins(if_serial_0, 'g', rs485_pa_bit,
 			rs485_port_g_bit)) {
-		printk(KERN_CRIT "ETRAX100LX serial: Could not allocate "
+		printk(KERN_ERR "ETRAX100LX serial: Could not allocate "
 			"RS485 pin\n");
 		put_tty_driver(driver);
 		return -EBUSY;
@@ -4494,7 +4494,7 @@ static int __init rs_init(void)
 		if (info->enabled) {
 			if (cris_request_io_interface(info->io_if,
 					info->io_if_description)) {
-				printk(KERN_CRIT "ETRAX100LX async serial: "
+				printk(KERN_ERR "ETRAX100LX async serial: "
 					"Could not allocate IO pins for "
 					"%s, port %d\n",
 					info->io_if_description, i);
Signature · 1 line
1.7.7
#53 lore raw

PATCH 52/79 TTY: serial, move 68360 driver to staging

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

This driver has been broken at least since 2008. At that time, a88487c79b (Fix compile errors in SGI console drivers) broke this driver completely.

And since nobody noticed for the past 3 years, move it into staging. I think this will rot there and we will throw it away completely after some time. Or maybe someone will volunteer to fix it ;).

---
 drivers/staging/Kconfig                       |    2 ++
 drivers/staging/Makefile                      |    1 +
 drivers/{tty => staging}/serial/68360serial.c |    0
 drivers/staging/serial/Kconfig                |   16 ++++++++++++++++
 drivers/staging/serial/Makefile               |    1 +
 drivers/staging/serial/TODO                   |    6 ++++++
 drivers/tty/serial/Kconfig                    |   17 -----------------
 drivers/tty/serial/Makefile                   |    1 -
 8 files changed, 26 insertions(+), 18 deletions(-)
 rename drivers/{tty => staging}/serial/68360serial.c (100%)
 create mode 100644 drivers/staging/serial/Kconfig
 create mode 100644 drivers/staging/serial/Makefile
 create mode 100644 drivers/staging/serial/TODO
drivers/staging/Kconfig +2 -0
index 06c9081..bd3d1cc 100644
@@ -24,6 +24,8 @@ menuconfig STAGING
 
 if STAGING
 
+source "drivers/staging/serial/Kconfig"
+
 source "drivers/staging/et131x/Kconfig"
 
 source "drivers/staging/slicoss/Kconfig"
drivers/staging/Makefile +1 -0
index f3c5e33..d480a94 100644
@@ -3,6 +3,7 @@
 # fix for build system bug...
 obj-$(CONFIG_STAGING)		+= staging.o
 
+obj-y				+= serial/
 obj-$(CONFIG_ET131X)		+= et131x/
 obj-$(CONFIG_SLICOSS)		+= slicoss/
 obj-$(CONFIG_VIDEO_GO7007)	+= go7007/
drivers/staging/serial/68360serial.c renamed from drivers/tty/serial/68360serial.c +0 -0
similarity index 100%
rename from drivers/tty/serial/68360serial.c
rename to drivers/staging/serial/68360serial.c
drivers/staging/serial/Kconfig new file +16 -0
new file mode 100644
index 0000000..9489688
@@ -0,0 +1,16 @@
+config SERIAL_68360_SMC
+	bool "68360 SMC uart support"
+	depends on M68360
+	help
+	  This driver supports the SMC serial ports of the Motorola 68360 CPU.
+
+config SERIAL_68360_SCC
+	bool "68360 SCC uart support"
+	depends on M68360
+	help
+	  This driver supports the SCC serial ports of the Motorola 68360 CPU.
+
+config SERIAL_68360
+	bool
+	depends on SERIAL_68360_SMC || SERIAL_68360_SCC
+	default y
drivers/staging/serial/Makefile new file +1 -0
new file mode 100644
index 0000000..37a6a0b
@@ -0,0 +1 @@
+obj-$(CONFIG_SERIAL_68360) += 68360serial.o
drivers/staging/serial/TODO new file +6 -0
new file mode 100644
index 0000000..a19cda8
@@ -0,0 +1,6 @@
+These are a few serial drivers that either do not build, or do not work if they
+do build, or if they seem to work, are for obsolete hardware, or are full of
+unfixable races and no one uses them anymore.
+
+If no one steps up to adopt any of these drivers, they will be removed
+in the 3.4 release.
drivers/tty/serial/Kconfig +0 -17
index 8ee3a66..5f479da 100644
@@ -1042,23 +1042,6 @@ config SERIAL_MCF_CONSOLE
 	help
 	  Enable a ColdFire internal serial port to be the system console.
 
-config SERIAL_68360_SMC
-	bool "68360 SMC uart support"
-	depends on M68360
-	help
-	  This driver supports the SMC serial ports of the Motorola 68360 CPU.
-
-config SERIAL_68360_SCC
-	bool "68360 SCC uart support"
-	depends on M68360
-	help
-	  This driver supports the SCC serial ports of the Motorola 68360 CPU.
-
-config SERIAL_68360
-	bool
-	depends on SERIAL_68360_SMC || SERIAL_68360_SCC
-	default y
-
 config SERIAL_PMACZILOG
 	tristate "Mac or PowerMac z85c30 ESCC support"
 	depends on (M68K && MAC) || (PPC_OF && PPC_PMAC)
drivers/tty/serial/Makefile +0 -1
index 7b59958..e10cf5b 100644
@@ -50,7 +50,6 @@ obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
 obj-$(CONFIG_SERIAL_MUX) += mux.o
 obj-$(CONFIG_SERIAL_68328) += 68328serial.o
-obj-$(CONFIG_SERIAL_68360) += 68360serial.o
 obj-$(CONFIG_SERIAL_MCF) += mcf.o
 obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
Signature · 1 line
1.7.7
#54 lore raw

Re: [PATCH 52/79] TTY: serial, move 68360 driver to staging

m68knommu => Greg

Quoted 143 lines · Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

This driver has been broken at least since 2008. At that time, a88487c79b (Fix compile errors in SGI console drivers) broke this driver completely.

And since nobody noticed for the past 3 years, move it into staging. I think this will rot there and we will throw it away completely after some time. Or maybe someone will volunteer to fix it ;).

---
 drivers/staging/Kconfig                       |    2 ++ drivers/staging/Makefile                      |    1 + drivers/{tty => staging}/serial/68360serial.c |    0 drivers/staging/serial/Kconfig                |   16 ++++++++++++++++ drivers/staging/serial/Makefile               |    1 + drivers/staging/serial/TODO                   |    6 ++++++ drivers/tty/serial/Kconfig                    |   17 ----------------- drivers/tty/serial/Makefile                   |    1 -

 8 files changed, 26 insertions(+), 18 deletions(-)

 rename drivers/{tty => staging}/serial/68360serial.c (100%) create mode 100644 drivers/staging/serial/Kconfig create mode 100644 drivers/staging/serial/Makefile create mode 100644 drivers/staging/serial/TODO

drivers/staging/Kconfig +0 -0
index 06c9081..bd3d1cc 100644
@@ -24,6 +24,8 @@ menuconfig STAGING
 

 if STAGING

drivers/staging/Kconfig +2 -0
+source "drivers/staging/serial/Kconfig"
+

 source "drivers/staging/et131x/Kconfig"

 source "drivers/staging/slicoss/Kconfig"

drivers/staging/Makefile +0 -0
index f3c5e33..d480a94 100644
@@ -3,6 +3,7 @@
  # fix for build system bug...

 obj-$(CONFIG_STAGING)          += staging.o

+obj-y                          += serial/
 obj-$(CONFIG_ET131X)           += et131x/
 obj-$(CONFIG_SLICOSS)          += slicoss/
 obj-$(CONFIG_VIDEO_GO7007)     += go7007/

drivers/staging/serial/68360serial.c renamed from drivers/tty/serial/68360serial.c +0 -0
similarity index 100%
rename from drivers/tty/serial/68360serial.c
rename to drivers/staging/serial/68360serial.c
drivers/staging/serial/Kconfig new file +16 -0
new file mode 100644
index 0000000..9489688
@@ -0,0 +1,16 @@
+config SERIAL_68360_SMC
+       bool "68360 SMC uart support"
+       depends on M68360
+       help
+         This driver supports the SMC serial ports of the Motorola 68360 CPU.
+
+config SERIAL_68360_SCC
+       bool "68360 SCC uart support"
+       depends on M68360
+       help
+         This driver supports the SCC serial ports of the Motorola 68360 CPU.
+
+config SERIAL_68360
+       bool
+       depends on SERIAL_68360_SMC || SERIAL_68360_SCC
+       default y
drivers/staging/serial/Makefile new file +1 -0
new file mode 100644
index 0000000..37a6a0b
@@ -0,0 +1 @@
+obj-$(CONFIG_SERIAL_68360) += 68360serial.o
drivers/staging/serial/TODO new file +6 -0
new file mode 100644
index 0000000..a19cda8
@@ -0,0 +1,6 @@
+These are a few serial drivers that either do not build, or do not work if they
+do build, or if they seem to work, are for obsolete hardware, or are full of
+unfixable races and no one uses them anymore.
+
+If no one steps up to adopt any of these drivers, they will be removed
+in the 3.4 release.
drivers/tty/serial/Kconfig +0 -0
index 8ee3a66..5f479da 100644
@@ -1042,23 +1042,6 @@ config SERIAL_MCF_CONSOLE

       help
         Enable a ColdFire internal serial port to be the system console.

drivers/tty/serial/Kconfig +0 -17
-config SERIAL_68360_SMC
-       bool "68360 SMC uart support"
-       depends on M68360
-       help
-         This driver supports the SMC serial ports of the Motorola 68360 CPU.
-
-config SERIAL_68360_SCC
-       bool "68360 SCC uart support"
-       depends on M68360
-       help
-         This driver supports the SCC serial ports of the Motorola 68360 CPU.
-
-config SERIAL_68360
-       bool
-       depends on SERIAL_68360_SMC || SERIAL_68360_SCC
-       default y
-

 config SERIAL_PMACZILOG
       tristate "Mac or PowerMac z85c30 ESCC support" depends on (M68K && MAC) || (PPC_OF && PPC_PMAC)

drivers/tty/serial/Makefile +0 -0
index 7b59958..e10cf5b 100644
@@ -50,7 +50,6 @@ obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o

 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
 obj-$(CONFIG_SERIAL_MUX) += mux.o
 obj-$(CONFIG_SERIAL_68328) += 68328serial.o
-obj-$(CONFIG_SERIAL_68360) += 68360serial.o
 obj-$(CONFIG_SERIAL_MCF) += mcf.o
 obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
--
1.7.7

Signature · 14 lines
Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

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
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#55 lore raw

PATCH 53/79 keyboard: Do not include <linux/irq.>

In reply to Greg Kroah-Hartman

From: Geert Uytterhoeven <[email protected]>

The top of <linux/irq.h> has this comment:

* Please do not include this file in generic code. There is currently
* no requirement for any architecture to implement anything held
* within this file.
*
* Thanks. --rmk

Remove inclusion of <linux/irq.>, to prevent the following compile error from happening soon:

| include/linux/irq.h:132: error: redefinition of ‘struct irq_data’ | include/linux/irq.h:286: error: redefinition of ‘struct irq_chip’

drivers/tty/vt/keyboard.c needs to include <asm/irq_regs.h> for get_irq_regs():

| drivers/tty/vt/keyboard.c:497: error: implicit declaration of function ‘get_irq_regs’ | drivers/tty/vt/keyboard.c:497: warning: initialization makes pointer from integer without a cast

---
 drivers/tty/vt/keyboard.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/tty/vt/keyboard.c +2 -1
index 3761ccf..a605549 100644
@@ -33,7 +33,6 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/irq.h>
 
 #include <linux/kbd_kern.h>
 #include <linux/kbd_diacr.h>
@@ -43,6 +42,8 @@
 #include <linux/notifier.h>
 #include <linux/jiffies.h>
 
+#include <asm/irq_regs.h>
+
 extern void ctrl_alt_del(void);
 
 /*
Signature · 6 lines
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#56 lore raw

PATCH 54/79 serial: mfd: Initconst section fixes

In reply to Greg Kroah-Hartman

From: Andi Kleen <[email protected]>

---
 drivers/tty/serial/mfd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/serial/mfd.c +1 -1
index cfa7501..286c386 100644
@@ -1467,7 +1467,7 @@ static void serial_hsu_remove(struct pci_dev *pdev)
 }
 
 /* First 3 are UART ports, and the 4th is the DMA */
-static const struct pci_device_id pci_ids[] __devinitdata = {
+static const struct pci_device_id pci_ids[] __devinitconst = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081B) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081C) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081D) },
Signature · 1 line
1.7.7
#57 lore raw

PATCH 55/79 serial-core: power up uart port early before we do set_termios when resuming

In reply to Greg Kroah-Hartman

From: Ning Jiang <[email protected]>

The following patch removed uart_change_pm() in uart_resume_port():

commit 5933a161abcb8d83a2c145177f48027c3c0a8995
Author: Yin Kangkai <[email protected]>
serial-core: reset the console speed on resume

It will break the pxa serial driver when the system resumes from suspend mode as it will try to set baud rate divider register in set_termios but with clock off. The register value can not be set correctly on some platform if the clock is disabled. The pxa driver will check the value and report the following warning:

------------[ cut here ]------------
WARNING: at drivers/tty/serial/pxa.c:545 serial_pxa_set_termios+0x1dc/0x250()
Modules linked in:
[<c0281f30>] (unwind_backtrace+0x0/0xf0) from [<c029341c>] (warn_slowpath_common+0x4c/0x64)
[<c029341c>] (warn_slowpath_common+0x4c/0x64) from [<c029344c>] (warn_slowpath_null+0x18/0x1c)
[<c029344c>] (warn_slowpath_null+0x18/0x1c) from [<c044b1e4>] (serial_pxa_set_termios+0x1dc/0x250)
[<c044b1e4>] (serial_pxa_set_termios+0x1dc/0x250) from [<c044a840>] (uart_resume_port+0x128/0x2dc)
[<c044a840>] (uart_resume_port+0x128/0x2dc) from [<c044bbe0>] (serial_pxa_resume+0x18/0x24)
[<c044bbe0>] (serial_pxa_resume+0x18/0x24) from [<c0454d34>] (platform_pm_resume+0x40/0x4c)
[<c0454d34>] (platform_pm_resume+0x40/0x4c) from [<c0457ebc>] (pm_op+0x68/0xb4)
[<c0457ebc>] (pm_op+0x68/0xb4) from [<c0458368>] (device_resume+0xb0/0xec)
[<c0458368>] (device_resume+0xb0/0xec) from [<c04584c8>] (dpm_resume+0xe0/0x194)
[<c04584c8>] (dpm_resume+0xe0/0x194) from [<c0458588>] (dpm_resume_end+0xc/0x18)
[<c0458588>] (dpm_resume_end+0xc/0x18) from [<c02c518c>] (suspend_devices_and_enter+0x16c/0x1ac)
[<c02c518c>] (suspend_devices_and_enter+0x16c/0x1ac) from [<c02c5278>] (enter_state+0xac/0xdc)
[<c02c5278>] (enter_state+0xac/0xdc) from [<c02c48ec>] (state_store+0xa0/0xbc)
[<c02c48ec>] (state_store+0xa0/0xbc) from [<c0408f7c>] (kobj_attr_store+0x18/0x1c)
[<c0408f7c>] (kobj_attr_store+0x18/0x1c) from [<c034a6a4>] (sysfs_write_file+0x108/0x140)
[<c034a6a4>] (sysfs_write_file+0x108/0x140) from [<c02fb798>] (vfs_write+0xac/0x134)
[<c02fb798>] (vfs_write+0xac/0x134) from [<c02fb8cc>] (sys_write+0x3c/0x68)
[<c02fb8cc>] (sys_write+0x3c/0x68) from [<c027c700>] (ret_fast_syscall+0x0/0x2c)
---[ end trace 88289eceb4675b04 ]---

This patch fix the problem by adding the power on opertion back for uart console when console_suspend_enabled is true.

---
 drivers/tty/serial/serial_core.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/tty/serial/serial_core.c +2 -0
index a32dc43..e562b12 100644
@@ -1975,6 +1975,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
 		if (port->tty && port->tty->termios && termios.c_cflag == 0)
 			termios = *(port->tty->termios);
 
+		if (console_suspend_enabled)
+			uart_change_pm(state, 0);
 		uport->ops->set_termios(uport, &termios, NULL);
 		if (console_suspend_enabled)
 			console_start(uport->cons);
Signature · 1 line
1.7.7
#58 lore raw

PATCH 56/79 TTY: irq: Remove IRQF_DISABLED

In reply to Greg Kroah-Hartman

From: Yong Zhang <[email protected]>

Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled], We run all interrupt handlers with interrupts disabled
and we even check and yell when an interrupt handler
returns with interrupts enabled (see commit [b738a50a:
genirq: Warn when handler enables interrupts]).

So now this flag is a NOOP and can be removed.

---
 drivers/tty/amiserial.c              |    2 +-
 drivers/tty/cyclades.c               |    2 +-
 drivers/tty/hvc/hvc_irq.c            |    2 +-
 drivers/tty/hvc/hvcs.c               |    2 +-
 drivers/tty/hvc/hvsi.c               |    2 +-
 drivers/tty/isicom.c                 |    2 +-
 drivers/tty/serial/68328serial.c     |    2 +-
 drivers/tty/serial/altera_jtaguart.c |    2 +-
 drivers/tty/serial/altera_uart.c     |    2 +-
 drivers/tty/serial/bfin_sport_uart.c |    2 +-
 drivers/tty/serial/bfin_uart.c       |    8 ++++----
 drivers/tty/serial/crisv10.c         |   18 +++++++++---------
 drivers/tty/serial/icom.c            |    2 +-
 drivers/tty/serial/lantiq.c          |    6 +++---
 drivers/tty/serial/mcf.c             |    2 +-
 drivers/tty/serial/mpc52xx_uart.c    |    2 +-
 drivers/tty/serial/serial_ks8695.c   |    8 ++++----
 drivers/tty/serial/sh-sci.c          |    2 +-
 drivers/tty/serial/sn_console.c      |    2 +-
 19 files changed, 35 insertions(+), 35 deletions(-)
drivers/tty/amiserial.c +1 -1
index 6d43f55..b84c834 100644
@@ -2017,7 +2017,7 @@ static int __init amiga_serial_probe(struct platform_device *pdev)
 	if (error)
 		goto fail_unregister;
 
-	error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED,
+	error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, 0,
 			    "serial RX", state);
 	if (error)
 		goto fail_free_irq;
drivers/tty/cyclades.c +1 -1
index 5beef49..c9bf779 100644
@@ -3367,7 +3367,7 @@ static int __init cy_detect_isa(void)
 
 		/* allocate IRQ */
 		if (request_irq(cy_isa_irq, cyy_interrupt,
-				IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
+				0, "Cyclom-Y", &cy_card[j])) {
 			printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
 				"could not allocate IRQ#%d.\n",
 				(unsigned long)cy_isa_address, cy_isa_irq);
drivers/tty/hvc/hvc_irq.c +1 -1
index 2623e17..c9adb05 100644
@@ -28,7 +28,7 @@ int notifier_add_irq(struct hvc_struct *hp, int irq)
 		hp->irq_requested = 0;
 		return 0;
 	}
-	rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED,
+	rc = request_irq(irq, hvc_handle_interrupt, 0,
 			   "hvc_console", hp);
 	if (!rc)
 		hp->irq_requested = 1;
drivers/tty/hvc/hvcs.c +1 -1
index e523773..55882b5 100644
@@ -1057,7 +1057,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
 	 * the conn was registered and now.
 	 */
 	if (!(rc = request_irq(irq, &hvcs_handle_interrupt,
-				IRQF_DISABLED, "ibmhvcs", hvcsd))) {
+				0, "ibmhvcs", hvcsd))) {
 		/*
 		 * It is possible the vty-server was removed after the irq was
 		 * requested but before we have time to enable interrupts.
drivers/tty/hvc/hvsi.c +1 -1
index c94e2f5..cdfa3e0 100644
@@ -1105,7 +1105,7 @@ static int __init hvsi_init(void)
 		struct hvsi_struct *hp = &hvsi_ports[i];
 		int ret = 1;
 
-		ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp);
+		ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp);
 		if (ret)
 			printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n",
 				hp->virq, ret);
drivers/tty/isicom.c +1 -1
index db1cf9c..e5c295a 100644
@@ -1598,7 +1598,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
 	}
 
 	retval = request_irq(board->irq, isicom_interrupt,
-			IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board);
+			IRQF_SHARED, ISICOM_NAME, board);
 	if (retval < 0) {
 		dev_err(&pdev->dev, "Could not install handler at Irq %d. "
 			"Card%d will be disabled.\n", board->irq, index + 1);
drivers/tty/serial/68328serial.c +1 -1
index f549231..a88ef97 100644
@@ -1306,7 +1306,7 @@ rs68328_init(void)
 
 	    if (request_irq(uart_irqs[i],
 			    rs_interrupt,
-			    IRQF_DISABLED,
+			    0,
 			    "M68328_UART", info))
                 panic("Unable to attach 68328 serial interrupt\n");
 	}
drivers/tty/serial/altera_jtaguart.c +1 -1
index 60e049b..00a73ec 100644
@@ -218,7 +218,7 @@ static int altera_jtaguart_startup(struct uart_port *port)
 	unsigned long flags;
 	int ret;
 
-	ret = request_irq(port->irq, altera_jtaguart_interrupt, IRQF_DISABLED,
+	ret = request_irq(port->irq, altera_jtaguart_interrupt, 0,
 			DRV_NAME, port);
 	if (ret) {
 		pr_err(DRV_NAME ": unable to attach Altera JTAG UART %d "
drivers/tty/serial/altera_uart.c +1 -1
index 50bc5a5..d902558 100644
@@ -315,7 +315,7 @@ static int altera_uart_startup(struct uart_port *port)
 		return 0;
 	}
 
-	ret = request_irq(port->irq, altera_uart_interrupt, IRQF_DISABLED,
+	ret = request_irq(port->irq, altera_uart_interrupt, 0,
 			DRV_NAME, port);
 	if (ret) {
 		pr_err(DRV_NAME ": unable to attach Altera UART %d "
drivers/tty/serial/bfin_sport_uart.c +1 -1
index 891d194..ee101c0 100644
@@ -294,7 +294,7 @@ static int sport_startup(struct uart_port *port)
 		if (request_irq(gpio_to_irq(up->cts_pin),
 			sport_mctrl_cts_int,
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
-			IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) {
+			0, "BFIN_SPORT_UART_CTS", up)) {
 			up->cts_pin = -1;
 			dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n");
 		}
drivers/tty/serial/bfin_uart.c +4 -4
index c7e592d..66afb98 100644
@@ -667,14 +667,14 @@ static int bfin_serial_startup(struct uart_port *port)
 		kgdboc_break_enabled = 0;
 	else {
 # endif
-	if (request_irq(uart->rx_irq, bfin_serial_rx_int, IRQF_DISABLED,
+	if (request_irq(uart->rx_irq, bfin_serial_rx_int, 0,
 	     "BFIN_UART_RX", uart)) {
 		printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
 		return -EBUSY;
 	}
 
 	if (request_irq
-	    (uart->tx_irq, bfin_serial_tx_int, IRQF_DISABLED,
+	    (uart->tx_irq, bfin_serial_tx_int, 0,
 	     "BFIN_UART_TX", uart)) {
 		printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n");
 		free_irq(uart->rx_irq, uart);
@@ -734,7 +734,7 @@ static int bfin_serial_startup(struct uart_port *port)
 		if (request_irq(gpio_to_irq(uart->cts_pin),
 			bfin_serial_mctrl_cts_int,
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
-			IRQF_DISABLED, "BFIN_UART_CTS", uart)) {
+			0, "BFIN_UART_CTS", uart)) {
 			uart->cts_pin = -1;
 			pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n");
 		}
@@ -745,7 +745,7 @@ static int bfin_serial_startup(struct uart_port *port)
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
 	if (uart->cts_pin >= 0 && request_irq(uart->status_irq,
 		bfin_serial_mctrl_cts_int,
-		IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
+		0, "BFIN_UART_MODEM_STATUS", uart)) {
 		uart->cts_pin = -1;
 		pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n");
 	}
drivers/tty/serial/crisv10.c +9 -9
index a931524..b743504 100644
@@ -258,7 +258,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_out_enabled = 1,
 	  .dma_out_nbr = SER0_TX_DMA_NBR,
 	  .dma_out_irq_nbr = SER0_DMA_TX_IRQ_NBR,
-	  .dma_out_irq_flags = IRQF_DISABLED,
+	  .dma_out_irq_flags = 0,
 	  .dma_out_irq_description = "serial 0 dma tr",
 #else
 	  .dma_out_enabled = 0,
@@ -271,7 +271,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_in_enabled = 1,
 	  .dma_in_nbr = SER0_RX_DMA_NBR,
 	  .dma_in_irq_nbr = SER0_DMA_RX_IRQ_NBR,
-	  .dma_in_irq_flags = IRQF_DISABLED,
+	  .dma_in_irq_flags = 0,
 	  .dma_in_irq_description = "serial 0 dma rec",
 #else
 	  .dma_in_enabled = 0,
@@ -313,7 +313,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_out_enabled = 1,
 	  .dma_out_nbr = SER1_TX_DMA_NBR,
 	  .dma_out_irq_nbr = SER1_DMA_TX_IRQ_NBR,
-	  .dma_out_irq_flags = IRQF_DISABLED,
+	  .dma_out_irq_flags = 0,
 	  .dma_out_irq_description = "serial 1 dma tr",
 #else
 	  .dma_out_enabled = 0,
@@ -326,7 +326,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_in_enabled = 1,
 	  .dma_in_nbr = SER1_RX_DMA_NBR,
 	  .dma_in_irq_nbr = SER1_DMA_RX_IRQ_NBR,
-	  .dma_in_irq_flags = IRQF_DISABLED,
+	  .dma_in_irq_flags = 0,
 	  .dma_in_irq_description = "serial 1 dma rec",
 #else
 	  .dma_in_enabled = 0,
@@ -369,7 +369,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_out_enabled = 1,
 	  .dma_out_nbr = SER2_TX_DMA_NBR,
 	  .dma_out_irq_nbr = SER2_DMA_TX_IRQ_NBR,
-	  .dma_out_irq_flags = IRQF_DISABLED,
+	  .dma_out_irq_flags = 0,
 	  .dma_out_irq_description = "serial 2 dma tr",
 #else
 	  .dma_out_enabled = 0,
@@ -382,7 +382,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_in_enabled = 1,
 	  .dma_in_nbr = SER2_RX_DMA_NBR,
 	  .dma_in_irq_nbr = SER2_DMA_RX_IRQ_NBR,
-	  .dma_in_irq_flags = IRQF_DISABLED,
+	  .dma_in_irq_flags = 0,
 	  .dma_in_irq_description = "serial 2 dma rec",
 #else
 	  .dma_in_enabled = 0,
@@ -423,7 +423,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_out_enabled = 1,
 	  .dma_out_nbr = SER3_TX_DMA_NBR,
 	  .dma_out_irq_nbr = SER3_DMA_TX_IRQ_NBR,
-	  .dma_out_irq_flags = IRQF_DISABLED,
+	  .dma_out_irq_flags = 0,
 	  .dma_out_irq_description = "serial 3 dma tr",
 #else
 	  .dma_out_enabled = 0,
@@ -436,7 +436,7 @@ static struct e100_serial rs_table[] = {
 	  .dma_in_enabled = 1,
 	  .dma_in_nbr = SER3_RX_DMA_NBR,
 	  .dma_in_irq_nbr = SER3_DMA_RX_IRQ_NBR,
-	  .dma_in_irq_flags = IRQF_DISABLED,
+	  .dma_in_irq_flags = 0,
 	  .dma_in_irq_description = "serial 3 dma rec",
 #else
 	  .dma_in_enabled = 0,
@@ -4558,7 +4558,7 @@ static int __init rs_init(void)
 	/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
 
 	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt,
-			IRQF_SHARED | IRQF_DISABLED, "serial ", driver))
+			IRQF_SHARED, "serial ", driver))
 		panic("%s: Failed to request irq8", __func__);
 
 #endif
drivers/tty/serial/icom.c +1 -1
index 8a869e5..d55709a 100644
@@ -1554,7 +1554,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
 
 	 /* save off irq and request irq line */
 	 if ( (retval = request_irq(dev->irq, icom_interrupt,
-				   IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
+				   IRQF_SHARED, ICOM_DRIVER_NAME,
 				   (void *) icom_adapter))) {
 		  goto probe_exit2;
 	 }
drivers/tty/serial/lantiq.c +3 -3
index 58cf279..9e2d42b 100644
@@ -338,21 +338,21 @@ lqasc_startup(struct uart_port *port)
 		ASCCON_ROEN, port->membase + LTQ_ASC_CON);
 
 	retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
-		IRQF_DISABLED, "asc_tx", port);
+		0, "asc_tx", port);
 	if (retval) {
 		pr_err("failed to request lqasc_tx_int\n");
 		return retval;
 	}
 
 	retval = request_irq(ltq_port->rx_irq, lqasc_rx_int,
-		IRQF_DISABLED, "asc_rx", port);
+		0, "asc_rx", port);
 	if (retval) {
 		pr_err("failed to request lqasc_rx_int\n");
 		goto err1;
 	}
 
 	retval = request_irq(ltq_port->err_irq, lqasc_err_int,
-		IRQF_DISABLED, "asc_err", port);
+		0, "asc_err", port);
 	if (retval) {
 		pr_err("failed to request lqasc_err_int\n");
 		goto err2;
drivers/tty/serial/mcf.c +1 -1
index 3394b7c..9afca09 100644
@@ -380,7 +380,7 @@ static void mcf_config_port(struct uart_port *port, int flags)
 	/* Clear mask, so no surprise interrupts. */
 	writeb(0, port->membase + MCFUART_UIMR);
 
-	if (request_irq(port->irq, mcf_interrupt, IRQF_DISABLED, "UART", port))
+	if (request_irq(port->irq, mcf_interrupt, 0, "UART", port))
 		printk(KERN_ERR "MCF: unable to attach ColdFire UART %d "
 			"interrupt vector=%d\n", port->line, port->irq);
 }
drivers/tty/serial/mpc52xx_uart.c +1 -1
index c395520..1093a88 100644
@@ -274,7 +274,7 @@ static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port,
 
 static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np)
 {
-	port->irqflags = IRQF_DISABLED;
+	port->irqflags = 0;
 	port->irq = irq_of_parse_and_map(np, 0);
 }
 
drivers/tty/serial/serial_ks8695.c +4 -4
index 5551f7a..7c13639 100644
@@ -337,19 +337,19 @@ static int ks8695uart_startup(struct uart_port *port)
 	/*
 	 * Allocate the IRQ
 	 */
-	retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, IRQF_DISABLED, "UART TX", port);
+	retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, 0, "UART TX", port);
 	if (retval)
 		goto err_tx;
 
-	retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, IRQF_DISABLED, "UART RX", port);
+	retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, 0, "UART RX", port);
 	if (retval)
 		goto err_rx;
 
-	retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, IRQF_DISABLED, "UART LineStatus", port);
+	retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, 0, "UART LineStatus", port);
 	if (retval)
 		goto err_ls;
 
-	retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, IRQF_DISABLED, "UART ModemStatus", port);
+	retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, 0, "UART ModemStatus", port);
 	if (retval)
 		goto err_ms;
 
drivers/tty/serial/sh-sci.c +1 -1
index 2ec57b2..ca1a4c3 100644
@@ -1961,7 +1961,7 @@ static int __devinit sci_init_single(struct platform_device *dev,
 	 * For the muxed case there's nothing more to do.
 	 */
 	port->irq		= p->irqs[SCIx_RXI_IRQ];
-	port->irqflags		= IRQF_DISABLED;
+	port->irqflags		= 0;
 
 	port->serial_in		= sci_serial_in;
 	port->serial_out	= sci_serial_out;
drivers/tty/serial/sn_console.c +1 -1
index 7320507..238c7df 100644
@@ -738,7 +738,7 @@ static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
 		DPRINTF("sn_console: switching to interrupt driven console\n");
 
 		if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
-				IRQF_DISABLED | IRQF_SHARED,
+				IRQF_SHARED,
 				"SAL console driver", port) >= 0) {
 			spin_lock_irqsave(&port->sc_port.lock, flags);
 			port->sc_port.irq = SGI_UART_VECTOR;
Signature · 1 line
1.7.7
#59 lore raw

PATCH 57/79 drivers/tty: don't use the byte channel handle as a parameter in ehv_bytechan.c

In reply to Greg Kroah-Hartman

From: Timur Tabi <[email protected]>

The ePAPR hypervisor byte channel console driver only supports one byte channel as a console, and the byte channel handle is stored in a global variable. It doesn't make any sense to pass that handle as a parameter to the console functions, since these functions already have access to the global variable.

---
 drivers/tty/ehv_bytechan.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)
drivers/tty/ehv_bytechan.c +2 -5
index f733718..1595dba 100644
@@ -282,7 +282,6 @@ static int ehv_bc_console_byte_channel_send(unsigned int handle, const char *s,
 static void ehv_bc_console_write(struct console *co, const char *s,
 				 unsigned int count)
 {
-	unsigned int handle = (uintptr_t)co->data;
 	char s2[EV_BYTE_CHANNEL_MAX_BYTES];
 	unsigned int i, j = 0;
 	char c;
@@ -295,14 +294,14 @@ static void ehv_bc_console_write(struct console *co, const char *s,
 
 		s2[j++] = c;
 		if (j >= (EV_BYTE_CHANNEL_MAX_BYTES - 1)) {
-			if (ehv_bc_console_byte_channel_send(handle, s2, j))
+			if (ehv_bc_console_byte_channel_send(stdout_bc, s2, j))
 				return;
 			j = 0;
 		}
 	}
 
 	if (j)
-		ehv_bc_console_byte_channel_send(handle, s2, j);
+		ehv_bc_console_byte_channel_send(stdout_bc, s2, j);
 }
 
 /*
@@ -348,8 +347,6 @@ static int __init ehv_bc_console_init(void)
 			   CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
 #endif
 
-	ehv_bc_console.data = (void *)(uintptr_t)stdout_bc;
-
 	/* add_preferred_console() must be called before register_console(),
 	   otherwise it won't work.  However, we don't want to enumerate all the
 	   byte channels here, either, since we only care about one. */
Signature · 1 line
1.7.7
#60 lore raw

PATCH 58/79 tty/n_gsm: fix bug in tiocmset

In reply to Greg Kroah-Hartman

From: Nikola Diklic-Perin <[email protected]>

Clear bitmask was not inverted before masking modem_tx.

Calling ioctl(fd, TIOCMBIC, TIOCM_RTS) results in:

[  197.430000] pre_modem_tx:	0x00000006
[  197.430000] clear:			0x00000004
[  197.430000] set:			0x00000000
[  197.440000] post_modem_tx:	0x00000004

which is wrong.

---
 drivers/tty/n_gsm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/n_gsm.c +1 -1
index 8d7766b..da3b31a 100644
@@ -2989,7 +2989,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty,
 	struct gsm_dlci *dlci = tty->driver_data;
 	unsigned int modem_tx = dlci->modem_tx;
 
-	modem_tx &= clear;
+	modem_tx &= ~clear;
 	modem_tx |= set;
 
 	if (modem_tx != dlci->modem_tx) {
Signature · 1 line
1.7.7
#61 lore raw

PATCH 59/79 8250: ratelimit LSR safety check engaged warning.

In reply to Greg Kroah-Hartman

From: Konrad Rzeszutek Wilk <[email protected]>

On my BIOSTAR TA890FXE the ttyS0 ends up spewing:

[904682.485933] ttyS0: LSR safety check engaged!
[904692.505895] ttyS0: LSR safety check engaged!
[904702.525972] ttyS0: LSR safety check engaged!
[904712.545967] ttyS0: LSR safety check engaged!
[904722.566125] ttyS0: LSR safety check engaged!

..
lets limit it so it won't be the only thing visible in the ring buffer.

---
 drivers/tty/serial/8250.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/8250.c +2 -2
index 82ca71a..076e9c6 100644
@@ -2055,8 +2055,8 @@ static int serial8250_startup(struct uart_port *port)
 	 */
 	if (!(up->port.flags & UPF_BUGGY_UART) &&
 	    (serial_inp(up, UART_LSR) == 0xff)) {
-		printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
-		       serial_index(&up->port));
+		printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
+				   serial_index(&up->port));
 		return -ENODEV;
 	}
 
Signature · 1 line
1.7.7
#62 lore raw

PATCH 60/79 tty/n_gsm: fix a bug in gsm_dlci_data_output (adaption = 2 case)

In reply to Greg Kroah-Hartman

From: Mikhail Kshevetskiy <[email protected]>

in adaption=2 case we should put 1 or 2 byte with modem status bits at the beginning of a buffer pointed by "dp". n_gsm use 1 byte case, so it allocate a buffer of len + 1 size. As result we should:
* put 1 byte of modem status bits
* increase data pointer
* put "len" bytes of data
but actually we have:
* increase first byte with the value of modem status bits
* decrease "len"
* put orig_len - 1 bytes of data starting from the buffer beggining
This is evidently wrong.

---
 drivers/tty/n_gsm.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/tty/n_gsm.c +1 -2
index da3b31a..14c26cd 100644
@@ -833,8 +833,7 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
 		break;
 	case 2:	/* Unstructed with modem bits. Always one byte as we never
 		   send inline break data */
-		*dp += gsm_encode_modem(dlci);
-		len--;
+		*dp++ = gsm_encode_modem(dlci);
 		break;
 	}
 	WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len);
Signature · 1 line
1.7.7
#63 lore raw

PATCH 61/79 tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output

In reply to Greg Kroah-Hartman

From: Mikhail Kshevetskiy <[email protected]>

n_gsm use a simple approach: every writing to fifo correspond exactly one reading from fifo. There are no problem in this approach until we read less bytes then we write. As result fifo may owerflow. This leads to packet loss and very slow responce.

For example, this happens with ping packets (about 96 byte each) and default gsm->mtu = 64. As result we get 50 sec ping timeout and 20% packet loss.

Fix the problem by reading and sending all data from the fifo

---
 drivers/tty/n_gsm.c |   52 +++++++++++++++++++++++++++-----------------------
 1 files changed, 28 insertions(+), 24 deletions(-)
drivers/tty/n_gsm.c +28 -24
index 14c26cd..4cb0d0a 100644
@@ -809,37 +809,41 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
 {
 	struct gsm_msg *msg;
 	u8 *dp;
-	int len, size;
+	int len, total_size, size;
 	int h = dlci->adaption - 1;
 
-	len = kfifo_len(dlci->fifo);
-	if (len == 0)
-		return 0;
+	total_size = 0;
+	while(1) {
+		len = kfifo_len(dlci->fifo);
+		if (len == 0)
+			return total_size;
 
-	/* MTU/MRU count only the data bits */
-	if (len > gsm->mtu)
-		len = gsm->mtu;
+		/* MTU/MRU count only the data bits */
+		if (len > gsm->mtu)
+			len = gsm->mtu;
 
-	size = len + h;
+		size = len + h;
 
-	msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
-	/* FIXME: need a timer or something to kick this so it can't
-	   get stuck with no work outstanding and no buffer free */
-	if (msg == NULL)
-		return -ENOMEM;
-	dp = msg->data;
-	switch (dlci->adaption) {
-	case 1:	/* Unstructured */
-		break;
-	case 2:	/* Unstructed with modem bits. Always one byte as we never
-		   send inline break data */
-		*dp++ = gsm_encode_modem(dlci);
-		break;
+		msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+		/* FIXME: need a timer or something to kick this so it can't
+		   get stuck with no work outstanding and no buffer free */
+		if (msg == NULL)
+			return -ENOMEM;
+		dp = msg->data;
+		switch (dlci->adaption) {
+		case 1:	/* Unstructured */
+			break;
+		case 2:	/* Unstructed with modem bits. Always one byte as we never
+			   send inline break data */
+			*dp++ = gsm_encode_modem(dlci);
+			break;
+		}
+		WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len);
+		__gsm_data_queue(dlci, msg);
+		total_size += size;
 	}
-	WARN_ON(kfifo_out_locked(dlci->fifo, dp , len, &dlci->lock) != len);
-	__gsm_data_queue(dlci, msg);
 	/* Bytes of data we used up */
-	return size;
+	return total_size;
 }
 
 /**
Signature · 1 line
1.7.7
#64 lore raw

PATCH 62/79 TTY: snyclinkmp: forever loop in tx_load_dma_buffer()

In reply to Greg Kroah-Hartman

From: Dan Carpenter <[email protected]>

My main concern here was the line that said:

	copy_count = min_t(unsigned short,count,SCABUFSIZE);

"count" is an unsigned int here so the cast to unsigned short truncates the upper bits. So if count is 0x10000 then copy_count is 0 and the loop never exits.

"count" comes from skb->len in hdlcdev_xmit().

The other min_t() changes are just cleanups.

---
 drivers/tty/synclinkmp.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/tty/synclinkmp.c +3 -3
index c77831c..0f6b796 100644
@@ -4950,7 +4950,7 @@ CheckAgain:
 
 	if ( debug_level >= DEBUG_LEVEL_DATA )
 		trace_block(info,info->rx_buf_list_ex[StartIndex].virt_addr,
-			min_t(int, framesize,SCABUFSIZE),0);
+			min_t(unsigned int, framesize, SCABUFSIZE), 0);
 
 	if (framesize) {
 		if (framesize > info->max_frame_size)
@@ -5015,14 +5015,14 @@ static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int co
 	SCADESC_EX *desc_ex;
 
 	if ( debug_level >= DEBUG_LEVEL_DATA )
-		trace_block(info,buf, min_t(int, count,SCABUFSIZE), 1);
+		trace_block(info, buf, min_t(unsigned int, count, SCABUFSIZE), 1);
 
 	/* Copy source buffer to one or more DMA buffers, starting with
 	 * the first transmit dma buffer.
 	 */
 	for(i=0;;)
 	{
-		copy_count = min_t(unsigned short,count,SCABUFSIZE);
+		copy_count = min_t(unsigned int, count, SCABUFSIZE);
 
 		desc = &info->tx_buf_list[i];
 		desc_ex = &info->tx_buf_list_ex[i];
Signature · 1 line
1.7.7
#65 lore raw

PATCH 63/79 hvc_console: display printk messages on console.

In reply to Greg Kroah-Hartman

From: Miche Baker-Harvey <[email protected]>

printk only works for "registered consoles." Currently, the hvc_console code calls register_console() from hvc_instantiate(), but that's only used in the early console case. In hvc_alloc(), register_console() was not called.

Add a call to register_console() in hvc_alloc(), set up the index in the hvc_console, and set up the necessary vtermnos[] and cons_op[] entries so that printk functions work.

---
 drivers/tty/hvc/hvc_console.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
drivers/tty/hvc/hvc_console.c +6 -1
index b6b2d18..7430bc3 100644
@@ -852,7 +852,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
 	 * find index to use:
 	 * see if this vterm id matches one registered for console.
 	 */
-	for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
+	for (i = 0; i < MAX_NR_HVC_CONSOLES; i++)
 		if (vtermnos[i] == hp->vtermno &&
 		    cons_ops[i] == hp->ops)
 			break;
@@ -862,9 +862,13 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
 		i = ++last_hvc;
 
 	hp->index = i;
+	hvc_console.index = i;
+	vtermnos[i] = vtermno;
+	cons_ops[i] = ops;
 
 	list_add_tail(&(hp->next), &hvc_structs);
 	spin_unlock(&hvc_structs_lock);
+	register_console(&hvc_console);
 
 	return hp;
 }
@@ -875,6 +879,7 @@ int hvc_remove(struct hvc_struct *hp)
 	unsigned long flags;
 	struct tty_struct *tty;
 
+	unregister_console(&hvc_console);
 	spin_lock_irqsave(&hp->lock, flags);
 	tty = tty_kref_get(hp->tty);
 
Signature · 1 line
1.7.7
#66 lore raw

PATCH 64/79 tty: Support compat_ioctl get/set termios_locked

In reply to Greg Kroah-Hartman

From: Thomas Meyer <[email protected]>

When running a Fedora 15 (x86) on an x86_64 kernel, in the boot process plymouthd complains about those two missing ioctls:

[    2.581783] ioctl32(plymouthd:186): Unknown cmd fd(10) cmd(00005457){t:'T';sz:0} arg(ffb6a5d0) on /dev/tty1
[    2.581803] ioctl32(plymouthd:186): Unknown cmd fd(10) cmd(00005456){t:'T';sz:0} arg(ffb6a680) on /dev/tty1

both ioctl functions work on the 'struct termios' resp. 'struct termios2', which has the same size (36 bytes resp. 44 bytes) on x86 and x86_64, so it's just a matter of converting the pointer from userland.

---
 drivers/tty/tty_io.c    |    2 ++
 drivers/tty/tty_ioctl.c |   17 +++++++++++++++++
 include/linux/tty.h     |    2 ++
 3 files changed, 21 insertions(+), 0 deletions(-)
drivers/tty/tty_io.c +2 -0
index 150e4f7..4ca4bcd 100644
@@ -2717,6 +2717,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
 	ld = tty_ldisc_ref_wait(tty);
 	if (ld->ops->compat_ioctl)
 		retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
+	else
+		retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg);
 	tty_ldisc_deref(ld);
 
 	return retval;
drivers/tty/tty_ioctl.c +17 -0
index 53f2442..9314d93 100644
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/mutex.h>
+#include <linux/compat.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -1179,3 +1180,19 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
 	}
 }
 EXPORT_SYMBOL(n_tty_ioctl_helper);
+
+#ifdef CONFIG_COMPAT
+long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	switch (cmd) {
+	case TIOCGLCKTRMIOS:
+	case TIOCSLCKTRMIOS:
+		return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg));
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+EXPORT_SYMBOL(n_tty_compat_ioctl_helper);
+#endif
+
include/linux/tty.h +2 -0
index 0ad6888..64c12a3 100644
@@ -579,6 +579,8 @@ extern int __init tty_init(void);
 /* tty_ioctl.c */
 extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
 		       unsigned int cmd, unsigned long arg);
+extern long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
+		       unsigned int cmd, unsigned long arg);
 
 /* serial.c */
 
Signature · 1 line
1.7.7
#67 lore raw

PATCH 65/79 parport_pc: release IO region properly if unsupported ITE887x card is found

In reply to Greg Kroah-Hartman

From: Jiri Kosina <[email protected]>

sio_ite_8872_probe() bails out if it detects no-parallel (1S, 2S) or unknown card.

It doesn't call release_region() on the previously allocated resource though. This causes

(a) leak of the resource
(b) kernel oops when parport module is removed and /proc/ioports is read. This is because the string that has been associated to the IO port region is a static char array inside the already removed module.

Let's call release_region() properly before baling out.

---
 drivers/parport/parport_pc.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/parport/parport_pc.c +3 -0
index d1cdb94..d0b597b 100644
@@ -2595,14 +2595,17 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq,
 		break;
 	case 0x6:
 		printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n");
+		release_region(inta_addr[i], 32);
 		return 0;
 	case 0x8:
 		printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n");
+		release_region(inta_addr[i], 32);
 		return 0;
 	default:
 		printk(KERN_INFO "parport_pc: unknown ITE887x\n");
 		printk(KERN_INFO "parport_pc: please mail 'lspci -nvv' "
 			"output to [email protected]\n");
+		release_region(inta_addr[i], 32);
 		return 0;
 	}
 
Signature · 1 line
1.7.7
#68 lore raw

PATCH 66/79 h8300: drivers/serial/Kconfig was moved

In reply to Greg Kroah-Hartman

From: Paul Bolle <[email protected]>

commit ab4382d27412e7e3e7c936e8d50d8888dfac3df8 moved drivers/serial/Kconfig to drivers/tty/serial/Kconfig, so we need to source the latter file.

---
 arch/h8300/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/h8300/Kconfig +1 -1
index 091ed61..2b1eee7 100644
@@ -195,7 +195,7 @@ config UNIX98_PTYS
 
 source "drivers/char/pcmcia/Kconfig"
 
-source "drivers/serial/Kconfig"
+source "drivers/tty/serial/Kconfig"
 
 source "drivers/i2c/Kconfig"
 
Signature · 1 line
1.7.7
#69 lore raw

PATCH 67/79 8250_pci: Fix kernel panic when pch_uart is disabled

In reply to Greg Kroah-Hartman

From: Tomoya MORINAGA <[email protected]>

Currently, ".setup" function is not set.
As a result, when detecting our IOH's uart device without pch_uart, kernel panic occurs at the following of pciserial_init_ports().

	for (i = 0; i < nr_ports; i++) {
		if (quirk->setup(priv, board, &serial_port, i))
			break;

So, this patch adds the ".setup" function.
We can use pci_default_setup because our IOH's uart is compatible with 16550.

---
 drivers/tty/serial/8250_pci.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)
drivers/tty/serial/8250_pci.c +10 -0
index a79caba..1b449b7 100644
@@ -1591,51 +1591,61 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
 		.vendor         = PCI_VENDOR_ID_INTEL,
 		.device         = 0x8811,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = PCI_VENDOR_ID_INTEL,
 		.device         = 0x8812,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = PCI_VENDOR_ID_INTEL,
 		.device         = 0x8813,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = PCI_VENDOR_ID_INTEL,
 		.device         = 0x8814,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = 0x10DB,
 		.device         = 0x8027,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = 0x10DB,
 		.device         = 0x8028,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = 0x10DB,
 		.device         = 0x8029,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = 0x10DB,
 		.device         = 0x800C,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = 0x10DB,
 		.device         = 0x800D,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	{
 		.vendor         = 0x10DB,
 		.device         = 0x800D,
 		.init		= pci_eg20t_init,
+		.setup		= pci_default_setup,
 	},
 	/*
 	 * Cronyx Omega PCI (PLX-chip based)
Signature · 1 line
1.7.7
#70 lore raw

PATCH 68/79 TTY: drop driver reference in tty_open fail path

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

When tty_driver_lookup_tty fails in tty_open, we forget to drop a reference to the tty driver. This was added by commit 4a2b5fddd5 (Move tty lookup/reopen to caller).

Fix that by adding tty_driver_kref_put to the fail path.

I will refactor the code later. This is for the ease of backporting to stable.

Introduced-in: v2.6.28-rc2

---
 drivers/tty/tty_io.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/tty/tty_io.c +1 -0
index 4ca4bcd..6913da8 100644
@@ -1873,6 +1873,7 @@ got_driver:
 		if (IS_ERR(tty)) {
 			tty_unlock();
 			mutex_unlock(&tty_mutex);
+			tty_driver_kref_put(driver);
 			return PTR_ERR(tty);
 		}
 	}
Signature · 1 line
1.7.7
#71 lore raw

PATCH 69/79 TTY: make tty_add_file non-failing

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

If tty_add_file fails at the point it is now, we have to revert all the changes we did to the tty. It means either decrease all refcounts if this was a tty reopen or delete the tty if it was newly allocated.

There was a try to fix this in v3.0-rc2 using tty_release in 0259894c7 (TTY: fix fail path in tty_open). But instead it introduced a NULL dereference. It's because tty_release dereferences filp->private_data, but that one is set even in our tty_add_file. And when tty_add_file fails, it's still NULL/garbage. Hence tty_release cannot be called there.

To circumvent the original leak (and the current NULL deref) we split tty_add_file into two functions, making the latter non-failing. In that case we may do the former early in open, where handling failures is easy. The latter stays as it is now. So there is no change in functionality.

The original bug (leak) was introduced by f573bd176 (tty: Remove __GFP_NOFAIL from tty_add_file()). Thanks Dan for reporting this.

Later, we may split tty_release into more functions and call only some of them in this fail path instead. (If at all possible.)

Introduced-in: v2.6.37-rc2

---
 drivers/tty/pty.c    |   16 +++++++++++-----
 drivers/tty/tty_io.c |   47 +++++++++++++++++++++++++++++++++++------------
 include/linux/tty.h  |    4 +++-
 3 files changed, 49 insertions(+), 18 deletions(-)
drivers/tty/pty.c +11 -5
index 98b6e3b..7613f95 100644
@@ -657,12 +657,18 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 
 	nonseekable_open(inode, filp);
 
+	retval = tty_alloc_file(filp);
+	if (retval)
+		return retval;
+
 	/* find a device that is not in use. */
 	tty_lock();
 	index = devpts_new_index(inode);
 	tty_unlock();
-	if (index < 0)
-		return index;
+	if (index < 0) {
+		retval = index;
+		goto err_file;
+	}
 
 	mutex_lock(&tty_mutex);
 	tty_lock();
@@ -676,9 +682,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 
 	set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
 
-	retval = tty_add_file(tty, filp);
-	if (retval)
-		goto out;
+	tty_add_file(tty, filp);
 
 	retval = devpts_pty_new(inode, tty->link);
 	if (retval)
@@ -697,6 +701,8 @@ out2:
 out:
 	devpts_kill_index(inode, index);
 	tty_unlock();
+err_file:
+	tty_free_file(filp);
 	return retval;
 }
 
drivers/tty/tty_io.c +35 -12

111 lines not on this page · raw message

include/linux/tty.h +3 -1
index 64c12a3..ff2925a 100644
@@ -471,7 +471,9 @@ extern void proc_clear_tty(struct task_struct *p);
 extern struct tty_struct *get_current_tty(void);
 extern void tty_default_fops(struct file_operations *fops);
 extern struct tty_struct *alloc_tty_struct(void);
-extern int tty_add_file(struct tty_struct *tty, struct file *file);
+extern int tty_alloc_file(struct file *file);
+extern void tty_add_file(struct tty_struct *tty, struct file *file);
+extern void tty_free_file(struct file *file);
 extern void free_tty_struct(struct tty_struct *tty);
 extern void initialize_tty_struct(struct tty_struct *tty,
 		struct tty_driver *driver, int idx);
Signature · 1 line
1.7.7
#72 lore raw

PATCH 70/79 TTY: pty, release tty in all ptmx_open fail paths

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

Mistakenly, commit 64ba3dc3143d (tty: never hold BTM while getting tty_mutex) switched one fail path in ptmx_open to not free the newly allocated tty.

Fix that by jumping to the appropriate place. And rename the labels so that it's clear what is going on there.

Introduced-in: v2.6.36-rc2

---
 drivers/tty/pty.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)
drivers/tty/pty.c +5 -5
index 7613f95..2feea63 100644
@@ -686,15 +686,15 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 
 	retval = devpts_pty_new(inode, tty->link);
 	if (retval)
-		goto out1;
+		goto err_release;
 
 	retval = ptm_driver->ops->open(tty, filp);
 	if (retval)
-		goto out2;
-out1:
+		goto err_release;
+
 	tty_unlock();
-	return retval;
-out2:
+	return 0;
+err_release:
 	tty_unlock();
 	tty_release(inode, filp);
 	return retval;
Signature · 1 line
1.7.7
#73 lore raw

PATCH 71/79 TTY: call tty_driver_lookup_tty unconditionally

In reply to Greg Kroah-Hartman

From: Jiri Slaby <[email protected]>

Commit 4a2b5fddd5 (Move tty lookup/reopen to caller) made the call to tty_driver_lookup_tty conditional in tty_open. It doesn't look like it was an intention. Or if it was, it was not documented in the changelog and the code now looks weird. For example there would be no need to remember the tty driver and tty index. Further the condition depends on a tty which we drop a reference of already.

If I'm looking correctly, this should not matter thanks to the locking currently done there. Thus, tty_driver->ttys[idx] cannot change under our hands. But anyway, it makes sense to change that to the old behaviour.

Introduced-in: v2.6.28-rc2

---
 drivers/tty/tty_io.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)
drivers/tty/tty_io.c +9 -12
index 767ecbb..0425170 100644
@@ -1821,7 +1821,7 @@ int tty_release(struct inode *inode, struct file *filp)
 
 static int tty_open(struct inode *inode, struct file *filp)
 {
-	struct tty_struct *tty = NULL;
+	struct tty_struct *tty;
 	int noctty, retval;
 	struct tty_driver *driver;
 	int index;
@@ -1892,17 +1892,14 @@ retry_open:
 		return -ENODEV;
 	}
 got_driver:
-	if (!tty) {
-		/* check whether we're reopening an existing tty */
-		tty = tty_driver_lookup_tty(driver, inode, index);
-
-		if (IS_ERR(tty)) {
-			tty_unlock();
-			mutex_unlock(&tty_mutex);
-			tty_driver_kref_put(driver);
-			tty_free_file(filp);
-			return PTR_ERR(tty);
-		}
+	/* check whether we're reopening an existing tty */
+	tty = tty_driver_lookup_tty(driver, inode, index);
+	if (IS_ERR(tty)) {
+		tty_unlock();
+		mutex_unlock(&tty_mutex);
+		tty_driver_kref_put(driver);
+		tty_free_file(filp);
+		return PTR_ERR(tty);
 	}
 
 	if (tty) {
Signature · 1 line
1.7.7
#74 lore raw

PATCH 72/79 tty/serial: RS485 bindings for device tree

In reply to Greg Kroah-Hartman

From: Nicolas Ferre <[email protected]>

Generic bindings for RS485 feature included in some UARTs. Those bindings have to be used withing an UART device tree node. Documentation updated to link to the bindings definition.

---
 Documentation/devicetree/bindings/serial/rs485.txt |   31 ++++++++++++++++++++
 .../devicetree/bindings/tty/serial/atmel-usart.txt |   27 +++++++++++++++++
 Documentation/serial/serial-rs485.txt              |    5 +++
 3 files changed, 63 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/serial/rs485.txt
 create mode 100644 Documentation/devicetree/bindings/tty/serial/atmel-usart.txt
Documentation/devicetree/bindings/serial/rs485.txt new file +31 -0
new file mode 100644
index 0000000..1e753c6
@@ -0,0 +1,31 @@
+* RS485 serial communications
+
+The RTS signal is capable of automatically controlling line direction for
+the built-in half-duplex mode.
+The properties described hereafter shall be given to a half-duplex capable
+UART node.
+
+Required properties:
+- rs485-rts-delay: prop-encoded-array <a b> where:
+  * a is the delay beteween rts signal and beginning of data sent in milliseconds.
+      it corresponds to the delay before sending data.
+  * b is the delay between end of data sent and rts signal in milliseconds
+      it corresponds to the delay after sending data and actual release of the line.
+
+Optional properties:
+- linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485
+  feature at boot time. It can be disabled later with proper ioctl.
+- rs485-rx-during-tx: empty property that enables the receiving of data even
+  whilst sending data.
+
+RS485 example for Atmel USART:
+	usart0: serial@fff8c000 {
+		compatible = "atmel,at91sam9260-usart";
+		reg = <0xfff8c000 0x4000>;
+		interrupts = <7>;
+		atmel,use-dma-rx;
+		atmel,use-dma-tx;
+		linux,rs485-enabled-at-boot-time;
+		rs485-rts-delay = <0 200>;		// in milliseconds
+	};
+
Documentation/devicetree/bindings/tty/serial/atmel-usart.txt new file +27 -0
new file mode 100644
index 0000000..a49d9a1
@@ -0,0 +1,27 @@
+* Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART)
+
+Required properties:
+- compatible: Should be "atmel,<chip>-usart"
+  The compatible <chip> indicated will be the first SoC to support an
+  additional mode or an USART new feature.
+- reg: Should contain registers location and length
+- interrupts: Should contain interrupt
+
+Optional properties:
+- atmel,use-dma-rx: use of PDC or DMA for receiving data
+- atmel,use-dma-tx: use of PDC or DMA for transmitting data
+
+<chip> compatible description:
+- at91rm9200:  legacy USART support
+- at91sam9260: generic USART implementation for SAM9 SoCs
+
+Example:
+
+	usart0: serial@fff8c000 {
+		compatible = "atmel,at91sam9260-usart";
+		reg = <0xfff8c000 0x4000>;
+		interrupts = <7>;
+		atmel,use-dma-rx;
+		atmel,use-dma-tx;
+	};
+
Documentation/serial/serial-rs485.txt +5 -0
index c8878f8..079cb3d 100644
@@ -28,6 +28,10 @@
    RS485 communications. This data structure is used to set and configure RS485
    parameters in the platform data and in ioctls.
 
+   The device tree can also provide RS485 boot time parameters (see [2]
+   for bindings). The driver is in charge of filling this data structure from
+   the values given by the device tree.
+
    Any driver for devices capable of working both as RS232 and RS485 should
    provide at least the following ioctls:
 
@@ -121,3 +125,4 @@
 5. REFERENCES
 
  [1]	include/linux/serial.h
+ [2]	Documentation/devicetree/bindings/serial/rs485.txt
Signature · 1 line
1.7.7
#75 lore raw

PATCH 73/79 tty/serial: atmel_serial: change platform_data variable name

In reply to Greg Kroah-Hartman

From: Nicolas Ferre <[email protected]>

Easier to follow if platform_data name is pdata.

---
 drivers/tty/serial/atmel_serial.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
drivers/tty/serial/atmel_serial.c +7 -7
index c7232a9..a507daa 100644
@@ -1417,13 +1417,13 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 				      struct platform_device *pdev)
 {
 	struct uart_port *port = &atmel_port->uart;
-	struct atmel_uart_data *data = pdev->dev.platform_data;
+	struct atmel_uart_data *pdata = pdev->dev.platform_data;
 
 	port->iotype		= UPIO_MEM;
 	port->flags		= UPF_BOOT_AUTOCONF;
 	port->ops		= &atmel_pops;
 	port->fifosize		= 1;
-	port->line		= data->num;
+	port->line		= pdata->num;
 	port->dev		= &pdev->dev;
 	port->mapbase	= pdev->resource[0].start;
 	port->irq	= pdev->resource[1].start;
@@ -1433,9 +1433,9 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 
 	memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
-	if (data->regs)
+	if (pdata->regs)
 		/* Already mapped by setup code */
-		port->membase = data->regs;
+		port->membase = pdata->regs;
 	else {
 		port->flags	|= UPF_IOREMAP;
 		port->membase	= NULL;
@@ -1450,9 +1450,9 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 		/* only enable clock when USART is in use */
 	}
 
-	atmel_port->use_dma_rx = data->use_dma_rx;
-	atmel_port->use_dma_tx = data->use_dma_tx;
-	atmel_port->rs485	= data->rs485;
+	atmel_port->use_dma_rx = pdata->use_dma_rx;
+	atmel_port->use_dma_tx = pdata->use_dma_tx;
+	atmel_port->rs485	= pdata->rs485;
 	/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
 	if (atmel_port->rs485.flags & SER_RS485_ENABLED)
 		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
Signature · 1 line
1.7.7
#76 lore raw

PATCH 74/79 tty/serial: atmel_serial: whitespace and braces modifications

In reply to Greg Kroah-Hartman

From: Nicolas Ferre <[email protected]>

---
 drivers/tty/serial/atmel_serial.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)
drivers/tty/serial/atmel_serial.c +5 -4
index a507daa..bb72354 100644
@@ -1433,10 +1433,10 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 
 	memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
-	if (pdata->regs)
+	if (pdata->regs) {
 		/* Already mapped by setup code */
 		port->membase = pdata->regs;
-	else {
+	} else {
 		port->flags	|= UPF_IOREMAP;
 		port->membase	= NULL;
 	}
@@ -1450,9 +1450,10 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 		/* only enable clock when USART is in use */
 	}
 
-	atmel_port->use_dma_rx = pdata->use_dma_rx;
-	atmel_port->use_dma_tx = pdata->use_dma_tx;
+	atmel_port->use_dma_rx	= pdata->use_dma_rx;
+	atmel_port->use_dma_tx	= pdata->use_dma_tx;
 	atmel_port->rs485	= pdata->rs485;
+
 	/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
 	if (atmel_port->rs485.flags & SER_RS485_ENABLED)
 		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
Signature · 1 line
1.7.7
#77 lore raw

PATCH 75/79 tty/serial: atmel_serial: auto-enumerate ports

In reply to Greg Kroah-Hartman

From: Nicolas Ferre <[email protected]>

If no platform data provided to enumerate ports, use a bit field to choose port number and check if port is already initialized. Use this mechanism for both console and plain serial ports.

---
 drivers/tty/serial/atmel_serial.c |   44 ++++++++++++++++++++++++++++++------
 1 files changed, 36 insertions(+), 8 deletions(-)
drivers/tty/serial/atmel_serial.c +36 -8
index bb72354..1074329 100644
@@ -157,6 +157,7 @@ struct atmel_uart_port {
 };
 
 static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
+static unsigned long atmel_ports_in_use;
 
 #ifdef SUPPORT_SYSRQ
 static struct console atmel_console;
@@ -1423,7 +1424,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 	port->flags		= UPF_BOOT_AUTOCONF;
 	port->ops		= &atmel_pops;
 	port->fifosize		= 1;
-	port->line		= pdata->num;
 	port->dev		= &pdev->dev;
 	port->mapbase	= pdev->resource[0].start;
 	port->irq	= pdev->resource[1].start;
@@ -1613,10 +1613,15 @@ static struct console atmel_console = {
 static int __init atmel_console_init(void)
 {
 	if (atmel_default_console_device) {
-		add_preferred_console(ATMEL_DEVICENAME,
-				      atmel_default_console_device->id, NULL);
-		atmel_init_port(&atmel_ports[atmel_default_console_device->id],
-				atmel_default_console_device);
+		int id = atmel_default_console_device->id;
+		struct atmel_uart_port *port = &atmel_ports[id];
+
+		set_bit(id, &atmel_ports_in_use);
+		port->backup_imr = 0;
+		port->uart.line = id;
+
+		add_preferred_console(ATMEL_DEVICENAME, id, NULL);
+		atmel_init_port(port, atmel_default_console_device);
 		register_console(&atmel_console);
 	}
 
@@ -1715,12 +1720,33 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
 	struct atmel_uart_port *port;
 	struct atmel_uart_data *pdata = pdev->dev.platform_data;
 	void *data;
-	int ret;
+	int ret = -ENODEV;
 
 	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
-	port = &atmel_ports[pdata->num];
+	if (pdata)
+		ret = pdata->num;
+
+	if (ret < 0)
+		/* port id not found in platform data:
+		 * auto-enumerate it */
+		ret = find_first_zero_bit(&atmel_ports_in_use,
+				sizeof(atmel_ports_in_use));
+
+	if (ret > ATMEL_MAX_UART) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	if (test_and_set_bit(ret, &atmel_ports_in_use)) {
+		/* port already in use */
+		ret = -EBUSY;
+		goto err;
+	}
+
+	port = &atmel_ports[ret];
 	port->backup_imr = 0;
+	port->uart.line = ret;
 
 	atmel_init_port(port, pdev);
 
@@ -1766,7 +1792,7 @@ err_alloc_ring:
 		clk_put(port->clk);
 		port->clk = NULL;
 	}
-
+err:
 	return ret;
 }
 
@@ -1786,6 +1812,8 @@ static int __devexit 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);
+
 	clk_put(atmel_port->clk);
 
 	return ret;
Signature · 1 line
1.7.7
#78 lore raw

PATCH 76/79 tty/serial: atmel_serial: add device tree support

In reply to Greg Kroah-Hartman

From: Nicolas Ferre <[email protected]>

Will use aliases to enumerate ports, if available.

---
 drivers/tty/serial/atmel_serial.c |   79 +++++++++++++++++++++++++++++++++----
 1 files changed, 71 insertions(+), 8 deletions(-)
drivers/tty/serial/atmel_serial.c +71 -8
index 1074329..fc4081e 100644
@@ -33,6 +33,8 @@
 #include <linux/sysrq.h>
 #include <linux/tty_flip.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/atmel_pdc.h>
 #include <linux/atmel_serial.h>
@@ -163,6 +165,16 @@ static unsigned long atmel_ports_in_use;
 static struct console atmel_console;
 #endif
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_serial_dt_ids[] = {
+	{ .compatible = "atmel,at91rm9200-usart" },
+	{ .compatible = "atmel,at91sam9260-usart" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_serial_dt_ids);
+#endif
+
 static inline struct atmel_uart_port *
 to_atmel_uart_port(struct uart_port *uart)
 {
@@ -1411,6 +1423,48 @@ static struct uart_ops atmel_pops = {
 #endif
 };
 
+static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
+					 struct device_node *np)
+{
+	u32 rs485_delay[2];
+
+	/* DMA/PDC usage specification */
+	if (of_get_property(np, "atmel,use-dma-rx", NULL))
+		atmel_port->use_dma_rx	= 1;
+	else
+		atmel_port->use_dma_rx	= 0;
+	if (of_get_property(np, "atmel,use-dma-tx", NULL))
+		atmel_port->use_dma_tx	= 1;
+	else
+		atmel_port->use_dma_tx	= 0;
+
+	/* rs485 properties */
+	if (of_property_read_u32_array(np, "rs485-rts-delay",
+					    rs485_delay, 2) == 0) {
+		struct serial_rs485 *rs485conf = &atmel_port->rs485;
+
+		rs485conf->delay_rts_before_send = rs485_delay[0];
+		rs485conf->delay_rts_after_send = rs485_delay[1];
+		rs485conf->flags = 0;
+
+		if (rs485conf->delay_rts_before_send == 0 &&
+		    rs485conf->delay_rts_after_send == 0) {
+			rs485conf->flags |= SER_RS485_RTS_ON_SEND;
+		} else {
+			if (rs485conf->delay_rts_before_send)
+				rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND;
+			if (rs485conf->delay_rts_after_send)
+				rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
+		}
+
+		if (of_get_property(np, "rs485-rx-during-tx", NULL))
+			rs485conf->flags |= SER_RS485_RX_DURING_TX;
+
+		if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL))
+			rs485conf->flags |= SER_RS485_ENABLED;
+	}
+}
+
 /*
  * Configure the port from the platform device resource info.
  */
@@ -1420,6 +1474,14 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 	struct uart_port *port = &atmel_port->uart;
 	struct atmel_uart_data *pdata = pdev->dev.platform_data;
 
+	if (pdev->dev.of_node) {
+		atmel_of_init_port(atmel_port, pdev->dev.of_node);
+	} else {
+		atmel_port->use_dma_rx	= pdata->use_dma_rx;
+		atmel_port->use_dma_tx	= pdata->use_dma_tx;
+		atmel_port->rs485	= pdata->rs485;
+	}
+
 	port->iotype		= UPIO_MEM;
 	port->flags		= UPF_BOOT_AUTOCONF;
 	port->ops		= &atmel_pops;
@@ -1433,7 +1495,7 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 
 	memset(&atmel_port->rx_ring, 0, sizeof(atmel_port->rx_ring));
 
-	if (pdata->regs) {
+	if (pdata && pdata->regs) {
 		/* Already mapped by setup code */
 		port->membase = pdata->regs;
 	} else {
@@ -1450,10 +1512,6 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 		/* only enable clock when USART is in use */
 	}
 
-	atmel_port->use_dma_rx	= pdata->use_dma_rx;
-	atmel_port->use_dma_tx	= pdata->use_dma_tx;
-	atmel_port->rs485	= pdata->rs485;
-
 	/* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
 	if (atmel_port->rs485.flags & SER_RS485_ENABLED)
 		atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
@@ -1718,17 +1776,21 @@ static int atmel_serial_resume(struct platform_device *pdev)
 static int __devinit atmel_serial_probe(struct platform_device *pdev)
 {
 	struct atmel_uart_port *port;
+	struct device_node *np = pdev->dev.of_node;
 	struct atmel_uart_data *pdata = pdev->dev.platform_data;
 	void *data;
 	int ret = -ENODEV;
 
 	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
-	if (pdata)
-		ret = pdata->num;
+	if (np)
+		ret = of_alias_get_id(np, "serial");
+	else
+		if (pdata)
+			ret = pdata->num;
 
 	if (ret < 0)
-		/* port id not found in platform data:
+		/* 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));
@@ -1827,6 +1889,7 @@ static struct platform_driver atmel_serial_driver = {
 	.driver		= {
 		.name	= "atmel_usart",
 		.owner	= THIS_MODULE,
+		.of_match_table	= of_match_ptr(atmel_serial_dt_ids),
 	},
 };
 
Signature · 1 line
1.7.7
#79 lore raw

PATCH 77/79 Revert "TTY: call tty_driver_lookup_tty unconditionally"

In reply to Greg Kroah-Hartman

This reverts commit 631180aca723cb92e128fdac5fd144e913ca84e5.

It caused problems when /dev/tty is a pty:

	https://lkml.org/lkml/2011/10/12/401
Cc Jiri Slaby <[email protected]>
Cc stable <[email protected]>
Cc Sukadev Bhattiprolu <[email protected]>
Cc Alan Cox <[email protected]>
---
 drivers/tty/tty_io.c |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)
drivers/tty/tty_io.c +12 -9
index 0425170..767ecbb 100644
@@ -1821,7 +1821,7 @@ int tty_release(struct inode *inode, struct file *filp)
 
 static int tty_open(struct inode *inode, struct file *filp)
 {
-	struct tty_struct *tty;
+	struct tty_struct *tty = NULL;
 	int noctty, retval;
 	struct tty_driver *driver;
 	int index;
@@ -1892,14 +1892,17 @@ retry_open:
 		return -ENODEV;
 	}
 got_driver:
-	/* check whether we're reopening an existing tty */
-	tty = tty_driver_lookup_tty(driver, inode, index);
-	if (IS_ERR(tty)) {
-		tty_unlock();
-		mutex_unlock(&tty_mutex);
-		tty_driver_kref_put(driver);
-		tty_free_file(filp);
-		return PTR_ERR(tty);
+	if (!tty) {
+		/* check whether we're reopening an existing tty */
+		tty = tty_driver_lookup_tty(driver, inode, index);
+
+		if (IS_ERR(tty)) {
+			tty_unlock();
+			mutex_unlock(&tty_mutex);
+			tty_driver_kref_put(driver);
+			tty_free_file(filp);
+			return PTR_ERR(tty);
+		}
 	}
 
 	if (tty) {
Signature · 1 line
1.7.7
#80 lore raw

PATCH 78/79 tty/serial: atmel_serial: bootconsole removed from auto-enumerates

In reply to Greg Kroah-Hartman

From: Nicolas Ferre <[email protected]>

Auto-enumerate mechanism conflicts with bootconsoles: remove the usage counter for this type of consoles.

---
 drivers/tty/serial/atmel_serial.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/tty/serial/atmel_serial.c +0 -1
index fc4081e..358bbb2 100644
@@ -1674,7 +1674,6 @@ static int __init atmel_console_init(void)
 		int id = atmel_default_console_device->id;
 		struct atmel_uart_port *port = &atmel_ports[id];
 
-		set_bit(id, &atmel_ports_in_use);
 		port->backup_imr = 0;
 		port->uart.line = id;
 
Signature · 1 line
1.7.7
#81 lore raw

PATCH 79/79 TTY: serial_core: Fix crash if DCD drop during suspend

In reply to Greg Kroah-Hartman

From: Doug Anderson <[email protected]>

This crash was showing up 100% of the time on Tegra CPUs when an agetty was running on the serial port and the console was not running on the serial port. The reason the Tegra saw it so reliably is that the Tegra CPU internally ties DTR to DCD/DSR. That means when we dropped DTR during suspend we would get always get an immediate DCD drop.

The specific order of operations that were running:
* uart_suspend_port() would be called to put the uart in suspend mode
* we'd drop DTR (ops->set_mctrl(uport, 0)).
* the DTR drop would be looped back in the CPU to be a DCD drop.
* the DCD drop would look to the serial driver as a hangup
* the hangup would call uart_shutdown()
* ... suspend / resume happens ...
* uart_resume_port() would be called and run the code in the (port->flags & ASYNC_SUSPENDED) block, which would startup the port (and enable tx again).
* Since the UART would be available for tx, we'd immediately get an interrupt, eventually calling transmit_chars()
* The transmit_chars() function would crash. The first crash would be a dereference of a NULL tty member, but since the port has been shutdown that was just a symptom.

I have proposed a patch that would fix the Tegra CPUs here (see
https://lkml.org/lkml/2011/10/11/444 - tty/serial: Prevent drop of DCD on suspend for Tegra UARTs). However, even with that fix it is still possible for systems that have an externally visible DCD line to see a crash if the DCD drops at just the right time during suspend: thus this patch is still useful.

---
 drivers/tty/serial/serial_core.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/tty/serial/serial_core.c +7 -0
index e562b12..9f72be2 100644
@@ -244,6 +244,13 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
 	}
 
 	/*
+	 * It's possible for shutdown to be called after suspend if we get
+	 * a DCD drop (hangup) at just the right time.  Clear suspended bit so
+	 * we don't try to resume a port that has been shutdown.
+	 */
+	clear_bit(ASYNCB_SUSPENDED, &port->flags);
+
+	/*
 	 * Free the transmit buffer page.
 	 */
 	if (state->xmit.buf) {
Signature · 1 line
1.7.7
#82 lore raw
In reply to Greg KH
Quoted 4 lines · Greg KH

The one in 8250_pci.c is trivial to fix, the atmel_serial one isn't as easy, but I'm sure you can figure it out :)  If you want me to do the merge for it, I'll be glad to do so, just let me know.

So I figured it out, but please double-check, especially since it seems to be some arm-only driver that I can't even compile-test my resolution.

Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#83 lore raw
Quoted 9 lines · Linus Torvalds
Quoted 4 lines · Greg KH

The one in 8250_pci.c is trivial to fix, the atmel_serial one isn't as easy, but I'm sure you can figure it out :)  If you want me to do the merge for it, I'll be glad to do so, just let me know.

So I figured it out, but please double-check, especially since it seems to be some arm-only driver that I can't even compile-test my resolution.

I think it looks correct, but yeah, as I can't build it either, it's tough to tell.

Nicolas, can you verify that Linus's merge was done correctly? If not, can you send a patch? It is commit efb8d21b2c6db3497655cc6a033ae8a9883e4063 in Linus's tree right now.

thanks,

greg k-h

#84 lore raw
Quoted 11 lines · Greg KH
Quoted 9 lines · Linus Torvalds
Quoted 4 lines · Greg KH

The one in 8250_pci.c is trivial to fix, the atmel_serial one isn't as easy, but I'm sure you can figure it out :)  If you want me to do the merge for it, I'll be glad to do so, just let me know.

So I figured it out, but please double-check, especially since it seems to be some arm-only driver that I can't even compile-test my resolution.

Quoted 6 lines

I think it looks correct, but yeah, as I can't build it either, it's tough to tell.

Nicolas, can you verify that Linus's merge was done correctly? If not, can you send a patch? It is commit efb8d21b2c6db3497655cc6a033ae8a9883e4063 in Linus's tree right now.

tryed to build efb8d21 with at91cap9adk_defconfig + DT + 8250 but it fails:

drivers/tty/serial/atmel_serial.c: In function 'atmel_serial_probe':
drivers/tty/serial/atmel_serial.c:1788:3: error: implicit declaration of function 'of_alias_get_id' [-Werror=implicit-function-declaration] drivers/tty/serial/atmel_serial.c: At top level:
drivers/tty/serial/atmel_serial.c:1893:3: error: implicit declaration of function 'of_match_ptr' [-Werror=implicit-function-declaration] drivers/tty/serial/atmel_serial.c:1893:3: error: initializer element is not constant drivers/tty/serial/atmel_serial.c:1893:3: error: (near initialization for 'atmel_serial_driver.driver.of_match_table')
cc1: some warnings being treated as errors

there is not mention of such (new) of_match_ptr macro anywhere in Linus' tree.

Regards,
Domenico
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#85 lore raw
Quoted 25 lines · Domenico Andreoli
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines

The one in 8250_pci.c is trivial to fix, the atmel_serial one isn't as easy, but I'm sure you can figure it out :)  If you want me to do the merge for it, I'll be glad to do so, just let me know.

So I figured it out, but please double-check, especially since it seems to be some arm-only driver that I can't even compile-test my resolution.

Quoted 6 lines

I think it looks correct, but yeah, as I can't build it either, it's tough to tell.

Nicolas, can you verify that Linus's merge was done correctly? If not, can you send a patch? It is commit efb8d21b2c6db3497655cc6a033ae8a9883e4063 in Linus's tree right now.

tryed to build efb8d21 with at91cap9adk_defconfig + DT + 8250 but it fails:

drivers/tty/serial/atmel_serial.c: In function 'atmel_serial_probe':
drivers/tty/serial/atmel_serial.c:1788:3: error: implicit declaration of function 'of_alias_get_id' [-Werror=implicit-function-declaration] drivers/tty/serial/atmel_serial.c: At top level:
drivers/tty/serial/atmel_serial.c:1893:3: error: implicit declaration of function 'of_match_ptr' [-Werror=implicit-function-declaration] drivers/tty/serial/atmel_serial.c:1893:3: error: initializer element is not constant drivers/tty/serial/atmel_serial.c:1893:3: error: (near initialization for 'atmel_serial_driver.driver.of_match_table')
cc1: some warnings being treated as errors

Quoted 1 line

there is not mention of such (new) of_match_ptr macro anywhere in Linus' tree.

Yes, it's depending on this one, which I believe is queued in Grant's tree but not yet merged:

commit 3a1e362e3f3cd571b3974b8d44b8e358ec7a098c
Author: Ben Dooks <[email protected]>
Date: Wed Aug 3 10:11:42 2011 +0100

OF: Add of_match_ptr() macro

Add a macro of_match_ptr() that allows the .of_match_table entry in the driver structures to be assigned without having an #ifdef xxx NULL for the case that OF is not enabled

Signature · 7 lines
Jiri Kosina
SUSE Labs

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#86 lore raw
In reply to Greg KH

On 10/26/2011 03:34 PM, Greg KH :

Quoted 11 lines · Linus Torvalds
Quoted 9 lines · Greg KH
Quoted 4 lines

The one in 8250_pci.c is trivial to fix, the atmel_serial one isn't as easy, but I'm sure you can figure it out :) If you want me to do the merge for it, I'll be glad to do so, just let me know.

So I figured it out, but please double-check, especially since it seems to be some arm-only driver that I can't even compile-test my resolution.

Quoted 6 lines

I think it looks correct, but yeah, as I can't build it either, it's tough to tell.

Nicolas, can you verify that Linus's merge was done correctly? If not, can you send a patch? It is commit efb8d21b2c6db3497655cc6a033ae8a9883e4063 in Linus's tree right now.

Yes, I have verified Linus's merge and it is correct.

Stephen hit this merge conflict in linux-next yesterday and I sent the fixup as "[PATCH] tty/serial: atmel_serial: fixup merge conflict". Anyway, sorry for the noise it has produced...

For the functions and macros that has been highlighted by Domenico in his attempt to compile the atmel_serial driver, they shall come with "device tree" git tree pull.

Best regards,

Signature · 1 line
Nicolas Ferre