TTY and Serial driver update for 4.7-rc1

Here's the large TTY and Serial driver update for 4.7-rc1.
 
 A few new serial drivers are added here, and Peter has fixed a bunch of
 long-standing bugs in the tty layer and serial drivers as normal.  Full
 details in the shortlog.
 
 All of these have been in linux-next for a while with no reported issues.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlc/0/oACgkQMUfUDdst+ynzyQCgsa54VNijdAzU6AA5HEfqmf2M
 cGMAn1boH7hUWlAbJmzzihx4JASoGjYW
 =V5VH
 -----END PGP SIGNATURE-----

Merge tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty and serial driver updates from Greg KH:
 "Here's the large TTY and Serial driver update for 4.7-rc1.

  A few new serial drivers are added here, and Peter has fixed a bunch
  of long-standing bugs in the tty layer and serial drivers as normal.
  Full details in the shortlog.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (88 commits)
  MAINTAINERS: 8250: remove website reference
  serial: core: Fix port mutex assert if lockdep disabled
  serial: 8250_dw: fix wrong logic in dw8250_check_lcr()
  tty: vt, finish looping on duplicate
  tty: vt, return error when con_startup fails
  QE-UART: add "fsl,t1040-ucc-uart" to of_device_id
  serial: mctrl_gpio: Drop support for out1-gpios and out2-gpios
  serial: 8250dw: Add device HID for future AMD UART controller
  Fix OpenSSH pty regression on close
  serial: mctrl_gpio: add IRQ locking
  serial: 8250: Integrate Fintek into 8250_base
  serial: mps2-uart: add support for early console
  serial: mps2-uart: add MPS2 UART driver
  dt-bindings: document the MPS2 UART bindings
  serial: sirf: Use generic uart-has-rtscts DT property
  serial: sirf: Introduce helper variable struct device_node *np
  serial: mxs-auart: Use generic uart-has-rtscts DT property
  serial: imx: Use generic uart-has-rtscts DT property
  doc: DT: Add Generic Serial Device Tree Bindings
  serial: 8250: of: Make tegra_serial_handle_break() static
  ...
This commit is contained in:
Linus Torvalds 2016-05-20 20:57:27 -07:00
commit e10abc629f
104 changed files with 2526 additions and 1172 deletions

View File

@ -0,0 +1,19 @@
ARM MPS2 UART
Required properties:
- compatible : Should be "arm,mps2-uart"
- reg : Address and length of the register set
- interrupts : Reference to the UART RX, TX and overrun interrupts
Required clocking property:
- clocks : The input clock of the UART
Examples:
uart0: serial@40004000 {
compatible = "arm,mps2-uart";
reg = <0x40004000 0x1000>;
interrupts = <0 1 12>;
clocks = <&sysclk>;
};

View File

@ -6,7 +6,7 @@ Required properties:
- interrupts : Should contain uart interrupt
Optional properties:
- fsl,uart-has-rtscts : Indicate the uart has rts and cts
- uart-has-rtscts : Indicate the uart has rts and cts
- fsl,irda-mode : Indicate the uart supports irda mode
- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
in DCE mode by default.
@ -24,6 +24,6 @@ uart1: serial@73fbc000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x73fbc000 0x4000>;
interrupts = <31>;
fsl,uart-has-rtscts;
uart-has-rtscts;
fsl,dte-mode;
};

View File

@ -1,8 +1,10 @@
* Freescale MXS Application UART (AUART)
Required properties:
- compatible : Should be "fsl,<soc>-auart". The supported SoCs include
imx23 and imx28.
Required properties for all SoCs:
- compatible : Should be one of fallowing variants:
"fsl,imx23-auart" - Freescale i.MX23
"fsl,imx28-auart" - Freescale i.MX28
"alphascale,asm9260-auart" - Alphascale ASM9260
- reg : Address and length of the register set for the device
- interrupts : Should contain the auart interrupt numbers
- dmas: DMA specifier, consisting of a phandle to DMA controller node
@ -10,8 +12,14 @@ Required properties:
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: "rx" for RX channel, "tx" for TX channel.
Required properties for "alphascale,asm9260-auart":
- clocks : the clocks feeding the watchdog timer. See clock-bindings.txt
- clock-names : should be set to
"mod" - source for tick counter.
"ahb" - ahb gate.
Optional properties:
- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines
- uart-has-rtscts : Indicate the UART has RTS and CTS lines
for hardware flow control,
it also means you enable the DMA support for this UART.
- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD

View File

@ -0,0 +1,57 @@
Generic Serial DT Bindings
This document lists a set of generic properties for describing UARTs in a
device tree. Whether these properties apply to a particular device depends on
the DT bindings for the actual device.
Optional properties:
- cts-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be
used as the UART's CTS line.
- dcd-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be
used as the UART's DCD line.
- dsr-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be
used as the UART's DSR line.
- dtr-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be
used as the UART's DTR line.
- rng-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be
used as the UART's RNG line.
- rts-gpios: Must contain a GPIO specifier, referring to the GPIO pin to be
used as the UART's RTS line.
- uart-has-rtscts: The presence of this property indicates that the
UART has dedicated lines for RTS/CTS hardware flow control, and that
they are available for use (wired and enabled by pinmux configuration).
This depends on both the UART hardware and the board wiring.
Note that this property is mutually-exclusive with "cts-gpios" and
"rts-gpios" above.
Examples:
uart1: serial@48022000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart2";
clock-frequency = <48000000>;
reg = <0x48022000 0x2000>;
interrupts = <73>;
dmas = <&edma 28 0>, <&edma 29 0>;
dma-names = "tx", "rx";
dtr-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
dsr-gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
dcd-gpios = <&gpio2 24 GPIO_ACTIVE_LOW>;
rng-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>;
cts-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
rts-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
status = "okay";
};
scifa4: serial@e6c80000 {
compatible = "renesas,scifa-sh73a0", "renesas,scifa";
reg = <0xe6c80000 0x100>;
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>;
clock-names = "fck";
power-domains = <&pd_a3sp>;
uart-has-rtscts;
status = "okay";
};

View File

@ -9,9 +9,9 @@ Required properties:
- clocks : Should contain uart clock number
Optional properties:
- sirf,uart-has-rtscts: we have hardware flow controller pins in hardware
- rts-gpios: RTS pin for USP-based UART if sirf,uart-has-rtscts is true
- cts-gpios: CTS pin for USP-based UART if sirf,uart-has-rtscts is true
- uart-has-rtscts: we have hardware flow controller pins in hardware
- rts-gpios: RTS pin for USP-based UART if uart-has-rtscts is true
- cts-gpios: CTS pin for USP-based UART if uart-has-rtscts is true
Example:
@ -28,7 +28,7 @@ On the board-specific dts, we can put rts-gpios and cts-gpios like
usp@b0090000 {
compatible = "sirf,prima2-usp-uart";
sirf,uart-has-rtscts;
uart-has-rtscts;
rts-gpios = <&gpio 15 0>;
cts-gpios = <&gpio 46 0>;
};

View File

@ -1054,6 +1054,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
the driver will use only 32-bit accessors to read/write
the device registers.
meson,<addr>
Start an early, polled-mode console on a meson serial
port at the specified address. The serial port must
already be setup and configured. Options are not yet
supported.
msm_serial,<addr>
Start an early, polled-mode console on an msm serial
port at the specified address. The serial port

View File

@ -210,9 +210,6 @@ TTY_IO_ERROR If set, causes all subsequent userspace read/write
TTY_OTHER_CLOSED Device is a pty and the other side has closed.
TTY_OTHER_DONE Device is a pty and the other side has closed and
all pending input processing has been completed.
TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into
smaller chunks.

View File

@ -175,7 +175,6 @@ F: drivers/net/ethernet/realtek/r8169.c
8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: linux-serial@vger.kernel.org
W: http://serial.sourceforge.net
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
F: drivers/tty/serial/8250*

View File

@ -300,7 +300,7 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
(cmd != TIOCMIWAIT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}

View File

@ -31,13 +31,15 @@ static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
} while (1);
}
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
static void prom_putchar_ar71xx(unsigned char ch)
{
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
__raw_writel(ch, base + UART_TX * 4);
prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
}
static void prom_putchar_ar933x(unsigned char ch)

View File

@ -1101,7 +1101,7 @@ static void dcd_change(MGSLPC_INFO *info, struct tty_struct *tty)
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
if (info->port.flags & ASYNC_CHECK_CD) {
if (tty_port_check_carrier(&info->port)) {
if (debug_level >= DEBUG_LEVEL_ISR)
printk("%s CD now %s...", info->device_name,
(info->serial_signals & SerialSignal_DCD) ? "on" : "off");
@ -1272,7 +1272,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
return 0;
if (!info->tx_buf) {
@ -1311,7 +1311,7 @@ static int startup(MGSLPC_INFO * info, struct tty_struct *tty)
if (tty)
clear_bit(TTY_IO_ERROR, &tty->flags);
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
return 0;
}
@ -1322,7 +1322,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty)
{
unsigned long flags;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
if (debug_level >= DEBUG_LEVEL_INFO)
@ -1361,7 +1361,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty)
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
}
static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty)
@ -1466,15 +1466,8 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty)
}
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
info->port.flags |= ASYNC_CTS_FLOW;
else
info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
info->port.flags &= ~ASYNC_CHECK_CD;
else
info->port.flags |= ASYNC_CHECK_CD;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
/* process tty input control flags */
@ -2246,7 +2239,7 @@ static int mgslpc_ioctl(struct tty_struct *tty,
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCMIWAIT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}
@ -2316,7 +2309,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
/* Handle transition away from B0 status */
if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) {
info->serial_signals |= SerialSignal_DTR;
if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
info->serial_signals |= SerialSignal_RTS;
spin_lock_irqsave(&info->lock, flags);
set_signals(info);
@ -2345,7 +2338,7 @@ static void mgslpc_close(struct tty_struct *tty, struct file * filp)
if (tty_port_close_start(port, tty, filp) == 0)
goto cleanup;
if (port->flags & ASYNC_INITIALIZED)
if (tty_port_initialized(port))
mgslpc_wait_until_sent(tty, info->timeout);
mgslpc_flush_buffer(tty);
@ -2378,7 +2371,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout)
if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent"))
return;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
goto exit;
orig_jiffies = jiffies;

View File

@ -629,8 +629,7 @@ static void ipoctal_hangup(struct tty_struct *tty)
tty_port_hangup(&channel->tty_port);
ipoctal_reset_channel(channel);
clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
tty_port_set_initialized(&channel->tty_port, 0);
wake_up_interruptible(&channel->tty_port.open_wait);
}
@ -642,7 +641,7 @@ static void ipoctal_shutdown(struct tty_struct *tty)
return;
ipoctal_reset_channel(channel);
clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags);
tty_port_set_initialized(&channel->tty_port, 0);
}
static void ipoctal_cleanup(struct tty_struct *tty)

View File

@ -1043,17 +1043,13 @@ isdn_tty_change_speed(modem_info *info)
if (!(cflag & PARODD))
cval |= UART_LCR_EPAR;
if (cflag & CLOCAL)
port->flags &= ~ASYNC_CHECK_CD;
else {
port->flags |= ASYNC_CHECK_CD;
}
tty_port_set_check_carrier(port, ~cflag & CLOCAL);
}
static int
isdn_tty_startup(modem_info *info)
{
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
return 0;
isdn_lock_drivers();
#ifdef ISDN_DEBUG_MODEM_OPEN
@ -1070,7 +1066,7 @@ isdn_tty_startup(modem_info *info)
*/
isdn_tty_change_speed(info);
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
info->send_outstanding = 0;
return 0;
@ -1083,7 +1079,7 @@ isdn_tty_startup(modem_info *info)
static void
isdn_tty_shutdown(modem_info *info)
{
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
@ -1103,7 +1099,7 @@ isdn_tty_shutdown(modem_info *info)
if (info->port.tty)
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
}
/* isdn_tty_write() is the main send-routine. It is called from the upper
@ -1351,7 +1347,7 @@ isdn_tty_tiocmget(struct tty_struct *tty)
if (isdn_tty_paranoia_check(info, tty->name, __func__))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
mutex_lock(&modem_info_mutex);
@ -1378,7 +1374,7 @@ isdn_tty_tiocmset(struct tty_struct *tty,
if (isdn_tty_paranoia_check(info, tty->name, __func__))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
#ifdef ISDN_DEBUG_MODEM_IOCTL
@ -1419,7 +1415,7 @@ isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg)
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_ioctl"))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */
@ -1581,7 +1577,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
* interrupt driver to stop checking the data ready bit in the
* line status register.
*/
if (port->flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(port)) {
tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
/*
* Before we drop DTR, make sure the UART transmitter
@ -1622,7 +1618,7 @@ isdn_tty_hangup(struct tty_struct *tty)
return;
isdn_tty_shutdown(info);
port->count = 0;
port->flags &= ~ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 0);
port->tty = NULL;
wake_up_interruptible(&port->open_wait);
}
@ -1979,7 +1975,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
#endif
if (
#ifndef FIX_FILE_TRANSFER
(info->port.flags & ASYNC_NORMAL_ACTIVE) &&
tty_port_active(&info->port) &&
#endif
(info->isdn_driver == -1) &&
(info->isdn_channel == -1) &&
@ -2018,8 +2014,6 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
return (wret == 2) ? 3 : 0;
}
#define TTY_IS_ACTIVE(info) (info->port.flags & ASYNC_NORMAL_ACTIVE)
int
isdn_tty_stat_callback(int i, isdn_ctrl *c)
{
@ -2077,7 +2071,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
#ifdef ISDN_TTY_STAT_DEBUG
printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);
#endif
if (TTY_IS_ACTIVE(info)) {
if (tty_port_active(&info->port)) {
if (info->dialing == 1) {
info->dialing = 2;
return 1;
@ -2088,7 +2082,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
#ifdef ISDN_TTY_STAT_DEBUG
printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line);
#endif
if (TTY_IS_ACTIVE(info)) {
if (tty_port_active(&info->port)) {
if (info->dialing == 1)
isdn_tty_modem_result(RESULT_BUSY, info);
if (info->dialing > 1)
@ -2118,7 +2112,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
* waiting for it and
* set DCD-bit of its modem-status.
*/
if (TTY_IS_ACTIVE(info) ||
if (tty_port_active(&info->port) ||
(info->port.blocked_open &&
(info->emu.mdmreg[REG_DCD] & BIT_DCD))) {
info->msr |= UART_MSR_DCD;
@ -2145,7 +2139,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
#ifdef ISDN_TTY_STAT_DEBUG
printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line);
#endif
if (TTY_IS_ACTIVE(info)) {
if (tty_port_active(&info->port)) {
#ifdef ISDN_DEBUG_MODEM_HUP
printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n");
#endif
@ -2157,7 +2151,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
#ifdef ISDN_TTY_STAT_DEBUG
printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line);
#endif
if (TTY_IS_ACTIVE(info)) {
if (tty_port_active(&info->port)) {
if (info->dialing) {
info->dialing = 0;
info->last_l2 = -1;
@ -2183,14 +2177,14 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
return 1;
#ifdef CONFIG_ISDN_TTY_FAX
case ISDN_STAT_FAXIND:
if (TTY_IS_ACTIVE(info)) {
if (tty_port_active(&info->port)) {
isdn_tty_fax_command(info, c);
}
break;
#endif
#ifdef CONFIG_ISDN_AUDIO
case ISDN_STAT_AUDIO:
if (TTY_IS_ACTIVE(info)) {
if (tty_port_active(&info->port)) {
switch (c->parm.num[0]) {
case ISDN_AUDIO_DTMF:
if (info->vonline) {
@ -2528,7 +2522,7 @@ isdn_tty_modem_result(int code, modem_info *info)
if (info->closing || (!info->port.tty))
return;
if (info->port.flags & ASYNC_CHECK_CD)
if (tty_port_check_carrier(&info->port))
tty_hangup(info->port.tty);
}
}

View File

@ -895,7 +895,7 @@ static void sdio_uart_set_termios(struct tty_struct *tty,
/* Handle transition away from B0 status */
if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
unsigned int mask = TIOCM_DTR;
if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))
if (!(cflag & CRTSCTS) || !tty_throttled(tty))
mask |= TIOCM_RTS;
sdio_uart_set_mctrl(port, mask);
}

View File

@ -2029,7 +2029,7 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
tty = tty_port_tty_get(&serial->port);
if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
if (tty && tty_throttled(tty)) {
tty_kref_put(tty);
return -1;
}

View File

@ -289,7 +289,7 @@ static void raw3215_timeout(unsigned long __data)
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw->flags &= ~RAW3215_TIMER_RUNS;
if (!(raw->port.flags & ASYNC_SUSPENDED)) {
if (!tty_port_suspended(&raw->port)) {
raw3215_mk_write_req(raw);
raw3215_start_io(raw);
if ((raw->queued_read || raw->queued_write) &&
@ -311,8 +311,7 @@ static void raw3215_timeout(unsigned long __data)
*/
static inline void raw3215_try_io(struct raw3215_info *raw)
{
if (!(raw->port.flags & ASYNC_INITIALIZED) ||
(raw->port.flags & ASYNC_SUSPENDED))
if (!tty_port_initialized(&raw->port) || tty_port_suspended(&raw->port))
return;
if (raw->queued_read != NULL)
raw3215_start_io(raw);
@ -494,7 +493,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
/* While console is frozen for suspend we have no other
* choice but to drop message from the buffer to make
* room for even more messages. */
if (raw->port.flags & ASYNC_SUSPENDED) {
if (tty_port_suspended(&raw->port)) {
raw3215_drop_line(raw);
continue;
}
@ -616,10 +615,10 @@ static int raw3215_startup(struct raw3215_info *raw)
{
unsigned long flags;
if (raw->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&raw->port))
return 0;
raw->line_pos = 0;
raw->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&raw->port, 1);
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_try_io(raw);
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@ -635,8 +634,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
if (!(raw->port.flags & ASYNC_INITIALIZED) ||
(raw->flags & RAW3215_FIXED))
if (!tty_port_initialized(&raw->port) || (raw->flags & RAW3215_FIXED))
return;
/* Wait for outstanding requests, then free irq */
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
@ -650,7 +648,7 @@ static void raw3215_shutdown(struct raw3215_info *raw)
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
remove_wait_queue(&raw->empty_wait, &wait);
set_current_state(TASK_RUNNING);
raw->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&raw->port, 1);
}
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
@ -773,7 +771,7 @@ static int raw3215_pm_stop(struct ccw_device *cdev)
raw = dev_get_drvdata(&cdev->dev);
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
raw->port.flags |= ASYNC_SUSPENDED;
tty_port_set_suspended(&raw->port, 1);
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
return 0;
}
@ -786,7 +784,7 @@ static int raw3215_pm_start(struct ccw_device *cdev)
/* Allow I/O again and flush output buffer. */
raw = dev_get_drvdata(&cdev->dev);
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
raw->port.flags &= ~ASYNC_SUSPENDED;
tty_port_set_suspended(&raw->port, 0);
raw->flags |= RAW3215_FLUSHING;
raw3215_try_io(raw);
raw->flags &= ~RAW3215_FLUSHING;
@ -859,7 +857,7 @@ static void con3215_flush(void)
unsigned long flags;
raw = raw3215[0]; /* console 3215 is the first one */
if (raw->port.flags & ASYNC_SUSPENDED)
if (tty_port_suspended(&raw->port))
/* The console is still frozen for suspend. */
if (ccw_device_force_console(raw->cdev))
/* Forcing didn't work, no panic message .. */

View File

@ -1860,7 +1860,7 @@ static int tty3270_ioctl(struct tty_struct *tty, unsigned int cmd,
tp = tty->driver_data;
if (!tp)
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
return kbd_ioctl(tp->kbd, cmd, arg);
}
@ -1874,7 +1874,7 @@ static long tty3270_compat_ioctl(struct tty_struct *tty,
tp = tty->driver_data;
if (!tp)
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
return kbd_ioctl(tp->kbd, cmd, (unsigned long)compat_ptr(arg));
}

View File

@ -1255,7 +1255,7 @@ static int dgnc_block_til_ready(struct tty_struct *tty,
if (file->f_flags & O_NONBLOCK)
break;
if (tty->flags & (1 << TTY_IO_ERROR)) {
if (tty_io_error(tty)) {
retval = -EIO;
break;
}

View File

@ -1305,7 +1305,7 @@ static void fwtty_set_termios(struct tty_struct *tty, struct ktermios *old)
if ((baud == 0) && (old->c_cflag & CBAUD)) {
port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS);
} else if ((baud != 0) && !(old->c_cflag & CBAUD)) {
if (C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
if (C_CRTSCTS(tty) || !tty_throttled(tty))
port->mctrl |= TIOCM_DTR | TIOCM_RTS;
else
port->mctrl |= TIOCM_DTR;

View File

@ -150,7 +150,7 @@ static void __speakup_paste_selection(struct work_struct *work)
add_wait_queue(&vc->paste_wait, &wait);
while (sel_buffer && sel_buffer_lth > pasted) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_bit(TTY_THROTTLED, &tty->flags)) {
if (tty_throttled(tty)) {
schedule();
continue;
}

View File

@ -398,7 +398,7 @@ static void check_modem_status(struct serial_state *info)
wake_up_interruptible(&port->delta_msr_wait);
}
if ((port->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) {
if (tty_port_check_carrier(port) && (dstatus & SER_DCD)) {
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
printk("ttyS%d CD now %s...", info->line,
(!(status & SER_DCD)) ? "on" : "off");
@ -525,7 +525,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)
local_irq_save(flags);
if (port->flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(port)) {
free_page(page);
goto errout;
}
@ -586,7 +586,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)
*/
change_speed(tty, info, NULL);
port->flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(port, 1);
local_irq_restore(flags);
return 0;
@ -604,7 +604,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)
unsigned long flags;
struct serial_state *state;
if (!(info->tport.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->tport))
return;
state = info;
@ -645,7 +645,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)
set_bit(TTY_IO_ERROR, &tty->flags);
info->tport.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->tport, 0);
local_irq_restore(flags);
}
@ -727,17 +727,12 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info,
info->IER &= ~UART_IER_MSI;
if (port->flags & ASYNC_HARDPPS_CD)
info->IER |= UART_IER_MSI;
if (cflag & CRTSCTS) {
port->flags |= ASYNC_CTS_FLOW;
tty_port_set_cts_flow(port, cflag & CRTSCTS);
if (cflag & CRTSCTS)
info->IER |= UART_IER_MSI;
} else
port->flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
port->flags &= ~ASYNC_CHECK_CD;
else {
port->flags |= ASYNC_CHECK_CD;
tty_port_set_check_carrier(port, ~cflag & CLOCAL);
if (~cflag & CLOCAL)
info->IER |= UART_IER_MSI;
}
/* TBD:
* Does clearing IER_MSI imply that we should disable the VBL interrupt ?
*/
@ -1089,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state,
port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
check_and_exit:
if (port->flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(port)) {
if (change_spd) {
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
tty->alt_speed = 57600;
@ -1143,7 +1138,7 @@ static int rs_tiocmget(struct tty_struct *tty)
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
control = info->MCR;
@ -1165,7 +1160,7 @@ static int rs_tiocmset(struct tty_struct *tty, unsigned int set,
if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
return -ENODEV;
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
local_irq_save(flags);
@ -1250,7 +1245,7 @@ static int rs_ioctl(struct tty_struct *tty,
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
(cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}
@ -1342,7 +1337,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
/* Handle transition away from B0 status */
if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
info->MCR |= SER_DTR;
if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
info->MCR |= SER_RTS;
local_irq_save(flags);
rtsdtr_ctrl(info->MCR);
@ -1395,7 +1390,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
* line status register.
*/
state->read_status_mask &= ~UART_LSR_DR;
if (port->flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(port)) {
/* disable receive interrupts */
custom.intena = IF_RBF;
mb();
@ -1495,7 +1490,7 @@ static void rs_hangup(struct tty_struct *tty)
rs_flush_buffer(tty);
shutdown(tty, info);
info->tport.count = 0;
info->tport.flags &= ~ASYNC_NORMAL_ACTIVE;
tty_port_set_active(&info->tport, 0);
info->tport.tty = NULL;
wake_up_interruptible(&info->tport.open_wait);
}
@ -1543,7 +1538,7 @@ static inline void line_info(struct seq_file *m, int line,
local_irq_save(flags);
status = ciab.pra;
control = (state->tport.flags & ASYNC_INITIALIZED) ? state->MCR : status;
control = tty_port_initialized(&state->tport) ? state->MCR : status;
local_irq_restore(flags);
stat_buf[0] = 0;

View File

@ -714,7 +714,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
wake_up_interruptible(&info->port.delta_msr_wait);
}
if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
if ((mdm_change & CyDCD) && tty_port_check_carrier(&info->port)) {
if (mdm_status & CyDCD)
wake_up_interruptible(&info->port.open_wait);
else
@ -1119,7 +1119,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
case C_CM_MDCD:
info->icount.dcd++;
delta_count++;
if (info->port.flags & ASYNC_CHECK_CD) {
if (tty_port_check_carrier(&info->port)) {
u32 dcd = fw_ver > 241 ? param :
readl(&info->u.cyz.ch_ctrl->rs_status);
if (dcd & C_RS_DCD)
@ -1279,7 +1279,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
spin_lock_irqsave(&card->card_lock, flags);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
goto errout;
if (!info->type) {
@ -1364,7 +1364,7 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
/* enable send, recv, modem !!! */
}
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
clear_bit(TTY_IO_ERROR, &tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
@ -1424,7 +1424,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
struct cyclades_card *card;
unsigned long flags;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
card = info->card;
@ -1448,7 +1448,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
some later date (after testing)!!! */
set_bit(TTY_IO_ERROR, &tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
spin_unlock_irqrestore(&card->card_lock, flags);
} else {
#ifdef CY_DEBUG_OPEN
@ -1473,7 +1473,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
tty_port_lower_dtr_rts(&info->port);
set_bit(TTY_IO_ERROR, &tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
spin_unlock_irqrestore(&card->card_lock, flags);
}
@ -1711,7 +1711,7 @@ static void cy_do_close(struct tty_port *port)
/* Stop accepting input */
cyy_writeb(info, CyCAR, channel & 0x03);
cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData);
if (info->port.flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(&info->port)) {
/* Waiting for on-board buffers to be empty before
closing the port */
spin_unlock_irqrestore(&card->card_lock, flags);
@ -2083,17 +2083,12 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
info->cor1 |= CyPARITY_NONE;
/* CTS flow control flag */
if (cflag & CRTSCTS) {
info->port.flags |= ASYNC_CTS_FLOW;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
if (cflag & CRTSCTS)
info->cor2 |= CyCtsAE;
} else {
info->port.flags &= ~ASYNC_CTS_FLOW;
info->cor2 &= ~CyCtsAE;
}
if (cflag & CLOCAL)
info->port.flags &= ~ASYNC_CHECK_CD;
else
info->port.flags |= ASYNC_CHECK_CD;
info->cor2 &= ~CyCtsAE;
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
/***********************************************
The hardware option, CyRtsAO, presents RTS when
@ -2234,7 +2229,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
}
/* As the HW flow control is done in firmware, the driver
doesn't need to care about it */
info->port.flags &= ~ASYNC_CTS_FLOW;
tty_port_set_cts_flow(&info->port, 0);
/* XON/XOFF/XANY flow control flags */
sw_flow = 0;
@ -2252,10 +2247,7 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
}
/* CD sensitivity */
if (cflag & CLOCAL)
info->port.flags &= ~ASYNC_CHECK_CD;
else
info->port.flags |= ASYNC_CHECK_CD;
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
if (baud == 0) { /* baud rate is zero, turn off line */
cy_writel(&ch_ctrl->rs_control,
@ -2342,7 +2334,7 @@ cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
info->port.closing_wait = new_serial.closing_wait * HZ / 100;
check_and_exit:
if (info->port.flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(&info->port)) {
cy_set_line_char(info, tty);
ret = 0;
} else {

View File

@ -632,7 +632,7 @@ int hvc_poll(struct hvc_struct *hp)
goto bail;
/* Now check if we can get data (are we throttled ?) */
if (test_bit(TTY_THROTTLED, &tty->flags))
if (tty_throttled(tty))
goto throttled;
/* If we aren't notifier driven and aren't throttled, we always
@ -814,7 +814,7 @@ static int hvc_poll_get_char(struct tty_driver *driver, int line)
n = hp->ops->get_chars(hp->vtermno, &ch, 1);
if (n == 0)
if (n <= 0)
return NO_POLL_CHAR;
return ch;

View File

@ -600,7 +600,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
hvcs_try_write(hvcsd);
if (!tty || test_bit(TTY_THROTTLED, &tty->flags)) {
if (!tty || tty_throttled(tty)) {
hvcsd->todo_mask &= ~(HVCS_READ_MASK);
goto bail;
} else if (!(hvcsd->todo_mask & (HVCS_READ_MASK)))

View File

@ -509,7 +509,7 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
}
spin_lock_irqsave(&hp->lock, flags);
if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) {
if (tty && hp->n_throttle && !tty_throttled(tty)) {
/* we weren't hung up and we weren't throttled, so we can
* deliver the rest now */
hvsi_send_overflow(hp);

View File

@ -1572,6 +1572,11 @@ static void handle_received_SETUP_packet(struct ipw_hardware *hw,
sizeof(struct ipw_setup_reboot_msg_ack),
ADDR_SETUP_PROT, TL_PROTOCOLID_SETUP,
TL_SETUP_SIGNO_REBOOT_MSG_ACK);
if (!packet) {
pr_err(IPWIRELESS_PCCARD_NAME
": Not enough memory to send reboot packet");
break;
}
packet->header.length =
sizeof(struct TlSetupRebootMsgAck);
send_packet(hw, PRIO_SETUP, &packet->header);

View File

@ -438,8 +438,8 @@ static void isicom_tx(unsigned long _data)
for (; count > 0; count--, port++) {
/* port not active or tx disabled to force flow control */
if (!(port->port.flags & ASYNC_INITIALIZED) ||
!(port->status & ISI_TXOK))
if (!tty_port_initialized(&port->port) ||
!(port->status & ISI_TXOK))
continue;
txcount = min_t(short, TX_SIZE, port->xmit_cnt);
@ -553,7 +553,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
port = card->ports + channel;
if (!(port->port.flags & ASYNC_INITIALIZED)) {
if (!tty_port_initialized(&port->port)) {
outw(0x0000, base+0x04); /* enable interrupts */
spin_unlock(&card->card_lock);
return IRQ_HANDLED;
@ -577,7 +577,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
header = inw(base);
switch (header & 0xff) {
case 0: /* Change in EIA signals */
if (port->port.flags & ASYNC_CHECK_CD) {
if (tty_port_check_carrier(&port->port)) {
if (port->status & ISI_DCD) {
if (!(header & ISI_DCD)) {
/* Carrier has been lost */
@ -758,18 +758,13 @@ static void isicom_config_port(struct tty_struct *tty)
outw(channel_setup, base);
InterruptTheCard(base);
}
if (C_CLOCAL(tty))
port->port.flags &= ~ASYNC_CHECK_CD;
else
port->port.flags |= ASYNC_CHECK_CD;
tty_port_set_check_carrier(&port->port, !C_CLOCAL(tty));
/* flow control settings ...*/
flow_ctrl = 0;
port->port.flags &= ~ASYNC_CTS_FLOW;
if (C_CRTSCTS(tty)) {
port->port.flags |= ASYNC_CTS_FLOW;
tty_port_set_cts_flow(&port->port, C_CRTSCTS(tty));
if (C_CRTSCTS(tty))
flow_ctrl |= ISICOM_CTSRTS;
}
if (I_IXON(tty))
flow_ctrl |= ISICOM_RESPOND_XONXOFF;
if (I_IXOFF(tty))

View File

@ -912,7 +912,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
/* pci hot-un-plug support */
for (a = 0; a < brd->numPorts; a++)
if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&brd->ports[a].port))
tty_port_tty_hangup(&brd->ports[a].port, false);
for (a = 0; a < MAX_PORTS_PER_BOARD; a++)
@ -921,7 +921,7 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
while (1) {
opened = 0;
for (a = 0; a < brd->numPorts; a++)
if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&brd->ports[a].port))
opened++;
mutex_unlock(&moxa_openlock);
if (!opened)
@ -1192,13 +1192,13 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = ch;
tty_port_tty_set(&ch->port, tty);
mutex_lock(&ch->port.mutex);
if (!(ch->port.flags & ASYNC_INITIALIZED)) {
if (!tty_port_initialized(&ch->port)) {
ch->statusflags = 0;
moxa_set_tty_param(tty, &tty->termios);
MoxaPortLineCtrl(ch, 1, 1);
MoxaPortEnable(ch);
MoxaSetFifo(ch, ch->type == PORT_16550A);
ch->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&ch->port, 1);
}
mutex_unlock(&ch->port.mutex);
mutex_unlock(&moxa_openlock);
@ -1379,7 +1379,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
{
struct tty_struct *tty = tty_port_tty_get(&p->port);
void __iomem *ofsAddr;
unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
unsigned int inited = tty_port_initialized(&p->port);
u16 intr;
if (tty) {
@ -1394,7 +1394,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
tty_wakeup(tty);
}
if (inited && !test_bit(TTY_THROTTLED, &tty->flags) &&
if (inited && !tty_throttled(tty) &&
MoxaPortRxQueue(p) > 0) { /* RX */
MoxaPortReadData(p);
tty_schedule_flip(&p->port);

View File

@ -711,8 +711,8 @@ static int mxser_change_speed(struct tty_struct *tty,
/* CTS flow control flag and modem status interrupts */
info->IER &= ~UART_IER_MSI;
info->MCR &= ~UART_MCR_AFE;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
if (cflag & CRTSCTS) {
info->port.flags |= ASYNC_CTS_FLOW;
info->IER |= UART_IER_MSI;
if ((info->type == PORT_16550A) || (info->board->chip_flag)) {
info->MCR |= UART_MCR_AFE;
@ -744,16 +744,11 @@ static int mxser_change_speed(struct tty_struct *tty,
}
}
}
} else {
info->port.flags &= ~ASYNC_CTS_FLOW;
}
outb(info->MCR, info->ioaddr + UART_MCR);
if (cflag & CLOCAL) {
info->port.flags &= ~ASYNC_CHECK_CD;
} else {
info->port.flags |= ASYNC_CHECK_CD;
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
if (~cflag & CLOCAL)
info->IER |= UART_IER_MSI;
}
outb(info->IER, info->ioaddr + UART_IER);
/*
@ -826,7 +821,7 @@ static void mxser_check_modem_status(struct tty_struct *tty,
port->mon_data.modem_status = status;
wake_up_interruptible(&port->port.delta_msr_wait);
if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
if (tty_port_check_carrier(&port->port) && (status & UART_MSR_DDCD)) {
if (status & UART_MSR_DCD)
wake_up_interruptible(&port->port.open_wait);
}
@ -1086,12 +1081,10 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
mutex_lock(&port->mutex);
mxser_close_port(port);
mxser_flush_buffer(tty);
if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
if (C_HUPCL(tty))
tty_port_lower_dtr_rts(port);
}
if (tty_port_initialized(port) && C_HUPCL(tty))
tty_port_lower_dtr_rts(port);
mxser_shutdown_port(port);
clear_bit(ASYNCB_INITIALIZED, &port->flags);
tty_port_set_initialized(port, 0);
mutex_unlock(&port->mutex);
info->closing = 0;
/* Right now the tty_port set is done outside of the close_end helper
@ -1287,7 +1280,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
process_txrx_fifo(info);
if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
if (tty_port_initialized(port)) {
if (flags != (port->flags & ASYNC_SPD_MASK)) {
spin_lock_irqsave(&info->slock, sl_flags);
mxser_change_speed(tty, NULL);
@ -1296,7 +1289,7 @@ static int mxser_set_serial_info(struct tty_struct *tty,
} else {
retval = mxser_activate(port, tty);
if (retval == 0)
set_bit(ASYNCB_INITIALIZED, &port->flags);
tty_port_set_initialized(port, 1);
}
return retval;
}
@ -1334,7 +1327,7 @@ static int mxser_tiocmget(struct tty_struct *tty)
if (tty->index == MXSER_PORTS)
return -ENOIOCTLCMD;
if (test_bit(TTY_IO_ERROR, &tty->flags))
if (tty_io_error(tty))
return -EIO;
control = info->MCR;
@ -1361,7 +1354,7 @@ static int mxser_tiocmset(struct tty_struct *tty,
if (tty->index == MXSER_PORTS)
return -ENOIOCTLCMD;
if (test_bit(TTY_IO_ERROR, &tty->flags))
if (tty_io_error(tty))
return -EIO;
spin_lock_irqsave(&info->slock, flags);
@ -1715,8 +1708,7 @@ static int mxser_ioctl(struct tty_struct *tty,
return 0;
}
if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT &&
test_bit(TTY_IO_ERROR, &tty->flags))
if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && tty_io_error(tty))
return -EIO;
switch (cmd) {
@ -2257,7 +2249,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
iir &= MOXA_MUST_IIR_MASK;
tty = tty_port_tty_get(&port->port);
if (!tty || port->closing ||
!(port->port.flags & ASYNC_INITIALIZED)) {
!tty_port_initialized(&port->port)) {
status = inb(port->ioaddr + UART_LSR);
outb(0x27, port->ioaddr + UART_FCR);
inb(port->ioaddr + UART_MSR);
@ -2400,7 +2392,6 @@ static int mxser_initbrd(struct mxser_board *brd,
if (brd->chip_flag != MOXA_OTHER_UART)
mxser_enable_must_enchance_mode(info->ioaddr);
info->port.flags = ASYNC_SHARE_IRQ;
info->type = brd->uart_type;
process_txrx_fifo(info);

View File

@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm)
}
}
spin_unlock(&gsm_mux_lock);
WARN_ON(i == MAX_MUX);
/* open failed before registering => nothing to do */
if (i == MAX_MUX)
return;
/* In theory disconnecting DLCI 0 is sufficient but for some
modems this is apparently not the case. */
@ -2947,7 +2949,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
dlci->modem_rx = 0;
/* We could in theory open and close before we wait - eg if we get
a DM straight back. This is ok as that will have caused a hangup */
set_bit(ASYNCB_INITIALIZED, &port->flags);
tty_port_set_initialized(port, 1);
/* Start sending off SABM messages */
gsm_dlci_begin_open(dlci);
/* And wait for virtual carrier */
@ -2970,10 +2972,8 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
if (tty_port_close_start(&dlci->port, tty, filp) == 0)
return;
gsm_dlci_begin_close(dlci);
if (test_bit(ASYNCB_INITIALIZED, &dlci->port.flags)) {
if (C_HUPCL(tty))
tty_port_lower_dtr_rts(&dlci->port);
}
if (tty_port_initialized(&dlci->port) && C_HUPCL(tty))
tty_port_lower_dtr_rts(&dlci->port);
tty_port_close_end(&dlci->port, tty);
tty_port_tty_set(&dlci->port, NULL);
return;

View File

@ -599,7 +599,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
add_wait_queue(&tty->read_wait, &wait);
for (;;) {
if (test_bit(TTY_OTHER_DONE, &tty->flags)) {
if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
ret = -EIO;
break;
}
@ -827,7 +827,7 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
/* set bits for operations that won't block */
if (n_hdlc->rx_buf_list.head)
mask |= POLLIN | POLLRDNORM; /* readable */
if (test_bit(TTY_OTHER_DONE, &tty->flags))
if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
mask |= POLLHUP;
if (tty_hung_up_p(filp))
mask |= POLLHUP;

View File

@ -1917,18 +1917,6 @@ static inline int input_available_p(struct tty_struct *tty, int poll)
return ldata->commit_head - ldata->read_tail >= amt;
}
static inline int check_other_done(struct tty_struct *tty)
{
int done = test_bit(TTY_OTHER_DONE, &tty->flags);
if (done) {
/* paired with cmpxchg() in check_other_closed(); ensures
* read buffer head index is not stale
*/
smp_mb__after_atomic();
}
return done;
}
/**
* copy_from_read_buf - copy read data directly
* @tty: terminal device
@ -2124,7 +2112,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
struct n_tty_data *ldata = tty->disc_data;
unsigned char __user *b = buf;
DEFINE_WAIT_FUNC(wait, woken_wake_function);
int c, done;
int c;
int minimum, time;
ssize_t retval = 0;
long timeout;
@ -2183,32 +2171,35 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
break;
}
done = check_other_done(tty);
if (!input_available_p(tty, 0)) {
if (done) {
retval = -EIO;
break;
}
if (tty_hung_up_p(file))
break;
if (!timeout)
break;
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
break;
}
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
up_read(&tty->termios_rwsem);
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
timeout);
tty_buffer_flush_work(tty->port);
down_read(&tty->termios_rwsem);
continue;
if (!input_available_p(tty, 0)) {
if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
retval = -EIO;
break;
}
if (tty_hung_up_p(file))
break;
if (!timeout)
break;
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
break;
}
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
up_read(&tty->termios_rwsem);
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
timeout);
down_read(&tty->termios_rwsem);
continue;
}
}
if (ldata->icanon && !L_EXTPROC(tty)) {
@ -2386,12 +2377,17 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
poll_wait(file, &tty->read_wait, wait);
poll_wait(file, &tty->write_wait, wait);
if (check_other_done(tty))
mask |= POLLHUP;
if (input_available_p(tty, 1))
mask |= POLLIN | POLLRDNORM;
else {
tty_buffer_flush_work(tty->port);
if (input_available_p(tty, 1))
mask |= POLLIN | POLLRDNORM;
}
if (tty->packet && tty->link->ctrl_status)
mask |= POLLPRI | POLLIN | POLLRDNORM;
if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
mask |= POLLHUP;
if (tty_hung_up_p(file))
mask |= POLLHUP;
if (tty->ops->write && !tty_is_writelocked(tty) &&

View File

@ -826,7 +826,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
size = __le32_to_cpu(readl(addr));
/* DBG1( "%d bytes port: %d", size, index); */
if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
if (tty && tty_throttled(tty)) {
DBG1("No room in tty, don't read data, don't ack interrupt, "
"disable interrupt");

View File

@ -44,7 +44,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
if (tty->driver->subtype == PTY_TYPE_MASTER)
WARN_ON(tty->count > 1);
else {
if (test_bit(TTY_IO_ERROR, &tty->flags))
if (tty_io_error(tty))
return;
if (tty->count > 2)
return;
@ -59,7 +59,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
if (!tty->link)
return;
set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
tty_flip_buffer_push(tty->link->port);
wake_up_interruptible(&tty->link->read_wait);
wake_up_interruptible(&tty->link->write_wait);
if (tty->driver->subtype == PTY_TYPE_MASTER) {
set_bit(TTY_OTHER_CLOSED, &tty->flags);
@ -247,9 +247,7 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
goto out;
clear_bit(TTY_IO_ERROR, &tty->flags);
/* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */
clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
clear_bit(TTY_OTHER_DONE, &tty->link->flags);
set_bit(TTY_THROTTLED, &tty->flags);
return 0;

View File

@ -495,7 +495,7 @@ static void rp_handle_port(struct r_port *info)
if (!info)
return;
if ((info->port.flags & ASYNC_INITIALIZED) == 0) {
if (!tty_port_initialized(&info->port)) {
printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
"info->flags & NOT_INIT\n");
return;
@ -615,7 +615,8 @@ static void rp_do_poll(unsigned long dummy)
* the board.
* Inputs: board, aiop, chan numbers
*/
static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
static void __init
init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
{
unsigned rocketMode;
struct r_port *info;
@ -920,7 +921,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
/*
* Info->count is now 1; so it's safe to sleep now.
*/
if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
if (!tty_port_initialized(port)) {
cp = &info->channel;
sSetRxTrigger(cp, TRIG_1);
if (sGetChanStatus(cp) & CD_ACT)
@ -944,7 +945,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
sEnRxFIFO(cp);
sEnTransmit(cp);
set_bit(ASYNCB_INITIALIZED, &info->port.flags);
tty_port_set_initialized(&info->port, 1);
/*
* Set up the tty->alt_speed kludge
@ -1042,9 +1043,10 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
}
}
spin_lock_irq(&port->lock);
info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_NORMAL_ACTIVE);
tty->closing = 0;
spin_unlock_irq(&port->lock);
tty_port_set_initialized(port, 0);
tty_port_set_active(port, 0);
mutex_unlock(&port->mutex);
tty_port_tty_set(port, NULL);
@ -1512,7 +1514,7 @@ static void rp_hangup(struct tty_struct *tty)
sDisCTSFlowCtl(cp);
sDisTxSoftFlowCtl(cp);
sClrTxXOFF(cp);
clear_bit(ASYNCB_INITIALIZED, &info->port.flags);
tty_port_set_initialized(&info->port, 0);
wake_up_interruptible(&info->port.open_wait);
}
@ -1624,7 +1626,7 @@ static int rp_write(struct tty_struct *tty,
/* Write remaining data into the port's xmit_buf */
while (1) {
/* Hung up ? */
if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
if (!tty_port_active(&info->port))
goto end;
c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
c = min(c, XMIT_BUF_SIZE - info->xmit_head);

View File

@ -17,7 +17,7 @@
struct uart_8250_dma {
int (*tx_dma)(struct uart_8250_port *p);
int (*rx_dma)(struct uart_8250_port *p, unsigned int iir);
int (*rx_dma)(struct uart_8250_port *p);
/* Filter function */
dma_filter_fn fn;
@ -84,7 +84,6 @@ struct serial8250_config {
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
#define SERIAL8250_SHARE_IRQS 1
@ -151,6 +150,12 @@ static inline int serial8250_pnp_init(void) { return 0; }
static inline void serial8250_pnp_exit(void) { }
#endif
#ifdef CONFIG_SERIAL_8250_FINTEK
int fintek_8250_probe(struct uart_8250_port *uart);
#else
static inline int fintek_8250_probe(struct uart_8250_port *uart) { return 0; }
#endif
#ifdef CONFIG_ARCH_OMAP1
static inline int is_omap1_8250(struct uart_8250_port *pt)
{
@ -190,7 +195,8 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt)
#ifdef CONFIG_SERIAL_8250_DMA
extern int serial8250_tx_dma(struct uart_8250_port *);
extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir);
extern int serial8250_rx_dma(struct uart_8250_port *);
extern void serial8250_rx_dma_flush(struct uart_8250_port *);
extern int serial8250_request_dma(struct uart_8250_port *);
extern void serial8250_release_dma(struct uart_8250_port *);
#else
@ -198,10 +204,11 @@ static inline int serial8250_tx_dma(struct uart_8250_port *p)
{
return -1;
}
static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
static inline int serial8250_rx_dma(struct uart_8250_port *p)
{
return -1;
}
static inline void serial8250_rx_dma_flush(struct uart_8250_port *p) { }
static inline int serial8250_request_dma(struct uart_8250_port *p)
{
return -1;

View File

@ -830,6 +830,7 @@ static int serial8250_probe(struct platform_device *dev)
uart.port.handle_irq = p->handle_irq;
uart.port.handle_break = p->handle_break;
uart.port.set_termios = p->set_termios;
uart.port.get_mctrl = p->get_mctrl;
uart.port.pm = p->pm;
uart.port.dev = &dev->dev;
uart.port.irqflags |= irqflag;
@ -1022,6 +1023,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
/* Possibly override set_termios call */
if (up->port.set_termios)
uart->port.set_termios = up->port.set_termios;
if (up->port.get_mctrl)
uart->port.get_mctrl = up->port.get_mctrl;
if (up->port.set_mctrl)
uart->port.set_mctrl = up->port.set_mctrl;
if (up->port.startup)

View File

@ -110,30 +110,11 @@ err:
return ret;
}
int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
int serial8250_rx_dma(struct uart_8250_port *p)
{
struct uart_8250_dma *dma = p->dma;
struct dma_async_tx_descriptor *desc;
switch (iir & 0x3f) {
case UART_IIR_RLSI:
/* 8250_core handles errors and break interrupts */
return -EIO;
case UART_IIR_RX_TIMEOUT:
/*
* If RCVR FIFO trigger level was not reached, complete the
* transfer and let 8250_core copy the remaining data.
*/
if (dma->rx_running) {
dmaengine_pause(dma->rxchan);
__dma_rx_complete(p);
dmaengine_terminate_all(dma->rxchan);
}
return -ETIMEDOUT;
default:
break;
}
if (dma->rx_running)
return 0;
@ -154,10 +135,23 @@ int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
return 0;
}
void serial8250_rx_dma_flush(struct uart_8250_port *p)
{
struct uart_8250_dma *dma = p->dma;
if (dma->rx_running) {
dmaengine_pause(dma->rxchan);
__dma_rx_complete(p);
dmaengine_terminate_all(dma->rxchan);
}
}
int serial8250_request_dma(struct uart_8250_port *p)
{
struct uart_8250_dma *dma = p->dma;
dma_cap_mask_t mask;
struct dma_slave_caps caps;
int ret;
/* Default slave configuration parameters */
dma->rxconf.direction = DMA_DEV_TO_MEM;
@ -178,6 +172,16 @@ int serial8250_request_dma(struct uart_8250_port *p)
if (!dma->rxchan)
return -ENODEV;
/* 8250 rx dma requires dmaengine driver to support pause/terminate */
ret = dma_get_slave_caps(dma->rxchan, &caps);
if (ret)
goto release_rx;
if (!caps.cmd_pause || !caps.cmd_terminate ||
caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) {
ret = -EINVAL;
goto release_rx;
}
dmaengine_slave_config(dma->rxchan, &dma->rxconf);
/* Get a channel for TX */
@ -185,8 +189,17 @@ int serial8250_request_dma(struct uart_8250_port *p)
dma->fn, dma->tx_param,
p->port.dev, "tx");
if (!dma->txchan) {
dma_release_channel(dma->rxchan);
return -ENODEV;
ret = -ENODEV;
goto release_rx;
}
/* 8250 tx dma requires dmaengine driver to support terminate */
ret = dma_get_slave_caps(dma->txchan, &caps);
if (ret)
goto err;
if (!caps.cmd_terminate) {
ret = -EINVAL;
goto err;
}
dmaengine_slave_config(dma->txchan, &dma->txconf);
@ -197,8 +210,10 @@ int serial8250_request_dma(struct uart_8250_port *p)
dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
&dma->rx_addr, GFP_KERNEL);
if (!dma->rx_buf)
if (!dma->rx_buf) {
ret = -ENOMEM;
goto err;
}
/* TX buffer */
dma->tx_addr = dma_map_single(dma->txchan->device->dev,
@ -208,6 +223,7 @@ int serial8250_request_dma(struct uart_8250_port *p)
if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
dma_free_coherent(dma->rxchan->device->dev, dma->rx_size,
dma->rx_buf, dma->rx_addr);
ret = -ENOMEM;
goto err;
}
@ -215,10 +231,10 @@ int serial8250_request_dma(struct uart_8250_port *p)
return 0;
err:
dma_release_channel(dma->rxchan);
dma_release_channel(dma->txchan);
return -ENOMEM;
release_rx:
dma_release_channel(dma->rxchan);
return ret;
}
EXPORT_SYMBOL_GPL(serial8250_request_dma);

View File

@ -104,15 +104,16 @@ static void dw8250_check_lcr(struct uart_port *p, int value)
dw8250_force_idle(p);
#ifdef CONFIG_64BIT
__raw_writeq(value & 0xff, offset);
#else
if (p->type == PORT_OCTEON)
__raw_writeq(value & 0xff, offset);
else
#endif
if (p->iotype == UPIO_MEM32)
writel(value, offset);
else if (p->iotype == UPIO_MEM32BE)
iowrite32be(value, offset);
else
writeb(value, offset);
#endif
}
/*
* FIXME: this deadlocks if port->lock is already held
@ -617,6 +618,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
{ "8086228A", 0 },
{ "APMC0D08", 0},
{ "AMD0020", 0 },
{ "AMDI0020", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);

View File

@ -1,9 +1,7 @@
/*
* Probe for F81216A LPC to 4 UART
*
* Based on drivers/tty/serial/8250_pnp.c, by Russell King, et al
*
* Copyright (C) 2014 Ricardo Ribalda, Qtechnology A/S
* Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S
*
*
* This program is free software; you can redistribute it and/or modify
@ -38,19 +36,15 @@
#define RXW4C_IRA BIT(3)
#define TXW4C_IRA BIT(2)
#define DRIVER_NAME "8250_fintek"
struct fintek_8250 {
u16 base_port;
u8 index;
u8 key;
long line;
};
static int fintek_8250_enter_key(u16 base_port, u8 key)
{
if (!request_muxed_region(base_port, 2, DRIVER_NAME))
if (!request_muxed_region(base_port, 2, "8250_fintek"))
return -EBUSY;
outb(key, base_port + ADDR_PORT);
@ -138,7 +132,7 @@ static int fintek_8250_rs485_config(struct uart_port *port,
return 0;
}
static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index)
static int find_base_port(struct fintek_8250 *pdata, u16 io_address)
{
static const u16 addr[] = {0x4e, 0x2e};
static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67};
@ -168,10 +162,13 @@ static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index)
continue;
fintek_8250_exit_key(addr[i]);
*key = keys[j];
*index = k;
return addr[i];
pdata->key = keys[j];
pdata->base_port = addr[i];
pdata->index = k;
return 0;
}
fintek_8250_exit_key(addr[i]);
}
}
@ -179,104 +176,21 @@ static int fintek_8250_base_port(u16 io_address, u8 *key, u8 *index)
return -ENODEV;
}
static int
fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
int fintek_8250_probe(struct uart_8250_port *uart)
{
struct uart_8250_port uart;
struct fintek_8250 *pdata;
int base_port;
u8 key;
u8 index;
struct fintek_8250 probe_data;
if (!pnp_port_valid(dev, 0))
if (find_base_port(&probe_data, uart->port.iobase))
return -ENODEV;
base_port = fintek_8250_base_port(pnp_port_start(dev, 0), &key, &index);
if (base_port < 0)
return -ENODEV;
memset(&uart, 0, sizeof(uart));
pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL);
pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
uart.port.private_data = pdata;
if (!pnp_irq_valid(dev, 0))
return -ENODEV;
uart.port.irq = pnp_irq(dev, 0);
uart.port.iobase = pnp_port_start(dev, 0);
uart.port.iotype = UPIO_PORT;
uart.port.rs485_config = fintek_8250_rs485_config;
memcpy(pdata, &probe_data, sizeof(probe_data));
uart->port.rs485_config = fintek_8250_rs485_config;
uart->port.private_data = pdata;
uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
uart.port.flags |= UPF_SHARE_IRQ;
uart.port.uartclk = 1843200;
uart.port.dev = &dev->dev;
pdata->key = key;
pdata->base_port = base_port;
pdata->index = index;
pdata->line = serial8250_register_8250_port(&uart);
if (pdata->line < 0)
return -ENODEV;
pnp_set_drvdata(dev, pdata);
return 0;
}
static void fintek_8250_remove(struct pnp_dev *dev)
{
struct fintek_8250 *pdata = pnp_get_drvdata(dev);
if (pdata)
serial8250_unregister_port(pdata->line);
}
#ifdef CONFIG_PM
static int fintek_8250_suspend(struct pnp_dev *dev, pm_message_t state)
{
struct fintek_8250 *pdata = pnp_get_drvdata(dev);
if (!pdata)
return -ENODEV;
serial8250_suspend_port(pdata->line);
return 0;
}
static int fintek_8250_resume(struct pnp_dev *dev)
{
struct fintek_8250 *pdata = pnp_get_drvdata(dev);
if (!pdata)
return -ENODEV;
serial8250_resume_port(pdata->line);
return 0;
}
#else
#define fintek_8250_suspend NULL
#define fintek_8250_resume NULL
#endif /* CONFIG_PM */
static const struct pnp_device_id fintek_dev_table[] = {
/* Qtechnology Panel PC / IO1000 */
{ "PNP0501"},
{}
};
MODULE_DEVICE_TABLE(pnp, fintek_dev_table);
static struct pnp_driver fintek_8250_driver = {
.name = DRIVER_NAME,
.probe = fintek_8250_probe,
.remove = fintek_8250_remove,
.suspend = fintek_8250_suspend,
.resume = fintek_8250_resume,
.id_table = fintek_dev_table,
};
module_pnp_driver(fintek_8250_driver);
MODULE_DESCRIPTION("Fintek F812164 module");
MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>");
MODULE_LICENSE("GPL");

View File

@ -9,11 +9,13 @@
* published by the Free Software Foundation.
*/
#include <linux/rational.h>
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/rational.h>
#include <linux/dma/hsu.h>
#include <linux/8250_pci.h>
#include "8250.h"
@ -24,6 +26,7 @@
#define PCI_DEVICE_ID_INTEL_DNV_UART 0x19d8
/* Intel MID Specific registers */
#define INTEL_MID_UART_DNV_FISR 0x08
#define INTEL_MID_UART_PS 0x30
#define INTEL_MID_UART_MUL 0x34
#define INTEL_MID_UART_DIV 0x38
@ -31,6 +34,7 @@
struct mid8250;
struct mid8250_board {
unsigned int flags;
unsigned long freq;
unsigned int base_baud;
int (*setup)(struct mid8250 *, struct uart_port *p);
@ -76,7 +80,11 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
struct pci_dev *pdev = to_pci_dev(p->dev);
int index = PCI_FUNC(pdev->devfn);
/* Currently no support for HSU port0 */
/*
* Device 0000:00:04.0 is not a real HSU port. It provides a global
* register set for all HSU ports, although it has the same PCI ID.
* Skip it here.
*/
if (index-- == 0)
return -ENODEV;
@ -88,16 +96,16 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
static int dnv_handle_irq(struct uart_port *p)
{
struct mid8250 *mid = p->private_data;
int ret;
unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
int ret = IRQ_NONE;
ret = hsu_dma_irq(&mid->dma_chip, 0);
ret |= hsu_dma_irq(&mid->dma_chip, 1);
/* For now, letting the HW generate separate interrupt for the UART */
if (ret)
return ret;
return serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
if (fisr & BIT(2))
ret |= hsu_dma_irq(&mid->dma_chip, 1);
if (fisr & BIT(1))
ret |= hsu_dma_irq(&mid->dma_chip, 0);
if (fisr & BIT(0))
ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
return ret;
}
#define DNV_DMA_CHAN_OFFSET 0x80
@ -106,12 +114,13 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p)
{
struct hsu_dma_chip *chip = &mid->dma_chip;
struct pci_dev *pdev = to_pci_dev(p->dev);
unsigned int bar = FL_GET_BASE(mid->board->flags);
int ret;
chip->dev = &pdev->dev;
chip->irq = pdev->irq;
chip->regs = p->membase;
chip->length = pci_resource_len(pdev, 0);
chip->length = pci_resource_len(pdev, bar);
chip->offset = DNV_DMA_CHAN_OFFSET;
/* Falling back to PIO mode if DMA probing fails */
@ -217,6 +226,7 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct uart_8250_port uart;
struct mid8250 *mid;
unsigned int bar;
int ret;
ret = pcim_enable_device(pdev);
@ -230,6 +240,7 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return -ENOMEM;
mid->board = (struct mid8250_board *)id->driver_data;
bar = FL_GET_BASE(mid->board->flags);
memset(&uart, 0, sizeof(struct uart_8250_port));
@ -242,8 +253,8 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
uart.port.set_termios = mid8250_set_termios;
uart.port.mapbase = pci_resource_start(pdev, 0);
uart.port.membase = pcim_iomap(pdev, 0, 0);
uart.port.mapbase = pci_resource_start(pdev, bar);
uart.port.membase = pcim_iomap(pdev, bar, 0);
if (!uart.port.membase)
return -ENOMEM;
@ -282,18 +293,21 @@ static void mid8250_remove(struct pci_dev *pdev)
}
static const struct mid8250_board pnw_board = {
.flags = FL_BASE0,
.freq = 50000000,
.base_baud = 115200,
.setup = pnw_setup,
};
static const struct mid8250_board tng_board = {
.flags = FL_BASE0,
.freq = 38400000,
.base_baud = 1843200,
.setup = tng_setup,
};
static const struct mid8250_board dnv_board = {
.flags = FL_BASE1,
.freq = 133333333,
.base_baud = 115200,
.setup = dnv_setup,

View File

@ -29,7 +29,7 @@ struct of_serial_info {
};
#ifdef CONFIG_ARCH_TEGRA
void tegra_serial_handle_break(struct uart_port *p)
static void tegra_serial_handle_break(struct uart_port *p)
{
unsigned int status, tmout = 10000;

View File

@ -115,6 +115,12 @@ struct omap8250_priv {
bool rx_dma_broken;
};
#ifdef CONFIG_SERIAL_8250_DMA
static void omap_8250_rx_dma_flush(struct uart_8250_port *p);
#else
static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { }
#endif
static u32 uart_read(struct uart_8250_port *up, u32 reg)
{
return readl(up->port.membase + (reg << up->port.regshift));
@ -635,7 +641,7 @@ static int omap_8250_startup(struct uart_port *port)
serial_out(up, UART_OMAP_WER, priv->wer);
if (up->dma)
up->dma->rx_dma(up, 0);
up->dma->rx_dma(up);
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
@ -654,7 +660,7 @@ static void omap_8250_shutdown(struct uart_port *port)
flush_work(&priv->qos_work);
if (up->dma)
up->dma->rx_dma(up, UART_IIR_RX_TIMEOUT);
omap_8250_rx_dma_flush(up);
pm_runtime_get_sync(port->dev);
@ -742,9 +748,9 @@ static void omap_8250_unthrottle(struct uart_port *port)
}
#ifdef CONFIG_SERIAL_8250_DMA
static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir);
static int omap_8250_rx_dma(struct uart_8250_port *p);
static void __dma_rx_do_complete(struct uart_8250_port *p, bool error)
static void __dma_rx_do_complete(struct uart_8250_port *p)
{
struct omap8250_priv *priv = p->port.private_data;
struct uart_8250_dma *dma = p->dma;
@ -754,9 +760,6 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error)
unsigned long flags;
int ret;
dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
dma->rx_size, DMA_FROM_DEVICE);
spin_lock_irqsave(&priv->rx_dma_lock, flags);
if (!dma->rx_running)
@ -764,7 +767,6 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error)
dma->rx_running = 0;
dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
dmaengine_terminate_all(dma->rxchan);
count = dma->rx_size - state.residue;
@ -775,15 +777,13 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error)
unlock:
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
if (!error)
omap_8250_rx_dma(p, 0);
tty_flip_buffer_push(tty_port);
}
static void __dma_rx_complete(void *param)
{
__dma_rx_do_complete(param, false);
__dma_rx_do_complete(param);
omap_8250_rx_dma(param);
}
static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
@ -806,10 +806,11 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p)
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
__dma_rx_do_complete(p, true);
__dma_rx_do_complete(p);
dmaengine_terminate_all(dma->rxchan);
}
static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
static int omap_8250_rx_dma(struct uart_8250_port *p)
{
struct omap8250_priv *priv = p->port.private_data;
struct uart_8250_dma *dma = p->dma;
@ -817,35 +818,6 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
struct dma_async_tx_descriptor *desc;
unsigned long flags;
switch (iir & 0x3f) {
case UART_IIR_RLSI:
/* 8250_core handles errors and break interrupts */
omap_8250_rx_dma_flush(p);
return -EIO;
case UART_IIR_RX_TIMEOUT:
/*
* If RCVR FIFO trigger level was not reached, complete the
* transfer and let 8250_core copy the remaining data.
*/
omap_8250_rx_dma_flush(p);
return -ETIMEDOUT;
case UART_IIR_RDI:
/*
* The OMAP UART is a special BEAST. If we receive RDI we _have_
* a DMA transfer programmed but it didn't work. One reason is
* that we were too slow and there were too many bytes in the
* FIFO, the UART counted wrong and never kicked the DMA engine
* to do anything. That means once we receive RDI on OMAP then
* the DMA won't do anything soon so we have to cancel the DMA
* transfer and purge the FIFO manually.
*/
omap_8250_rx_dma_flush(p);
return -ETIMEDOUT;
default:
break;
}
if (priv->rx_dma_broken)
return -EINVAL;
@ -868,9 +840,6 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
dma->rx_cookie = dmaengine_submit(desc);
dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
dma->rx_size, DMA_FROM_DEVICE);
dma_async_issue_pending(dma->rxchan);
out:
spin_unlock_irqrestore(&priv->rx_dma_lock, flags);
@ -1022,6 +991,18 @@ err:
return ret;
}
static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
{
switch (iir & 0x3f) {
case UART_IIR_RLSI:
case UART_IIR_RX_TIMEOUT:
case UART_IIR_RDI:
omap_8250_rx_dma_flush(up);
return true;
}
return omap_8250_rx_dma(up);
}
/*
* This is mostly serial8250_handle_irq(). We have a slightly different DMA
* hoook for RX/TX and need different logic for them in the ISR. Therefore we
@ -1033,7 +1014,6 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
unsigned char status;
unsigned long flags;
u8 iir;
int dma_err = 0;
serial8250_rpm_get(up);
@ -1048,11 +1028,9 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
status = serial_port_in(port, UART_LSR);
if (status & (UART_LSR_DR | UART_LSR_BI)) {
dma_err = omap_8250_rx_dma(up, iir);
if (dma_err) {
if (handle_rx_dma(up, iir)) {
status = serial8250_rx_chars(up, status);
omap_8250_rx_dma(up, 0);
omap_8250_rx_dma(up);
}
}
serial8250_modem_status(up);
@ -1066,8 +1044,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
* try again due to an earlier failer which
* might have been resolved by now.
*/
dma_err = omap_8250_tx_dma(up);
if (dma_err)
if (omap_8250_tx_dma(up))
serial8250_tx_chars(up);
}
}
@ -1084,7 +1061,7 @@ static bool the_no_dma_filter_fn(struct dma_chan *chan, void *param)
#else
static inline int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
static inline int omap_8250_rx_dma(struct uart_8250_port *p)
{
return -EINVAL;
}
@ -1395,7 +1372,7 @@ static int omap8250_runtime_suspend(struct device *dev)
}
if (up->dma && up->dma->rxchan)
omap_8250_rx_dma(up, UART_IIR_RX_TIMEOUT);
omap_8250_rx_dma_flush(up);
priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
schedule_work(&priv->qos_work);
@ -1407,20 +1384,18 @@ static int omap8250_runtime_resume(struct device *dev)
{
struct omap8250_priv *priv = dev_get_drvdata(dev);
struct uart_8250_port *up;
int loss_cntx;
/* In case runtime-pm tries this before we are setup */
if (!priv)
return 0;
up = serial8250_get_port(priv->line);
loss_cntx = omap8250_lost_context(up);
if (loss_cntx)
if (omap8250_lost_context(up))
omap8250_restore_regs(up);
if (up->dma && up->dma->rxchan)
omap_8250_rx_dma(up, 0);
omap_8250_rx_dma(up);
priv->latency = priv->calc_latency;
schedule_work(&priv->qos_work);

View File

@ -1377,6 +1377,9 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
unsigned long m, n;
u32 reg;
/* Gracefully handle the B0 case: fall back to B9600 */
fuart = fuart ? fuart : 9600 * 16;
/* Get Fuart closer to Fref */
fuart *= rounddown_pow_of_two(fref / fuart);
@ -1413,6 +1416,17 @@ static bool byt_dma_filter(struct dma_chan *chan, void *param)
return true;
}
static unsigned int
byt_get_mctrl(struct uart_port *port)
{
unsigned int ret = serial8250_do_get_mctrl(port);
/* Force DCD and DSR signals to permanently be reported as active. */
ret |= TIOCM_CAR | TIOCM_DSR;
return ret;
}
static int
byt_serial_setup(struct serial_private *priv,
const struct pciserial_board *board,
@ -1477,6 +1491,7 @@ byt_serial_setup(struct serial_private *priv,
port->port.type = PORT_16550A;
port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
port->port.set_termios = byt_set_termios;
port->port.get_mctrl = byt_get_mctrl;
port->port.fifosize = 64;
port->tx_loadsz = 64;
port->dma = dma;

View File

@ -1315,6 +1315,13 @@ static void autoconfig(struct uart_8250_port *up)
out_lock:
spin_unlock_irqrestore(&port->lock, flags);
/*
* Check if the device is a Fintek F81216A
*/
if (port->type == PORT_16550A)
fintek_8250_probe(up);
if (up->capabilities != old_capabilities) {
pr_warn("ttyS%d: detected caps %08x should be %08x\n",
serial_index(port), old_capabilities,
@ -1788,6 +1795,18 @@ unsigned int serial8250_modem_status(struct uart_8250_port *up)
}
EXPORT_SYMBOL_GPL(serial8250_modem_status);
static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
{
switch (iir & 0x3f) {
case UART_IIR_RX_TIMEOUT:
serial8250_rx_dma_flush(up);
/* fall-through */
case UART_IIR_RLSI:
return true;
}
return up->dma->rx_dma(up);
}
/*
* This handles the interrupt from one port.
*/
@ -1796,7 +1815,6 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
unsigned char status;
unsigned long flags;
struct uart_8250_port *up = up_to_u8250p(port);
int dma_err = 0;
if (iir & UART_IIR_NO_INT)
return 0;
@ -1808,15 +1826,11 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
DEBUG_INTR("status = %x...", status);
if (status & (UART_LSR_DR | UART_LSR_BI)) {
if (up->dma)
dma_err = up->dma->rx_dma(up, iir);
if (!up->dma || dma_err)
if (!up->dma || handle_rx_dma(up, iir))
status = serial8250_rx_chars(up, status);
}
serial8250_modem_status(up);
if ((!up->dma || (up->dma && up->dma->tx_err)) &&
(status & UART_LSR_THRE))
if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE))
serial8250_tx_chars(up);
spin_unlock_irqrestore(&port->lock, flags);
@ -1882,7 +1896,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
}
static unsigned int serial8250_get_mctrl(struct uart_port *port)
unsigned int serial8250_do_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int status;
@ -1903,6 +1917,14 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
ret |= TIOCM_CTS;
return ret;
}
EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl);
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
if (port->get_mctrl)
return port->get_mctrl(port);
return serial8250_do_get_mctrl(port);
}
void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
{

View File

@ -209,7 +209,7 @@ static int uniphier_uart_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "failed to get IRQ number");
dev_err(dev, "failed to get IRQ number\n");
return irq;
}

View File

@ -57,6 +57,18 @@ config SERIAL_8250_PNP
This builds standard PNP serial support. You may be able to
disable this feature if you only need legacy serial support.
config SERIAL_8250_FINTEK
bool "Support for Fintek F81216A LPC to 4 UART RS485 API"
depends on SERIAL_8250
---help---
Selecting this option will add support for the RS485 capabilities
of the Fintek F81216A LPC to 4 UART.
If this option is not selected the device will be configured as a
standard 16550A serial port.
If unsure, say N.
config SERIAL_8250_CONSOLE
bool "Console on 8250/16550 and compatible serial port"
depends on SERIAL_8250=y
@ -358,14 +370,6 @@ config SERIAL_8250_OMAP_TTYO_FIXUP
not booting kernel because the serial console remains silent in case
they forgot to update the command line.
config SERIAL_8250_FINTEK
tristate "Support for Fintek F81216A LPC to 4 UART"
depends on SERIAL_8250 && PNP
help
Selecting this option will add support for the Fintek F81216A
LPC to 4 UART. This device has some RS485 functionality not available
through the PNP driver. If unsure, say N.
config SERIAL_8250_LPC18XX
tristate "NXP LPC18xx/43xx serial port support"
depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST)
@ -398,8 +402,10 @@ config SERIAL_8250_INGENIC
its UARTs, say Y to this option. If unsure, say N.
config SERIAL_8250_MID
tristate "Support for serial ports on Intel MID platforms"
tristate "Support for serial ports on Intel MID platforms" if EXPERT
default SERIAL_8250
depends on SERIAL_8250 && PCI
depends on X86 || COMPILE_TEST
select HSU_DMA if SERIAL_8250_DMA
select HSU_DMA_PCI if (HSU_DMA && X86_INTEL_MID)
select RATIONAL

View File

@ -7,6 +7,7 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o 8250_base.o
8250-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o
8250_base-y := 8250_port.o
8250_base-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o
8250_base-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o
obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o
obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o
obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
@ -23,7 +24,6 @@ obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
obj-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o
obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o
obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o
obj-$(CONFIG_SERIAL_8250_UNIPHIER) += 8250_uniphier.o

View File

@ -213,6 +213,7 @@ config SERIAL_MESON_CONSOLE
bool "Support for console on meson"
depends on SERIAL_MESON=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
help
Say Y here if you wish to use a Amlogic MesonX UART as the
system console (the system console is the device which
@ -1404,11 +1405,12 @@ config SERIAL_PCH_UART_CONSOLE
config SERIAL_MXS_AUART
tristate "MXS AUART support"
depends on HAS_DMA
depends on ARCH_MXS || COMPILE_TEST
depends on ARCH_MXS || MACH_ASM9260 || COMPILE_TEST
select SERIAL_CORE
select SERIAL_MCTRL_GPIO if GPIOLIB
help
This driver supports the MXS Application UART (AUART) port.
This driver supports the MXS and Alphascale ASM9260 Application
UART (AUART) port.
config SERIAL_MXS_AUART_CONSOLE
bool "MXS AUART console support"
@ -1467,6 +1469,19 @@ config SERIAL_EFM32_UART
This driver support the USART and UART ports on
Energy Micro's efm32 SoCs.
config SERIAL_MPS2_UART_CONSOLE
bool "MPS2 UART console support"
depends on SERIAL_MPS2_UART
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
config SERIAL_MPS2_UART
bool "MPS2 UART port"
depends on ARM || COMPILE_TEST
select SERIAL_CORE
help
This driver support the UART ports on ARM MPS2.
config SERIAL_EFM32_UART_CONSOLE
bool "EFM32 UART/USART console support"
depends on SERIAL_EFM32_UART=y
@ -1625,6 +1640,7 @@ config SERIAL_STM32_CONSOLE
config SERIAL_MVEBU_UART
bool "Marvell EBU serial port support"
depends on ARCH_MVEBU || COMPILE_TEST
select SERIAL_CORE
help
This driver is for Marvell EBU SoC's UART. If you have a machine

View File

@ -92,6 +92,7 @@ obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o
obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o
obj-$(CONFIG_SERIAL_MVEBU_UART) += mvebu-uart.o
obj-$(CONFIG_SERIAL_PIC32) += pic32_uart.o
obj-$(CONFIG_SERIAL_MPS2_UART) += mps2-uart.o
# GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o

View File

@ -121,6 +121,7 @@ static struct vendor_data vendor_arm = {
static struct vendor_data vendor_sbsa = {
.reg_offset = pl011_std_offsets,
.access_32b = true,
.oversampling = false,
.dma_threshold = false,
.cts_event_workaround = false,

View File

@ -274,6 +274,13 @@ static bool atmel_use_dma_rx(struct uart_port *port)
return atmel_port->use_dma_rx;
}
static bool atmel_use_fifo(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
return atmel_port->fifo_size;
}
static unsigned int atmel_get_lines_status(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
@ -2090,7 +2097,12 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
mode |= ATMEL_US_USMODE_RS485;
} else if (termios->c_cflag & CRTSCTS) {
/* RS232 with hardware handshake (RTS/CTS) */
mode |= ATMEL_US_USMODE_HWHS;
if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
dev_info(port->dev, "not enabling hardware flow control because DMA is used");
termios->c_cflag &= ~CRTSCTS;
} else {
mode |= ATMEL_US_USMODE_HWHS;
}
} else {
/* RS232 without hadware handshake */
mode |= ATMEL_US_USMODE_NORMAL;

View File

@ -2599,7 +2599,7 @@ startup(struct e100_serial * info)
/* if it was already initialized, skip this */
if (info->port.flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(&info->port)) {
local_irq_restore(flags);
free_page(xmit_page);
return 0;
@ -2703,7 +2703,7 @@ startup(struct e100_serial * info)
e100_rts(info, 1);
e100_dtr(info, 1);
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
local_irq_restore(flags);
return 0;
@ -2745,7 +2745,7 @@ shutdown(struct e100_serial * info)
info->tr_running = 0;
}
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
#ifdef SERIAL_DEBUG_OPEN
@ -2776,7 +2776,7 @@ shutdown(struct e100_serial * info)
if (info->port.tty)
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
local_irq_restore(flags);
}
@ -3273,9 +3273,9 @@ set_serial_info(struct e100_serial *info,
info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
check_and_exit:
if (info->port.flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(&info->port))
change_speed(info);
} else
else
retval = startup(info);
return retval;
}
@ -3445,7 +3445,7 @@ rs_ioctl(struct tty_struct *tty,
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
(cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}
@ -3628,7 +3628,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
e100_disable_rx(info);
e100_disable_rx_irq(info);
if (info->port.flags & ASYNC_INITIALIZED) {
if (tty_port_initialized(&info->port)) {
/*
* Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially
@ -3648,8 +3648,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
schedule_timeout_interruptible(info->port.close_delay);
wake_up_interruptible(&info->port.open_wait);
}
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
local_irq_restore(flags);
tty_port_set_active(&info->port, 0);
/* port closed */
@ -3732,7 +3732,7 @@ rs_hangup(struct tty_struct *tty)
shutdown(info);
info->event = 0;
info->port.count = 0;
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
tty_port_set_active(&info->port, 0);
info->port.tty = NULL;
wake_up_interruptible(&info->port.open_wait);
}
@ -3755,9 +3755,8 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
* If non-blocking mode is set, or the port is not enabled,
* then make the check up front and then exit.
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
info->port.flags |= ASYNC_NORMAL_ACTIVE;
if ((filp->f_flags & O_NONBLOCK) || tty_io_error(tty)) {
tty_port_set_active(&info->port, 1);
return 0;
}
@ -3788,8 +3787,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
e100_dtr(info, 1);
local_irq_restore(flags);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
!(info->port.flags & ASYNC_INITIALIZED)) {
if (tty_hung_up_p(filp) || !tty_port_initialized(&info->port)) {
#ifdef SERIAL_DO_RESTART
if (info->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
@ -3826,7 +3824,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
#endif
if (retval)
return retval;
info->port.flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(&info->port, 1);
return 0;
}

View File

@ -651,7 +651,7 @@ static void ifx_spi_complete(void *ctx)
struct ifx_spi_device *ifx_dev = ctx;
int length;
int actual_length;
unsigned char more;
unsigned char more = 0;
unsigned char cts;
int local_write_pending = 0;
int queue_length;

View File

@ -114,6 +114,7 @@
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
#define UCR3_DTRDEN (1<<3) /* Data Terminal Ready Delta Enable. */
#define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */
#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
#define UCR3_BPEN (1<<0) /* Preset registers enable */
@ -142,7 +143,7 @@
#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
#define USR1_AGTIM (1<<8) /* Ageing timer interrupt flag */
#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
#define USR1_DTRD (1<<7) /* DTR Delta */
#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
@ -361,6 +362,7 @@ static void imx_stop_tx(struct uart_port *port)
imx_port_rts_inactive(sport, &temp);
else
imx_port_rts_active(sport, &temp);
temp |= UCR2_RXEN;
writel(temp, port->membase + UCR2);
temp = readl(port->membase + UCR4);
@ -568,6 +570,8 @@ static void imx_start_tx(struct uart_port *port)
imx_port_rts_inactive(sport, &temp);
else
imx_port_rts_active(sport, &temp);
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
temp &= ~UCR2_RXEN;
writel(temp, port->membase + UCR2);
/* enable transmitter and shifter empty irq */
@ -729,11 +733,61 @@ static void imx_dma_rxint(struct imx_port *sport)
spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
* We have a modem side uart, so the meanings of RTS and CTS are inverted.
*/
static unsigned int imx_get_hwmctrl(struct imx_port *sport)
{
unsigned int tmp = TIOCM_DSR;
unsigned usr1 = readl(sport->port.membase + USR1);
if (usr1 & USR1_RTSS)
tmp |= TIOCM_CTS;
/* in DCE mode DCDIN is always 0 */
if (!(usr1 & USR2_DCDIN))
tmp |= TIOCM_CAR;
if (sport->dte_mode)
if (!(readl(sport->port.membase + USR2) & USR2_RIIN))
tmp |= TIOCM_RI;
return tmp;
}
/*
* Handle any change of modem status signal since we were last called.
*/
static void imx_mctrl_check(struct imx_port *sport)
{
unsigned int status, changed;
status = imx_get_hwmctrl(sport);
changed = status ^ sport->old_status;
if (changed == 0)
return;
sport->old_status = status;
if (changed & TIOCM_RI && status & TIOCM_RI)
sport->port.icount.rng++;
if (changed & TIOCM_DSR)
sport->port.icount.dsr++;
if (changed & TIOCM_CAR)
uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
if (changed & TIOCM_CTS)
uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
}
static irqreturn_t imx_int(int irq, void *dev_id)
{
struct imx_port *sport = dev_id;
unsigned int sts;
unsigned int sts2;
irqreturn_t ret = IRQ_NONE;
sts = readl(sport->port.membase + USR1);
sts2 = readl(sport->port.membase + USR2);
@ -743,26 +797,47 @@ static irqreturn_t imx_int(int irq, void *dev_id)
imx_dma_rxint(sport);
else
imx_rxint(irq, dev_id);
ret = IRQ_HANDLED;
}
if ((sts & USR1_TRDY &&
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) ||
(sts2 & USR2_TXDC &&
readl(sport->port.membase + UCR4) & UCR4_TCEN))
readl(sport->port.membase + UCR4) & UCR4_TCEN)) {
imx_txint(irq, dev_id);
ret = IRQ_HANDLED;
}
if (sts & USR1_RTSD)
if (sts & USR1_DTRD) {
unsigned long flags;
if (sts & USR1_DTRD)
writel(USR1_DTRD, sport->port.membase + USR1);
spin_lock_irqsave(&sport->port.lock, flags);
imx_mctrl_check(sport);
spin_unlock_irqrestore(&sport->port.lock, flags);
ret = IRQ_HANDLED;
}
if (sts & USR1_RTSD) {
imx_rtsint(irq, dev_id);
ret = IRQ_HANDLED;
}
if (sts & USR1_AWAKE)
if (sts & USR1_AWAKE) {
writel(USR1_AWAKE, sport->port.membase + USR1);
ret = IRQ_HANDLED;
}
if (sts2 & USR2_ORE) {
sport->port.icount.overrun++;
writel(USR2_ORE, sport->port.membase + USR2);
ret = IRQ_HANDLED;
}
return IRQ_HANDLED;
return ret;
}
/*
@ -782,28 +857,6 @@ static unsigned int imx_tx_empty(struct uart_port *port)
return ret;
}
/*
* We have a modem side uart, so the meanings of RTS and CTS are inverted.
*/
static unsigned int imx_get_hwmctrl(struct imx_port *sport)
{
unsigned int tmp = TIOCM_DSR;
unsigned usr1 = readl(sport->port.membase + USR1);
if (usr1 & USR1_RTSS)
tmp |= TIOCM_CTS;
/* in DCE mode DCDIN is always 0 */
if (!(usr1 & USR2_DCDIN))
tmp |= TIOCM_CAR;
/* in DCE mode RIIN is always 0 */
if (readl(sport->port.membase + USR2) & USR2_RIIN)
tmp |= TIOCM_RI;
return tmp;
}
static unsigned int imx_get_mctrl(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
@ -860,33 +913,6 @@ static void imx_break_ctl(struct uart_port *port, int break_state)
spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
* Handle any change of modem status signal since we were last called.
*/
static void imx_mctrl_check(struct imx_port *sport)
{
unsigned int status, changed;
status = imx_get_hwmctrl(sport);
changed = status ^ sport->old_status;
if (changed == 0)
return;
sport->old_status = status;
if (changed & TIOCM_RI)
sport->port.icount.rng++;
if (changed & TIOCM_DSR)
sport->port.icount.dsr++;
if (changed & TIOCM_CAR)
uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
if (changed & TIOCM_CTS)
uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
}
/*
* This is our per-port timeout handler, for checking the
* modem status signals.
@ -1193,7 +1219,7 @@ static int imx_startup(struct uart_port *port)
/*
* Finally, clear and enable interrupts
*/
writel(USR1_RTSD, sport->port.membase + USR1);
writel(USR1_RTSD | USR1_DTRD, sport->port.membase + USR1);
writel(USR2_ORE, sport->port.membase + USR2);
if (sport->dma_is_inited && !sport->dma_is_enabled)
@ -1212,11 +1238,32 @@ static int imx_startup(struct uart_port *port)
temp |= (UCR2_RXEN | UCR2_TXEN);
if (!sport->have_rtscts)
temp |= UCR2_IRTS;
/*
* make sure the edge sensitive RTS-irq is disabled,
* we're using RTSD instead.
*/
if (!is_imx1_uart(sport))
temp &= ~UCR2_RTSEN;
writel(temp, sport->port.membase + UCR2);
if (!is_imx1_uart(sport)) {
temp = readl(sport->port.membase + UCR3);
temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
/*
* The effect of RI and DCD differs depending on the UFCR_DCEDTE
* bit. In DCE mode they control the outputs, in DTE mode they
* enable the respective irqs. At least the DCD irq cannot be
* cleared on i.MX25 at least, so it's not usable and must be
* disabled. I don't have test hardware to check if RI has the
* same problem but I consider this likely so it's disabled for
* now, too.
*/
temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP |
UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
if (sport->dte_mode)
temp &= ~(UCR3_RI | UCR3_DCD);
writel(temp, sport->port.membase + UCR3);
}
@ -1610,19 +1657,17 @@ static int imx_rs485_config(struct uart_port *port,
struct serial_rs485 *rs485conf)
{
struct imx_port *sport = (struct imx_port *)port;
unsigned long temp;
/* unimplemented */
rs485conf->delay_rts_before_send = 0;
rs485conf->delay_rts_after_send = 0;
rs485conf->flags |= SER_RS485_RX_DURING_TX;
/* RTS is required to control the transmitter */
if (!sport->have_rtscts)
rs485conf->flags &= ~SER_RS485_ENABLED;
if (rs485conf->flags & SER_RS485_ENABLED) {
unsigned long temp;
/* disable transmitter */
temp = readl(sport->port.membase + UCR2);
if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
@ -1632,6 +1677,14 @@ static int imx_rs485_config(struct uart_port *port,
writel(temp, sport->port.membase + UCR2);
}
/* Make sure Rx is enabled in case Tx is active with Rx disabled */
if (!(rs485conf->flags & SER_RS485_ENABLED) ||
rs485conf->flags & SER_RS485_RX_DURING_TX) {
temp = readl(sport->port.membase + UCR2);
temp |= UCR2_RXEN;
writel(temp, sport->port.membase + UCR2);
}
port->rs485 = *rs485conf;
return 0;
@ -1927,7 +1980,8 @@ static int serial_imx_probe_dt(struct imx_port *sport,
}
sport->port.line = ret;
if (of_get_property(np, "fsl,uart-has-rtscts", NULL))
if (of_get_property(np, "uart-has-rtscts", NULL) ||
of_get_property(np, "fsl,uart-has-rtscts", NULL) /* deprecated */)
sport->have_rtscts = 1;
if (of_get_property(np, "fsl,dte-mode", NULL))

View File

@ -481,18 +481,13 @@ static void meson_console_putchar(struct uart_port *port, int ch)
writel(ch, port->membase + AML_UART_WFIFO);
}
static void meson_serial_console_write(struct console *co, const char *s,
u_int count)
static void meson_serial_port_write(struct uart_port *port, const char *s,
u_int count)
{
struct uart_port *port;
unsigned long flags;
int locked;
u32 val, tmp;
port = meson_ports[co->index];
if (!port)
return;
local_irq_save(flags);
if (port->sysrq) {
locked = 0;
@ -516,6 +511,18 @@ static void meson_serial_console_write(struct console *co, const char *s,
local_irq_restore(flags);
}
static void meson_serial_console_write(struct console *co, const char *s,
u_int count)
{
struct uart_port *port;
port = meson_ports[co->index];
if (!port)
return;
meson_serial_port_write(port, s, count);
}
static int meson_serial_console_setup(struct console *co, char *options)
{
struct uart_port *port;
@ -554,6 +561,27 @@ static int __init meson_serial_console_init(void)
}
console_initcall(meson_serial_console_init);
static void meson_serial_early_console_write(struct console *co,
const char *s,
u_int count)
{
struct earlycon_device *dev = co->data;
meson_serial_port_write(&dev->port, s, count);
}
static int __init
meson_serial_early_console_setup(struct earlycon_device *device, const char *opt)
{
if (!device->port.membase)
return -ENODEV;
device->con->write = meson_serial_early_console_write;
return 0;
}
OF_EARLYCON_DECLARE(meson, "amlogic,meson-uart",
meson_serial_early_console_setup);
#define MESON_SERIAL_CONSOLE (&meson_serial_console)
#else
#define MESON_SERIAL_CONSOLE NULL

View File

@ -0,0 +1,625 @@
/*
* Copyright (C) 2015 ARM Limited
*
* Author: Vladimir Murzin <vladimir.murzin@arm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* TODO: support for SysRq
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/tty_flip.h>
#include <linux/types.h>
#define SERIAL_NAME "ttyMPS"
#define DRIVER_NAME "mps2-uart"
#define MAKE_NAME(x) (DRIVER_NAME # x)
#define UARTn_DATA 0x00
#define UARTn_STATE 0x04
#define UARTn_STATE_TX_FULL BIT(0)
#define UARTn_STATE_RX_FULL BIT(1)
#define UARTn_STATE_TX_OVERRUN BIT(2)
#define UARTn_STATE_RX_OVERRUN BIT(3)
#define UARTn_CTRL 0x08
#define UARTn_CTRL_TX_ENABLE BIT(0)
#define UARTn_CTRL_RX_ENABLE BIT(1)
#define UARTn_CTRL_TX_INT_ENABLE BIT(2)
#define UARTn_CTRL_RX_INT_ENABLE BIT(3)
#define UARTn_CTRL_TX_OVERRUN_INT_ENABLE BIT(4)
#define UARTn_CTRL_RX_OVERRUN_INT_ENABLE BIT(5)
#define UARTn_INT 0x0c
#define UARTn_INT_TX BIT(0)
#define UARTn_INT_RX BIT(1)
#define UARTn_INT_TX_OVERRUN BIT(2)
#define UARTn_INT_RX_OVERRUN BIT(3)
#define UARTn_BAUDDIV 0x10
#define UARTn_BAUDDIV_MASK GENMASK(20, 0)
/*
* Helpers to make typical enable/disable operations more readable.
*/
#define UARTn_CTRL_TX_GRP (UARTn_CTRL_TX_ENABLE |\
UARTn_CTRL_TX_INT_ENABLE |\
UARTn_CTRL_TX_OVERRUN_INT_ENABLE)
#define UARTn_CTRL_RX_GRP (UARTn_CTRL_RX_ENABLE |\
UARTn_CTRL_RX_INT_ENABLE |\
UARTn_CTRL_RX_OVERRUN_INT_ENABLE)
#define MPS2_MAX_PORTS 3
struct mps2_uart_port {
struct uart_port port;
struct clk *clk;
unsigned int tx_irq;
unsigned int rx_irq;
};
static inline struct mps2_uart_port *to_mps2_port(struct uart_port *port)
{
return container_of(port, struct mps2_uart_port, port);
}
static void mps2_uart_write8(struct uart_port *port, u8 val, unsigned int off)
{
struct mps2_uart_port *mps_port = to_mps2_port(port);
writeb(val, mps_port->port.membase + off);
}
static u8 mps2_uart_read8(struct uart_port *port, unsigned int off)
{
struct mps2_uart_port *mps_port = to_mps2_port(port);
return readb(mps_port->port.membase + off);
}
static void mps2_uart_write32(struct uart_port *port, u32 val, unsigned int off)
{
struct mps2_uart_port *mps_port = to_mps2_port(port);
writel_relaxed(val, mps_port->port.membase + off);
}
static unsigned int mps2_uart_tx_empty(struct uart_port *port)
{
u8 status = mps2_uart_read8(port, UARTn_STATE);
return (status & UARTn_STATE_TX_FULL) ? 0 : TIOCSER_TEMT;
}
static void mps2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
}
static unsigned int mps2_uart_get_mctrl(struct uart_port *port)
{
return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR;
}
static void mps2_uart_stop_tx(struct uart_port *port)
{
u8 control = mps2_uart_read8(port, UARTn_CTRL);
control &= ~UARTn_CTRL_TX_INT_ENABLE;
mps2_uart_write8(port, control, UARTn_CTRL);
}
static void mps2_uart_tx_chars(struct uart_port *port)
{
struct circ_buf *xmit = &port->state->xmit;
while (!(mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)) {
if (port->x_char) {
mps2_uart_write8(port, port->x_char, UARTn_DATA);
port->x_char = 0;
port->icount.tx++;
continue;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
break;
mps2_uart_write8(port, xmit->buf[xmit->tail], UARTn_DATA);
xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE;
port->icount.tx++;
}
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
if (uart_circ_empty(xmit))
mps2_uart_stop_tx(port);
}
static void mps2_uart_start_tx(struct uart_port *port)
{
u8 control = mps2_uart_read8(port, UARTn_CTRL);
control |= UARTn_CTRL_TX_INT_ENABLE;
mps2_uart_write8(port, control, UARTn_CTRL);
/*
* We've just unmasked the TX IRQ and now slow-starting via
* polling; if there is enough data to fill up the internal
* write buffer in one go, the TX IRQ should assert, at which
* point we switch to fully interrupt-driven TX.
*/
mps2_uart_tx_chars(port);
}
static void mps2_uart_stop_rx(struct uart_port *port)
{
u8 control = mps2_uart_read8(port, UARTn_CTRL);
control &= ~UARTn_CTRL_RX_GRP;
mps2_uart_write8(port, control, UARTn_CTRL);
}
static void mps2_uart_break_ctl(struct uart_port *port, int ctl)
{
}
static void mps2_uart_rx_chars(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
while (mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_RX_FULL) {
u8 rxdata = mps2_uart_read8(port, UARTn_DATA);
port->icount.rx++;
tty_insert_flip_char(&port->state->port, rxdata, TTY_NORMAL);
}
tty_flip_buffer_push(tport);
}
static irqreturn_t mps2_uart_rxirq(int irq, void *data)
{
struct uart_port *port = data;
u8 irqflag = mps2_uart_read8(port, UARTn_INT);
if (unlikely(!(irqflag & UARTn_INT_RX)))
return IRQ_NONE;
spin_lock(&port->lock);
mps2_uart_write8(port, UARTn_INT_RX, UARTn_INT);
mps2_uart_rx_chars(port);
spin_unlock(&port->lock);
return IRQ_HANDLED;
}
static irqreturn_t mps2_uart_txirq(int irq, void *data)
{
struct uart_port *port = data;
u8 irqflag = mps2_uart_read8(port, UARTn_INT);
if (unlikely(!(irqflag & UARTn_INT_TX)))
return IRQ_NONE;
spin_lock(&port->lock);
mps2_uart_write8(port, UARTn_INT_TX, UARTn_INT);
mps2_uart_tx_chars(port);
spin_unlock(&port->lock);
return IRQ_HANDLED;
}
static irqreturn_t mps2_uart_oerrirq(int irq, void *data)
{
irqreturn_t handled = IRQ_NONE;
struct uart_port *port = data;
u8 irqflag = mps2_uart_read8(port, UARTn_INT);
spin_lock(&port->lock);
if (irqflag & UARTn_INT_RX_OVERRUN) {
struct tty_port *tport = &port->state->port;
mps2_uart_write8(port, UARTn_INT_RX_OVERRUN, UARTn_INT);
port->icount.overrun++;
tty_insert_flip_char(tport, 0, TTY_OVERRUN);
tty_flip_buffer_push(tport);
handled = IRQ_HANDLED;
}
/*
* It's never been seen in practice and it never *should* happen since
* we check if there is enough room in TX buffer before sending data.
* So we keep this check in case something suspicious has happened.
*/
if (irqflag & UARTn_INT_TX_OVERRUN) {
mps2_uart_write8(port, UARTn_INT_TX_OVERRUN, UARTn_INT);
handled = IRQ_HANDLED;
}
spin_unlock(&port->lock);
return handled;
}
static int mps2_uart_startup(struct uart_port *port)
{
struct mps2_uart_port *mps_port = to_mps2_port(port);
u8 control = mps2_uart_read8(port, UARTn_CTRL);
int ret;
control &= ~(UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP);
mps2_uart_write8(port, control, UARTn_CTRL);
ret = request_irq(mps_port->rx_irq, mps2_uart_rxirq, 0,
MAKE_NAME(-rx), mps_port);
if (ret) {
dev_err(port->dev, "failed to register rxirq (%d)\n", ret);
return ret;
}
ret = request_irq(mps_port->tx_irq, mps2_uart_txirq, 0,
MAKE_NAME(-tx), mps_port);
if (ret) {
dev_err(port->dev, "failed to register txirq (%d)\n", ret);
goto err_free_rxirq;
}
ret = request_irq(port->irq, mps2_uart_oerrirq, IRQF_SHARED,
MAKE_NAME(-overrun), mps_port);
if (ret) {
dev_err(port->dev, "failed to register oerrirq (%d)\n", ret);
goto err_free_txirq;
}
control |= UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP;
mps2_uart_write8(port, control, UARTn_CTRL);
return 0;
err_free_txirq:
free_irq(mps_port->tx_irq, mps_port);
err_free_rxirq:
free_irq(mps_port->rx_irq, mps_port);
return ret;
}
static void mps2_uart_shutdown(struct uart_port *port)
{
struct mps2_uart_port *mps_port = to_mps2_port(port);
u8 control = mps2_uart_read8(port, UARTn_CTRL);
control &= ~(UARTn_CTRL_RX_GRP | UARTn_CTRL_TX_GRP);
mps2_uart_write8(port, control, UARTn_CTRL);
free_irq(mps_port->rx_irq, mps_port);
free_irq(mps_port->tx_irq, mps_port);
free_irq(port->irq, mps_port);
}
static void
mps2_uart_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
unsigned long flags;
unsigned int baud, bauddiv;
termios->c_cflag &= ~(CRTSCTS | CMSPAR);
termios->c_cflag &= ~CSIZE;
termios->c_cflag |= CS8;
termios->c_cflag &= ~PARENB;
termios->c_cflag &= ~CSTOPB;
baud = uart_get_baud_rate(port, termios, old,
DIV_ROUND_CLOSEST(port->uartclk, UARTn_BAUDDIV_MASK),
DIV_ROUND_CLOSEST(port->uartclk, 16));
bauddiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
spin_lock_irqsave(&port->lock, flags);
uart_update_timeout(port, termios->c_cflag, baud);
mps2_uart_write32(port, bauddiv, UARTn_BAUDDIV);
spin_unlock_irqrestore(&port->lock, flags);
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud);
}
static const char *mps2_uart_type(struct uart_port *port)
{
return (port->type == PORT_MPS2UART) ? DRIVER_NAME : NULL;
}
static void mps2_uart_release_port(struct uart_port *port)
{
}
static int mps2_uart_request_port(struct uart_port *port)
{
return 0;
}
static void mps2_uart_config_port(struct uart_port *port, int type)
{
if (type & UART_CONFIG_TYPE && !mps2_uart_request_port(port))
port->type = PORT_MPS2UART;
}
static int mps2_uart_verify_port(struct uart_port *port, struct serial_struct *serinfo)
{
return -EINVAL;
}
static const struct uart_ops mps2_uart_pops = {
.tx_empty = mps2_uart_tx_empty,
.set_mctrl = mps2_uart_set_mctrl,
.get_mctrl = mps2_uart_get_mctrl,
.stop_tx = mps2_uart_stop_tx,
.start_tx = mps2_uart_start_tx,
.stop_rx = mps2_uart_stop_rx,
.break_ctl = mps2_uart_break_ctl,
.startup = mps2_uart_startup,
.shutdown = mps2_uart_shutdown,
.set_termios = mps2_uart_set_termios,
.type = mps2_uart_type,
.release_port = mps2_uart_release_port,
.request_port = mps2_uart_request_port,
.config_port = mps2_uart_config_port,
.verify_port = mps2_uart_verify_port,
};
static struct mps2_uart_port mps2_uart_ports[MPS2_MAX_PORTS];
#ifdef CONFIG_SERIAL_MPS2_UART_CONSOLE
static void mps2_uart_console_putchar(struct uart_port *port, int ch)
{
while (mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)
cpu_relax();
mps2_uart_write8(port, ch, UARTn_DATA);
}
static void mps2_uart_console_write(struct console *co, const char *s, unsigned int cnt)
{
struct uart_port *port = &mps2_uart_ports[co->index].port;
uart_console_write(port, s, cnt, mps2_uart_console_putchar);
}
static int mps2_uart_console_setup(struct console *co, char *options)
{
struct mps2_uart_port *mps_port;
int baud = 9600;
int bits = 8;
int parity = 'n';
int flow = 'n';
if (co->index < 0 || co->index >= MPS2_MAX_PORTS)
return -ENODEV;
mps_port = &mps2_uart_ports[co->index];
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
return uart_set_options(&mps_port->port, co, baud, parity, bits, flow);
}
static struct uart_driver mps2_uart_driver;
static struct console mps2_uart_console = {
.name = SERIAL_NAME,
.device = uart_console_device,
.write = mps2_uart_console_write,
.setup = mps2_uart_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
.data = &mps2_uart_driver,
};
#define MPS2_SERIAL_CONSOLE (&mps2_uart_console)
static void mps2_early_putchar(struct uart_port *port, int ch)
{
while (readb(port->membase + UARTn_STATE) & UARTn_STATE_TX_FULL)
cpu_relax();
writeb((unsigned char)ch, port->membase + UARTn_DATA);
}
static void mps2_early_write(struct console *con, const char *s, unsigned int n)
{
struct earlycon_device *dev = con->data;
uart_console_write(&dev->port, s, n, mps2_early_putchar);
}
static int __init mps2_early_console_setup(struct earlycon_device *device,
const char *opt)
{
if (!device->port.membase)
return -ENODEV;
device->con->write = mps2_early_write;
return 0;
}
OF_EARLYCON_DECLARE(mps2, "arm,mps2-uart", mps2_early_console_setup);
#else
#define MPS2_SERIAL_CONSOLE NULL
#endif
static struct uart_driver mps2_uart_driver = {
.driver_name = DRIVER_NAME,
.dev_name = SERIAL_NAME,
.nr = MPS2_MAX_PORTS,
.cons = MPS2_SERIAL_CONSOLE,
};
static struct mps2_uart_port *mps2_of_get_port(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
int id;
if (!np)
return NULL;
id = of_alias_get_id(np, "serial");
if (id < 0)
id = 0;
if (WARN_ON(id >= MPS2_MAX_PORTS))
return NULL;
mps2_uart_ports[id].port.line = id;
return &mps2_uart_ports[id];
}
static int mps2_init_port(struct mps2_uart_port *mps_port,
struct platform_device *pdev)
{
struct resource *res;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mps_port->port.membase = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(mps_port->port.membase))
return PTR_ERR(mps_port->port.membase);
mps_port->port.mapbase = res->start;
mps_port->port.mapsize = resource_size(res);
mps_port->rx_irq = platform_get_irq(pdev, 0);
mps_port->tx_irq = platform_get_irq(pdev, 1);
mps_port->port.irq = platform_get_irq(pdev, 2);
mps_port->port.iotype = UPIO_MEM;
mps_port->port.flags = UPF_BOOT_AUTOCONF;
mps_port->port.fifosize = 1;
mps_port->port.ops = &mps2_uart_pops;
mps_port->port.dev = &pdev->dev;
mps_port->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(mps_port->clk))
return PTR_ERR(mps_port->clk);
ret = clk_prepare_enable(mps_port->clk);
if (ret)
return ret;
mps_port->port.uartclk = clk_get_rate(mps_port->clk);
clk_disable_unprepare(mps_port->clk);
return ret;
}
static int mps2_serial_probe(struct platform_device *pdev)
{
struct mps2_uart_port *mps_port;
int ret;
mps_port = mps2_of_get_port(pdev);
if (!mps_port)
return -ENODEV;
ret = mps2_init_port(mps_port, pdev);
if (ret)
return ret;
ret = uart_add_one_port(&mps2_uart_driver, &mps_port->port);
if (ret)
return ret;
platform_set_drvdata(pdev, mps_port);
return 0;
}
static int mps2_serial_remove(struct platform_device *pdev)
{
struct mps2_uart_port *mps_port = platform_get_drvdata(pdev);
uart_remove_one_port(&mps2_uart_driver, &mps_port->port);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id mps2_match[] = {
{ .compatible = "arm,mps2-uart", },
{},
};
MODULE_DEVICE_TABLE(of, mps2_match);
#endif
static struct platform_driver mps2_serial_driver = {
.probe = mps2_serial_probe,
.remove = mps2_serial_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(mps2_match),
},
};
static int __init mps2_uart_init(void)
{
int ret;
ret = uart_register_driver(&mps2_uart_driver);
if (ret)
return ret;
ret = platform_driver_register(&mps2_serial_driver);
if (ret)
uart_unregister_driver(&mps2_uart_driver);
return ret;
}
module_init(mps2_uart_init);
static void __exit mps2_uart_exit(void)
{
platform_driver_unregister(&mps2_serial_driver);
uart_unregister_driver(&mps2_uart_driver);
}
module_exit(mps2_uart_exit);
MODULE_AUTHOR("Vladimir Murzin <vladimir.murzin@arm.com>");
MODULE_DESCRIPTION("MPS2 UART driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRIVER_NAME);

View File

@ -861,37 +861,72 @@ struct msm_baud_map {
};
static const struct msm_baud_map *
msm_find_best_baud(struct uart_port *port, unsigned int baud)
msm_find_best_baud(struct uart_port *port, unsigned int baud,
unsigned long *rate)
{
unsigned int i, divisor;
const struct msm_baud_map *entry;
struct msm_port *msm_port = UART_TO_MSM(port);
unsigned int divisor, result;
unsigned long target, old, best_rate = 0, diff, best_diff = ULONG_MAX;
const struct msm_baud_map *entry, *end, *best;
static const struct msm_baud_map table[] = {
{ 1536, 0x00, 1 },
{ 768, 0x11, 1 },
{ 384, 0x22, 1 },
{ 192, 0x33, 1 },
{ 96, 0x44, 1 },
{ 48, 0x55, 1 },
{ 32, 0x66, 1 },
{ 24, 0x77, 1 },
{ 16, 0x88, 1 },
{ 12, 0x99, 6 },
{ 8, 0xaa, 6 },
{ 6, 0xbb, 6 },
{ 4, 0xcc, 6 },
{ 3, 0xdd, 8 },
{ 2, 0xee, 16 },
{ 1, 0xff, 31 },
{ 0, 0xff, 31 },
{ 2, 0xee, 16 },
{ 3, 0xdd, 8 },
{ 4, 0xcc, 6 },
{ 6, 0xbb, 6 },
{ 8, 0xaa, 6 },
{ 12, 0x99, 6 },
{ 16, 0x88, 1 },
{ 24, 0x77, 1 },
{ 32, 0x66, 1 },
{ 48, 0x55, 1 },
{ 96, 0x44, 1 },
{ 192, 0x33, 1 },
{ 384, 0x22, 1 },
{ 768, 0x11, 1 },
{ 1536, 0x00, 1 },
};
divisor = uart_get_divisor(port, baud);
best = table; /* Default to smallest divider */
target = clk_round_rate(msm_port->clk, 16 * baud);
divisor = DIV_ROUND_CLOSEST(target, 16 * baud);
for (i = 0, entry = table; i < ARRAY_SIZE(table); i++, entry++)
if (entry->divisor <= divisor)
break;
end = table + ARRAY_SIZE(table);
entry = table;
while (entry < end) {
if (entry->divisor <= divisor) {
result = target / entry->divisor / 16;
diff = abs(result - baud);
return entry; /* Default to smallest divider */
/* Keep track of best entry */
if (diff < best_diff) {
best_diff = diff;
best = entry;
best_rate = target;
}
if (result == baud)
break;
} else if (entry->divisor > divisor) {
old = target;
target = clk_round_rate(msm_port->clk, old + 1);
/*
* The rate didn't get any faster so we can't do
* better at dividing it down
*/
if (target == old)
break;
/* Start the divisor search over at this new rate */
entry = table;
divisor = DIV_ROUND_CLOSEST(target, 16 * baud);
continue;
}
entry++;
}
*rate = best_rate;
return best;
}
static int msm_set_baud_rate(struct uart_port *port, unsigned int baud,
@ -900,22 +935,20 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud,
unsigned int rxstale, watermark, mask;
struct msm_port *msm_port = UART_TO_MSM(port);
const struct msm_baud_map *entry;
unsigned long flags;
entry = msm_find_best_baud(port, baud);
msm_write(port, entry->code, UART_CSR);
if (baud > 460800)
port->uartclk = baud * 16;
unsigned long flags, rate;
flags = *saved_flags;
spin_unlock_irqrestore(&port->lock, flags);
clk_set_rate(msm_port->clk, port->uartclk);
entry = msm_find_best_baud(port, baud, &rate);
clk_set_rate(msm_port->clk, rate);
baud = rate / 16 / entry->divisor;
spin_lock_irqsave(&port->lock, flags);
*saved_flags = flags;
port->uartclk = rate;
msm_write(port, entry->code, UART_CSR);
/* RX stale watermark */
rxstale = entry->rxstale;
@ -1577,8 +1610,6 @@ static int msm_serial_probe(struct platform_device *pdev)
msm_port->pclk = devm_clk_get(&pdev->dev, "iface");
if (IS_ERR(msm_port->pclk))
return PTR_ERR(msm_port->pclk);
clk_set_rate(msm_port->clk, 1843200);
}
port->uartclk = clk_get_rate(msm_port->clk);

View File

@ -1,5 +1,7 @@
/*
* ***************************************************************************
* Marvell Armada-3700 Serial Driver
* Author: Wilson Ding <dingwei@marvell.com>
* Copyright (C) 2015 Marvell International Ltd.
* ***************************************************************************
* This program is free software: you can redistribute it and/or modify it
@ -23,7 +25,6 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
@ -594,30 +595,18 @@ static int mvebu_uart_probe(struct platform_device *pdev)
return 0;
}
static int mvebu_uart_remove(struct platform_device *pdev)
{
struct mvebu_uart_data *data = platform_get_drvdata(pdev);
uart_remove_one_port(&mvebu_uart_driver, data->port);
data->port->private_data = NULL;
data->port->mapbase = 0;
return 0;
}
/* Match table for of_platform binding */
static const struct of_device_id mvebu_uart_of_match[] = {
{ .compatible = "marvell,armada-3700-uart", },
{}
};
MODULE_DEVICE_TABLE(of, mvebu_uart_of_match);
static struct platform_driver mvebu_uart_platform_driver = {
.probe = mvebu_uart_probe,
.remove = mvebu_uart_remove,
.driver = {
.owner = THIS_MODULE,
.name = "mvebu-uart",
.of_match_table = of_match_ptr(mvebu_uart_of_match),
.suppress_bind_attrs = true,
},
};
@ -635,16 +624,4 @@ static int __init mvebu_uart_init(void)
return ret;
}
static void __exit mvebu_uart_exit(void)
{
platform_driver_unregister(&mvebu_uart_platform_driver);
uart_unregister_driver(&mvebu_uart_driver);
}
arch_initcall(mvebu_uart_init);
module_exit(mvebu_uart_exit);
MODULE_AUTHOR("Wilson Ding <dingwei@marvell.com>");
MODULE_DESCRIPTION("Marvell Armada-3700 Serial Driver");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@ -1271,6 +1271,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
/* check to see if we need to change clock source */
if (ourport->baudclk != clk) {
clk_prepare_enable(clk);
s3c24xx_serial_setsource(port, clk_sel);
if (!IS_ERR(ourport->baudclk)) {
@ -1278,8 +1280,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
ourport->baudclk = ERR_PTR(-EINVAL);
}
clk_prepare_enable(clk);
ourport->baudclk = clk;
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
}

View File

@ -666,7 +666,7 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
struct uart_port *port = &s->p[portno].port;
do {
unsigned int iir, msr, rxlen;
unsigned int iir, rxlen;
iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG);
if (iir & SC16IS7XX_IIR_NO_INT_BIT)
@ -683,12 +683,6 @@ static void sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
if (rxlen)
sc16is7xx_handle_rx(port, rxlen, iir);
break;
case SC16IS7XX_IIR_CTSRTS_SRC:
msr = sc16is7xx_port_read(port, SC16IS7XX_MSR_REG);
uart_handle_cts_change(port,
!!(msr & SC16IS7XX_MSR_DCTS_BIT));
break;
case SC16IS7XX_IIR_THRI_SRC:
sc16is7xx_handle_tx(port);
break;
@ -1014,9 +1008,8 @@ static int sc16is7xx_startup(struct uart_port *port)
SC16IS7XX_EFCR_TXDISABLE_BIT,
0);
/* Enable RX, TX, CTS change interrupts */
val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_THRI_BIT |
SC16IS7XX_IER_CTSI_BIT;
/* Enable RX, TX interrupts */
val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_THRI_BIT;
sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val);
return 0;

View File

@ -206,10 +206,8 @@ static void set_dtr(struct tegra_uart_port *tup, bool active)
static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl)
{
struct tegra_uart_port *tup = to_tegra_uport(u);
unsigned long mcr;
int dtr_enable;
mcr = tup->mcr_shadow;
tup->rts_active = !!(mctrl & TIOCM_RTS);
set_rts(tup, tup->rts_active);

File diff suppressed because it is too large Load Diff

View File

@ -43,8 +43,6 @@ static const struct {
{ "rng", TIOCM_RNG, false, },
{ "rts", TIOCM_RTS, true, },
{ "dtr", TIOCM_DTR, true, },
{ "out1", TIOCM_OUT1, true, },
{ "out2", TIOCM_OUT2, true, },
};
void mctrl_gpio_set(struct mctrl_gpios *gpios, unsigned int mctrl)
@ -125,9 +123,12 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context)
struct uart_port *port = gpios->port;
u32 mctrl = gpios->mctrl_prev;
u32 mctrl_diff;
unsigned long flags;
mctrl_gpio_get(gpios, &mctrl);
spin_lock_irqsave(&port->lock, flags);
mctrl_diff = mctrl ^ gpios->mctrl_prev;
gpios->mctrl_prev = mctrl;
@ -147,6 +148,8 @@ static irqreturn_t mctrl_gpio_irq_handle(int irq, void *context)
wake_up_interruptible(&port->state->port.delta_msr_wait);
}
spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}

View File

@ -32,8 +32,6 @@ enum mctrl_gpio_idx {
UART_GPIO_RI = UART_GPIO_RNG,
UART_GPIO_RTS,
UART_GPIO_DTR,
UART_GPIO_OUT1,
UART_GPIO_OUT2,
UART_GPIO_MAX,
};

View File

@ -1264,6 +1264,7 @@ MODULE_DEVICE_TABLE(of, sirfsoc_uart_ids);
static int sirfsoc_uart_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct sirfsoc_uart_port *sirfport;
struct uart_port *port;
struct resource *res;
@ -1276,13 +1277,13 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
};
const struct of_device_id *match;
match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node);
match = of_match_node(sirfsoc_uart_ids, np);
sirfport = devm_kzalloc(&pdev->dev, sizeof(*sirfport), GFP_KERNEL);
if (!sirfport) {
ret = -ENOMEM;
goto err;
}
sirfport->port.line = of_alias_get_id(pdev->dev.of_node, "serial");
sirfport->port.line = of_alias_get_id(np, "serial");
sirf_ports[sirfport->port.line] = sirfport;
sirfport->port.iotype = UPIO_MEM;
sirfport->port.flags = UPF_BOOT_AUTOCONF;
@ -1291,25 +1292,25 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
port->private_data = sirfport;
sirfport->uart_reg = (struct sirfsoc_uart_register *)match->data;
sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node,
"sirf,uart-has-rtscts");
if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart") ||
of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart"))
sirfport->hw_flow_ctrl =
of_property_read_bool(np, "uart-has-rtscts") ||
of_property_read_bool(np, "sirf,uart-has-rtscts") /* deprecated */;
if (of_device_is_compatible(np, "sirf,prima2-uart") ||
of_device_is_compatible(np, "sirf,atlas7-uart"))
sirfport->uart_reg->uart_type = SIRF_REAL_UART;
if (of_device_is_compatible(pdev->dev.of_node,
"sirf,prima2-usp-uart") || of_device_is_compatible(
pdev->dev.of_node, "sirf,atlas7-usp-uart")) {
if (of_device_is_compatible(np, "sirf,prima2-usp-uart") ||
of_device_is_compatible(np, "sirf,atlas7-usp-uart")) {
sirfport->uart_reg->uart_type = SIRF_USP_UART;
if (!sirfport->hw_flow_ctrl)
goto usp_no_flow_control;
if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL))
sirfport->cts_gpio = of_get_named_gpio(
pdev->dev.of_node, "cts-gpios", 0);
if (of_find_property(np, "cts-gpios", NULL))
sirfport->cts_gpio =
of_get_named_gpio(np, "cts-gpios", 0);
else
sirfport->cts_gpio = -1;
if (of_find_property(pdev->dev.of_node, "rts-gpios", NULL))
sirfport->rts_gpio = of_get_named_gpio(
pdev->dev.of_node, "rts-gpios", 0);
if (of_find_property(np, "rts-gpios", NULL))
sirfport->rts_gpio =
of_get_named_gpio(np, "rts-gpios", 0);
else
sirfport->rts_gpio = -1;
@ -1336,13 +1337,11 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
gpio_direction_output(sirfport->rts_gpio, 1);
}
usp_no_flow_control:
if (of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-uart") ||
of_device_is_compatible(pdev->dev.of_node, "sirf,atlas7-usp-uart"))
if (of_device_is_compatible(np, "sirf,atlas7-uart") ||
of_device_is_compatible(np, "sirf,atlas7-usp-uart"))
sirfport->is_atlas7 = true;
if (of_property_read_u32(pdev->dev.of_node,
"fifosize",
&port->fifosize)) {
if (of_property_read_u32(np, "fifosize", &port->fifosize)) {
dev_err(&pdev->dev,
"Unable to find fifosize in uart node.\n");
ret = -EFAULT;

View File

@ -72,7 +72,7 @@ static void uartlite_outbe32(u32 val, void __iomem *addr)
iowrite32be(val, addr);
}
static struct uartlite_reg_ops uartlite_be = {
static const struct uartlite_reg_ops uartlite_be = {
.in = uartlite_inbe32,
.out = uartlite_outbe32,
};
@ -87,21 +87,21 @@ static void uartlite_outle32(u32 val, void __iomem *addr)
iowrite32(val, addr);
}
static struct uartlite_reg_ops uartlite_le = {
static const struct uartlite_reg_ops uartlite_le = {
.in = uartlite_inle32,
.out = uartlite_outle32,
};
static inline u32 uart_in32(u32 offset, struct uart_port *port)
{
struct uartlite_reg_ops *reg_ops = port->private_data;
const struct uartlite_reg_ops *reg_ops = port->private_data;
return reg_ops->in(port->membase + offset);
}
static inline void uart_out32(u32 val, u32 offset, struct uart_port *port)
{
struct uartlite_reg_ops *reg_ops = port->private_data;
const struct uartlite_reg_ops *reg_ops = port->private_data;
reg_ops->out(val, port->membase + offset);
}
@ -345,13 +345,13 @@ static int ulite_request_port(struct uart_port *port)
return -EBUSY;
}
port->private_data = &uartlite_be;
port->private_data = (void *)&uartlite_be;
ret = uart_in32(ULITE_CONTROL, port);
uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port);
ret = uart_in32(ULITE_STATUS, port);
/* Endianess detection */
if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY)
port->private_data = &uartlite_le;
port->private_data = (void *)&uartlite_le;
return 0;
}

View File

@ -1478,6 +1478,9 @@ static const struct of_device_id ucc_uart_match[] = {
.type = "serial",
.compatible = "ucc_uart",
},
{
.compatible = "fsl,t1040-ucc-uart",
},
{},
};
MODULE_DEVICE_TABLE(of, ucc_uart_match);

View File

@ -1340,7 +1340,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
if ( (info->port.flags & ASYNC_CHECK_CD) &&
if (tty_port_check_carrier(&info->port) &&
(status & MISCSTATUS_DCD_LATCHED) ) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("%s CD now %s...", info->device_name,
@ -1361,8 +1361,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
if (status & MISCSTATUS_CTS) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx start...");
if (info->port.tty)
info->port.tty->hw_stopped = 0;
info->port.tty->hw_stopped = 0;
usc_start_transmitter(info);
info->pending_bh |= BH_TRANSMIT;
return;
@ -1749,13 +1748,13 @@ static irqreturn_t mgsl_interrupt(int dummy, void *dev_id)
static int startup(struct mgsl_struct * info)
{
int retval = 0;
if ( debug_level >= DEBUG_LEVEL_INFO )
printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
return 0;
if (!info->xmit_buf) {
/* allocate a page of memory for a transmit buffer */
info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
@ -1788,14 +1787,13 @@ static int startup(struct mgsl_struct * info)
/* program hardware for current parameters */
mgsl_change_params(info);
if (info->port.tty)
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
return 0;
} /* end of startup() */
/* shutdown()
@ -1808,8 +1806,8 @@ static int startup(struct mgsl_struct * info)
static void shutdown(struct mgsl_struct * info)
{
unsigned long flags;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
if (debug_level >= DEBUG_LEVEL_INFO)
@ -1853,13 +1851,12 @@ static void shutdown(struct mgsl_struct * info)
spin_unlock_irqrestore(&info->irq_spinlock,flags);
mgsl_release_resources(info);
mgsl_release_resources(info);
if (info->port.tty)
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
} /* end of shutdown() */
static void mgsl_program_hw(struct mgsl_struct *info)
@ -1966,15 +1963,8 @@ static void mgsl_change_params(struct mgsl_struct *info)
}
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
info->port.flags |= ASYNC_CTS_FLOW;
else
info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
info->port.flags &= ~ASYNC_CHECK_CD;
else
info->port.flags |= ASYNC_CHECK_CD;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
/* process tty input control flags */
@ -2972,7 +2962,7 @@ static int mgsl_ioctl(struct tty_struct *tty,
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCMIWAIT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}
@ -3049,7 +3039,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio
/* Handle transition away from B0 status */
if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) {
info->serial_signals |= SerialSignal_DTR;
if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
info->serial_signals |= SerialSignal_RTS;
spin_lock_irqsave(&info->irq_spinlock,flags);
usc_set_serial_signals(info);
@ -3091,7 +3081,7 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
goto cleanup;
mutex_lock(&info->port.mutex);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
mgsl_wait_until_sent(tty, info->timeout);
mgsl_flush_buffer(tty);
tty_ldisc_flush(tty);
@ -3129,15 +3119,15 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_wait_until_sent(%s) entry\n",
__FILE__,__LINE__, info->device_name );
if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent"))
return;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
goto exit;
orig_jiffies = jiffies;
/* Set check interval to 1/5 of estimated time to
* send a character, and make it at least 1. The check
* interval should also be less than the timeout.
@ -3204,7 +3194,7 @@ static void mgsl_hangup(struct tty_struct *tty)
shutdown(info);
info->port.count = 0;
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
tty_port_set_active(&info->port, 0);
info->port.tty = NULL;
wake_up_interruptible(&info->port.open_wait);
@ -3270,9 +3260,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
printk("%s(%d):block_til_ready on %s\n",
__FILE__,__LINE__, tty->driver->name );
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) {
/* nonblock mode is set or port is not enabled */
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
return 0;
}
@ -3297,14 +3287,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
port->count--;
spin_unlock_irqrestore(&info->irq_spinlock, flags);
port->blocked_open++;
while (1) {
if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
if (C_BAUD(tty) && tty_port_initialized(port))
tty_port_raise_dtr_rts(port);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
retval = (port->flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS;
break;
@ -3341,7 +3331,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
__FILE__,__LINE__, tty->driver->name, port->count );
if (!retval)
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
return retval;

View File

@ -726,7 +726,7 @@ static void close(struct tty_struct *tty, struct file *filp)
goto cleanup;
mutex_lock(&info->port.mutex);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
wait_until_sent(tty, info->timeout);
flush_buffer(tty);
tty_ldisc_flush(tty);
@ -756,9 +756,9 @@ static void hangup(struct tty_struct *tty)
spin_lock_irqsave(&info->port.lock, flags);
info->port.count = 0;
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
info->port.tty = NULL;
spin_unlock_irqrestore(&info->port.lock, flags);
tty_port_set_active(&info->port, 0);
mutex_unlock(&info->port.mutex);
wake_up_interruptible(&info->port.open_wait);
@ -784,7 +784,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
/* Handle transition away from B0 status */
if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) {
info->signals |= SerialSignal_DTR;
if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
info->signals |= SerialSignal_RTS;
spin_lock_irqsave(&info->lock,flags);
set_signals(info);
@ -893,7 +893,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
if (sanity_check(info, tty->name, "wait_until_sent"))
return;
DBGINFO(("%s wait_until_sent entry\n", info->device_name));
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
goto exit;
orig_jiffies = jiffies;
@ -1032,7 +1032,7 @@ static int ioctl(struct tty_struct *tty,
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCMIWAIT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}
@ -2080,7 +2080,7 @@ static void dcd_change(struct slgt_info *info, unsigned short status)
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
if (info->port.flags & ASYNC_CHECK_CD) {
if (tty_port_check_carrier(&info->port)) {
if (info->signals & SerialSignal_DCD)
wake_up_interruptible(&info->port.open_wait);
else {
@ -2421,7 +2421,7 @@ static int startup(struct slgt_info *info)
{
DBGINFO(("%s startup\n", info->device_name));
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
return 0;
if (!info->tx_buf) {
@ -2442,7 +2442,7 @@ static int startup(struct slgt_info *info)
if (info->port.tty)
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
return 0;
}
@ -2454,7 +2454,7 @@ static void shutdown(struct slgt_info *info)
{
unsigned long flags;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
DBGINFO(("%s shutdown\n", info->device_name));
@ -2489,7 +2489,7 @@ static void shutdown(struct slgt_info *info)
if (info->port.tty)
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
}
static void program_hw(struct slgt_info *info)
@ -2576,15 +2576,8 @@ static void change_params(struct slgt_info *info)
}
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
info->port.flags |= ASYNC_CTS_FLOW;
else
info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
info->port.flags &= ~ASYNC_CHECK_CD;
else
info->port.flags |= ASYNC_CHECK_CD;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
/* process tty input control flags */
@ -3269,9 +3262,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
DBGINFO(("%s block_til_ready\n", tty->driver->name));
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) {
/* nonblock mode is set or port is not enabled */
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
return 0;
}
@ -3294,12 +3287,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
port->blocked_open++;
while (1) {
if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
if (C_BAUD(tty) && tty_port_initialized(port))
tty_port_raise_dtr_rts(port);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
retval = (port->flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS;
break;
@ -3328,7 +3321,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
port->blocked_open--;
if (!retval)
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
return retval;

View File

@ -812,7 +812,7 @@ static void close(struct tty_struct *tty, struct file *filp)
goto cleanup;
mutex_lock(&info->port.mutex);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
wait_until_sent(tty, info->timeout);
flush_buffer(tty);
@ -849,9 +849,9 @@ static void hangup(struct tty_struct *tty)
spin_lock_irqsave(&info->port.lock, flags);
info->port.count = 0;
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
info->port.tty = NULL;
spin_unlock_irqrestore(&info->port.lock, flags);
tty_port_set_active(&info->port, 1);
mutex_unlock(&info->port.mutex);
wake_up_interruptible(&info->port.open_wait);
@ -881,7 +881,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
/* Handle transition away from B0 status */
if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) {
info->serial_signals |= SerialSignal_DTR;
if (!C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags))
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
info->serial_signals |= SerialSignal_RTS;
spin_lock_irqsave(&info->lock,flags);
set_signals(info);
@ -1061,7 +1061,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
if (sanity_check(info, tty->name, "wait_until_sent"))
return;
if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags))
if (!tty_port_initialized(&info->port))
goto exit;
orig_jiffies = jiffies;
@ -1261,7 +1261,7 @@ static int ioctl(struct tty_struct *tty,
if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
(cmd != TIOCMIWAIT)) {
if (tty->flags & (1 << TTY_IO_ERROR))
if (tty_io_error(tty))
return -EIO;
}
@ -2463,7 +2463,7 @@ static void isr_io_pin( SLMP_INFO *info, u16 status )
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
if ( (info->port.flags & ASYNC_CHECK_CD) &&
if (tty_port_check_carrier(&info->port) &&
(status & MISCSTATUS_DCD_LATCHED) ) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("%s CD now %s...", info->device_name,
@ -2636,7 +2636,7 @@ static int startup(SLMP_INFO * info)
if ( debug_level >= DEBUG_LEVEL_INFO )
printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name);
if (info->port.flags & ASYNC_INITIALIZED)
if (tty_port_initialized(&info->port))
return 0;
if (!info->tx_buf) {
@ -2662,7 +2662,7 @@ static int startup(SLMP_INFO * info)
if (info->port.tty)
clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags |= ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 1);
return 0;
}
@ -2673,7 +2673,7 @@ static void shutdown(SLMP_INFO * info)
{
unsigned long flags;
if (!(info->port.flags & ASYNC_INITIALIZED))
if (!tty_port_initialized(&info->port))
return;
if (debug_level >= DEBUG_LEVEL_INFO)
@ -2705,7 +2705,7 @@ static void shutdown(SLMP_INFO * info)
if (info->port.tty)
set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->port.flags &= ~ASYNC_INITIALIZED;
tty_port_set_initialized(&info->port, 0);
}
static void program_hw(SLMP_INFO *info)
@ -2813,15 +2813,8 @@ static void change_params(SLMP_INFO *info)
}
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
info->port.flags |= ASYNC_CTS_FLOW;
else
info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
info->port.flags &= ~ASYNC_CHECK_CD;
else
info->port.flags |= ASYNC_CHECK_CD;
tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
/* process tty input control flags */
@ -3285,10 +3278,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
printk("%s(%d):%s block_til_ready()\n",
__FILE__,__LINE__, tty->driver->name );
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) {
/* nonblock mode is set or port is not enabled */
/* just verify that callout device is not active */
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
return 0;
}
@ -3315,12 +3308,12 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
port->blocked_open++;
while (1) {
if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
if (C_BAUD(tty) && tty_port_initialized(port))
tty_port_raise_dtr_rts(port);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)){
if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
retval = (port->flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS;
break;
@ -3355,7 +3348,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
__FILE__,__LINE__, tty->driver->name, port->count );
if (!retval)
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
return retval;
}

View File

@ -37,29 +37,6 @@
#define TTY_BUFFER_PAGE (((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
/*
* If all tty flip buffers have been processed by flush_to_ldisc() or
* dropped by tty_buffer_flush(), check if the linked pty has been closed.
* If so, wake the reader/poll to process
*/
static inline void check_other_closed(struct tty_struct *tty)
{
unsigned long flags, old;
/* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */
for (flags = ACCESS_ONCE(tty->flags);
test_bit(TTY_OTHER_CLOSED, &flags);
) {
old = flags;
__set_bit(TTY_OTHER_DONE, &flags);
flags = cmpxchg(&tty->flags, old, flags);
if (old == flags) {
wake_up_interruptible(&tty->read_wait);
break;
}
}
}
/**
* tty_buffer_lock_exclusive - gain exclusive access to buffer
* tty_buffer_unlock_exclusive - release exclusive access
@ -254,8 +231,6 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
if (ld && ld->ops->flush_buffer)
ld->ops->flush_buffer(tty);
check_other_closed(tty);
atomic_dec(&buf->priority);
mutex_unlock(&buf->lock);
}
@ -522,10 +497,8 @@ static void flush_to_ldisc(struct work_struct *work)
*/
count = smp_load_acquire(&head->commit) - head->read;
if (!count) {
if (next == NULL) {
check_other_closed(tty);
if (next == NULL)
break;
}
buf->head = next;
tty_buffer_free(port, head);
continue;
@ -614,3 +587,8 @@ bool tty_buffer_cancel_work(struct tty_port *port)
{
return cancel_work_sync(&port->buf.work);
}
void tty_buffer_flush_work(struct tty_port *port)
{
flush_work(&port->buf.work);
}

View File

@ -230,9 +230,6 @@ static void tty_del_file(struct file *file)
tty_free_file(file);
}
#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
/**
* tty_name - return tty naming
* @tty: tty structure
@ -1070,7 +1067,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
if (tty_paranoia_check(tty, inode, "tty_read"))
return -EIO;
if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
if (!tty || tty_io_error(tty))
return -EIO;
/* We want to wait for the line discipline to sort out in this
@ -1245,8 +1242,7 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
if (tty_paranoia_check(tty, file_inode(file), "tty_write"))
return -EIO;
if (!tty || !tty->ops->write ||
(test_bit(TTY_IO_ERROR, &tty->flags)))
if (!tty || !tty->ops->write || tty_io_error(tty))
return -EIO;
/* Short term debug to catch buggy drivers */
if (tty->ops->write_room == NULL)
@ -1964,7 +1960,6 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp)
* tty_lookup_driver - lookup a tty driver for a given device file
* @device: device number
* @filp: file pointer to tty
* @noctty: set if the device should not become a controlling tty
* @index: index for the device in the @return driver
* @return: driver for this inode (with increased refcount)
*

View File

@ -158,7 +158,7 @@ int tty_throttle_safe(struct tty_struct *tty)
int ret = 0;
mutex_lock(&tty->throttle_mutex);
if (!test_bit(TTY_THROTTLED, &tty->flags)) {
if (!tty_throttled(tty)) {
if (tty->flow_change != TTY_THROTTLE_SAFE)
ret = 1;
else {
@ -189,7 +189,7 @@ int tty_unthrottle_safe(struct tty_struct *tty)
int ret = 0;
mutex_lock(&tty->throttle_mutex);
if (test_bit(TTY_THROTTLED, &tty->flags)) {
if (tty_throttled(tty)) {
if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
ret = 1;
else {

View File

@ -204,7 +204,8 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
if (port->console)
goto out;
if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
if (tty_port_initialized(port)) {
tty_port_set_initialized(port, 0);
/*
* Drop DTR/RTS if HUPCL is set. This causes any attached
* modem to hang up the line.
@ -236,12 +237,12 @@ void tty_port_hangup(struct tty_port *port)
spin_lock_irqsave(&port->lock, flags);
port->count = 0;
port->flags &= ~ASYNC_NORMAL_ACTIVE;
tty = port->tty;
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
port->tty = NULL;
spin_unlock_irqrestore(&port->lock, flags);
tty_port_set_active(port, 0);
tty_port_shutdown(port, tty);
tty_kref_put(tty);
wake_up_interruptible(&port->open_wait);
@ -364,15 +365,15 @@ int tty_port_block_til_ready(struct tty_port *port,
/* if non-blocking mode is set we can pass directly to open unless
the port has just hung up or is in another error state */
if (tty->flags & (1 << TTY_IO_ERROR)) {
port->flags |= ASYNC_NORMAL_ACTIVE;
if (tty_io_error(tty)) {
tty_port_set_active(port, 1);
return 0;
}
if (filp->f_flags & O_NONBLOCK) {
/* Indicate we are open */
if (C_BAUD(tty))
tty_port_raise_dtr_rts(port);
port->flags |= ASYNC_NORMAL_ACTIVE;
tty_port_set_active(port, 1);
return 0;
}
@ -393,13 +394,13 @@ int tty_port_block_til_ready(struct tty_port *port,
while (1) {
/* Indicate we are open */
if (C_BAUD(tty) && test_bit(ASYNCB_INITIALIZED, &port->flags))
if (C_BAUD(tty) && tty_port_initialized(port))
tty_port_raise_dtr_rts(port);
prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
/* Check for a hangup or uninitialised port.
Return accordingly */
if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
if (port->flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
@ -430,9 +431,9 @@ int tty_port_block_til_ready(struct tty_port *port,
if (!tty_hung_up_p(filp))
port->count++;
port->blocked_open--;
if (retval == 0)
port->flags |= ASYNC_NORMAL_ACTIVE;
spin_unlock_irqrestore(&port->lock, flags);
if (retval == 0)
tty_port_set_active(port, 1);
return retval;
}
EXPORT_SYMBOL(tty_port_block_til_ready);
@ -480,7 +481,7 @@ int tty_port_close_start(struct tty_port *port,
tty->closing = 1;
if (test_bit(ASYNCB_INITIALIZED, &port->flags)) {
if (tty_port_initialized(port)) {
/* Don't block on a stalled port, just pull the chain */
if (tty->flow_stopped)
tty_driver_flush_buffer(tty);
@ -514,8 +515,8 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
spin_lock_irqsave(&port->lock, flags);
wake_up_interruptible(&port->open_wait);
}
port->flags &= ~ASYNC_NORMAL_ACTIVE;
spin_unlock_irqrestore(&port->lock, flags);
tty_port_set_active(port, 0);
}
EXPORT_SYMBOL(tty_port_close_end);
@ -578,7 +579,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
mutex_lock(&port->mutex);
if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
if (!tty_port_initialized(port)) {
clear_bit(TTY_IO_ERROR, &tty->flags);
if (port->ops->activate) {
int retval = port->ops->activate(port, tty);
@ -587,7 +588,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
return retval;
}
}
set_bit(ASYNCB_INITIALIZED, &port->flags);
tty_port_set_initialized(port, 1);
}
mutex_unlock(&port->mutex);
return tty_port_block_til_ready(port, tty, filp);

View File

@ -354,7 +354,7 @@ int paste_selection(struct tty_struct *tty)
add_wait_queue(&vc->paste_wait, &wait);
while (sel_buffer && sel_buffer_lth > pasted) {
set_current_state(TASK_INTERRUPTIBLE);
if (test_bit(TTY_THROTTLED, &tty->flags)) {
if (tty_throttled(tty)) {
schedule();
continue;
}

View File

@ -760,50 +760,54 @@ static void visual_init(struct vc_data *vc, int num, int init)
int vc_allocate(unsigned int currcons) /* return 0 on success */
{
struct vt_notifier_param param;
struct vc_data *vc;
WARN_CONSOLE_UNLOCKED();
if (currcons >= MAX_NR_CONSOLES)
return -ENXIO;
if (!vc_cons[currcons].d) {
struct vc_data *vc;
struct vt_notifier_param param;
/* prevent users from taking too much memory */
if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
return -EPERM;
if (vc_cons[currcons].d)
return 0;
/* due to the granularity of kmalloc, we waste some memory here */
/* the alloc is done in two steps, to optimize the common situation
of a 25x80 console (structsize=216, screenbuf_size=4000) */
/* although the numbers above are not valid since long ago, the
point is still up-to-date and the comment still has its value
even if only as a historical artifact. --mj, July 1998 */
param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
if (!vc)
/* due to the granularity of kmalloc, we waste some memory here */
/* the alloc is done in two steps, to optimize the common situation
of a 25x80 console (structsize=216, screenbuf_size=4000) */
/* although the numbers above are not valid since long ago, the
point is still up-to-date and the comment still has its value
even if only as a historical artifact. --mj, July 1998 */
param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
if (!vc)
return -ENOMEM;
vc_cons[currcons].d = vc;
tty_port_init(&vc->port);
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
visual_init(vc, currcons, 1);
if (!*vc->vc_uni_pagedir_loc)
vc_cons[currcons].d = vc;
tty_port_init(&vc->port);
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
visual_init(vc, currcons, 1);
if (!*vc->vc_uni_pagedir_loc)
con_set_default_unimap(vc);
vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
if (!vc->vc_screenbuf) {
kfree(vc);
vc_cons[currcons].d = NULL;
return -ENOMEM;
}
/* If no drivers have overridden us and the user didn't pass a
boot option, default to displaying the cursor */
if (global_cursor_default == -1)
global_cursor_default = 1;
vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
if (!vc->vc_screenbuf)
goto err_free;
/* If no drivers have overridden us and the user didn't pass a
boot option, default to displaying the cursor */
if (global_cursor_default == -1)
global_cursor_default = 1;
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
}
return 0;
err_free:
kfree(vc);
vc_cons[currcons].d = NULL;
return -ENOMEM;
}
static inline int resize_screen(struct vc_data *vc, int width, int height,
@ -1035,20 +1039,27 @@ struct vc_data *vc_deallocate(unsigned int currcons)
#define VT100ID "\033[?1;2c"
#define VT102ID "\033[?6c"
unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
8,12,10,14, 9,13,11,15 };
/* the default colour table, for VGA+ colour systems */
int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
unsigned char default_red[] = {
0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff
};
module_param_array(default_red, byte, NULL, S_IRUGO | S_IWUSR);
module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
unsigned char default_grn[] = {
0x00, 0x00, 0xaa, 0x55, 0x00, 0x00, 0xaa, 0xaa,
0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff
};
module_param_array(default_grn, byte, NULL, S_IRUGO | S_IWUSR);
unsigned char default_blu[] = {
0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa,
0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff
};
module_param_array(default_blu, byte, NULL, S_IRUGO | S_IWUSR);
/*
* gotoxy() must verify all boundaries, because the arguments
@ -3564,7 +3575,7 @@ static int do_register_con_driver(const struct consw *csw, int first, int last)
struct module *owner = csw->owner;
struct con_driver *con_driver;
const char *desc;
int i, retval = 0;
int i, retval;
WARN_CONSOLE_UNLOCKED();
@ -3575,17 +3586,17 @@ static int do_register_con_driver(const struct consw *csw, int first, int last)
con_driver = &registered_con_driver[i];
/* already registered */
if (con_driver->con == csw)
if (con_driver->con == csw) {
retval = -EBUSY;
goto err;
}
}
if (retval)
goto err;
desc = csw->con_startup();
if (!desc)
if (!desc) {
retval = -ENODEV;
goto err;
}
retval = -EINVAL;

View File

@ -1680,7 +1680,7 @@ static int acm_resume(struct usb_interface *intf)
if (--acm->susp_count)
goto out;
if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
if (tty_port_initialized(&acm->port)) {
rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
for (;;) {
@ -1710,7 +1710,7 @@ static int acm_reset_resume(struct usb_interface *intf)
{
struct acm *acm = usb_get_intfdata(intf);
if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
if (tty_port_initialized(&acm->port))
tty_port_tty_hangup(&acm->port, false);
return acm_resume(intf);

View File

@ -512,7 +512,7 @@ static void gs_rx_push(unsigned long _port)
req = list_first_entry(queue, struct usb_request, list);
/* leave data queued if tty was rx throttled */
if (tty && test_bit(TTY_THROTTLED, &tty->flags))
if (tty && tty_throttled(tty))
break;
switch (req->status) {
@ -579,7 +579,7 @@ static void gs_rx_push(unsigned long _port)
* from starving ... but it's not clear that case ever happens.
*/
if (!list_empty(queue) && tty) {
if (!test_bit(TTY_THROTTLED, &tty->flags)) {
if (!tty_throttled(tty)) {
if (do_push)
tasklet_schedule(&port->push);
else

View File

@ -601,7 +601,7 @@ sisusbcon_save_screen(struct vc_data *c)
/* interface routine */
static int
sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
sisusbcon_set_palette(struct vc_data *c, const unsigned char *table)
{
struct sisusb_usb_data *sisusb;
int i, j;

View File

@ -127,7 +127,7 @@ static int usb_console_setup(struct console *co, char *options)
info->port = port;
++port->port.count;
if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
if (!tty_port_initialized(&port->port)) {
if (serial->type->set_termios) {
/*
* allocate a fake tty so the driver can initialize
@ -168,7 +168,7 @@ static int usb_console_setup(struct console *co, char *options)
tty_port_tty_set(&port->port, NULL);
tty_kref_put(tty);
}
set_bit(ASYNCB_INITIALIZED, &port->port.flags);
tty_port_set_initialized(&port->port, 1);
}
/* Now that any required fake tty operations are completed restore
* the tty port count */

View File

@ -699,8 +699,7 @@ static void digi_set_termios(struct tty_struct *tty,
/* don't set RTS if using hardware flow control */
/* and throttling input */
modem_signals = TIOCM_DTR;
if (!C_CRTSCTS(tty) ||
!test_bit(TTY_THROTTLED, &tty->flags))
if (!C_CRTSCTS(tty) || !tty_throttled(tty))
modem_signals |= TIOCM_RTS;
digi_set_modem_signals(port, modem_signals, 1);
}

View File

@ -473,7 +473,7 @@ static bool usb_serial_generic_msr_changed(struct tty_struct *tty,
* Use tty-port initialised flag to detect all hangups including the
* one generated at USB-device disconnect.
*/
if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
if (!tty_port_initialized(&port->port))
return true;
spin_lock_irqsave(&port->lock, flags);
@ -503,7 +503,7 @@ int usb_serial_generic_tiocmiwait(struct tty_struct *tty, unsigned long arg)
ret = wait_event_interruptible(port->port.delta_msr_wait,
usb_serial_generic_msr_changed(tty, arg, &cnow));
if (!ret && !test_bit(ASYNCB_INITIALIZED, &port->port.flags))
if (!ret && !tty_port_initialized(&port->port))
ret = -EIO;
return ret;
@ -606,7 +606,7 @@ int usb_serial_generic_resume(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
if (!tty_port_initialized(&port->port))
continue;
if (port->bulk_in_size) {

View File

@ -503,7 +503,7 @@ static void mxuport_process_read_urb_demux_data(struct urb *urb)
return;
}
if (test_bit(ASYNCB_INITIALIZED, &demux_port->port.flags)) {
if (tty_port_initialized(&demux_port->port)) {
ch = data + HEADER_SIZE;
mxuport_process_read_urb_data(demux_port, ch, rcv_len);
} else {
@ -544,7 +544,7 @@ static void mxuport_process_read_urb_demux_event(struct urb *urb)
}
demux_port = serial->port[rcv_port];
if (test_bit(ASYNCB_INITIALIZED, &demux_port->port.flags)) {
if (tty_port_initialized(&demux_port->port)) {
ch = data + HEADER_SIZE;
rcv_event = get_unaligned_be16(data + 2);
mxuport_process_read_urb_event(demux_port, ch,
@ -1339,7 +1339,7 @@ static int mxuport_resume(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
if (!tty_port_initialized(&port->port))
continue;
r = usb_serial_generic_write_start(port, GFP_NOIO);

View File

@ -776,7 +776,7 @@ static void sierra_close(struct usb_serial_port *port)
/*
* Need to take susp_lock to make sure port is not already being
* resumed, but no need to hold it due to ASYNC_INITIALIZED.
* resumed, but no need to hold it due to initialized
*/
spin_lock_irq(&intfdata->susp_lock);
if (--intfdata->open_ports == 0)
@ -1039,7 +1039,7 @@ static int sierra_resume(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
if (!tty_port_initialized(&port->port))
continue;
err = sierra_submit_delayed_urbs(port);

View File

@ -254,7 +254,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp)
*
* Shut down a USB serial port. Serialized against activate by the
* tport mutex and kept to matching open/close pairs
* of calls by the ASYNCB_INITIALIZED flag.
* of calls by the initialized flag.
*
* Not called if tty is console.
*/

View File

@ -464,7 +464,7 @@ void usb_wwan_close(struct usb_serial_port *port)
/*
* Need to take susp_lock to make sure port is not already being
* resumed, but no need to hold it due to ASYNC_INITIALIZED.
* resumed, but no need to hold it due to initialized
*/
spin_lock_irq(&intfdata->susp_lock);
if (--intfdata->open_ports == 0)
@ -682,7 +682,7 @@ int usb_wwan_resume(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))
if (!tty_port_initialized(&port->port))
continue;
portdata = usb_get_serial_port_data(port);

View File

@ -170,7 +170,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
int height, int width);
static int fbcon_switch(struct vc_data *vc);
static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
static int fbcon_set_palette(struct vc_data *vc, unsigned char *table);
static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table);
static int fbcon_scrolldelta(struct vc_data *vc, int lines);
/*
@ -2652,7 +2652,7 @@ static struct fb_cmap palette_cmap = {
0, 16, palette_red, palette_green, palette_blue, NULL
};
static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
static int fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
int i, j, k, depth;

View File

@ -481,7 +481,7 @@ static int mdacon_switch(struct vc_data *c)
return 1; /* redrawing needed */
}
static int mdacon_set_palette(struct vc_data *c, unsigned char *table)
static int mdacon_set_palette(struct vc_data *c, const unsigned char *table)
{
return -EINVAL;
}

View File

@ -574,7 +574,7 @@ static int newport_font_set(struct vc_data *vc, struct console_font *font, unsig
return newport_set_font(vc->vc_num, font);
}
static int newport_set_palette(struct vc_data *vc, unsigned char *table)
static int newport_set_palette(struct vc_data *vc, const unsigned char *table)
{
return -EINVAL;
}

View File

@ -79,7 +79,7 @@ static const char *sticon_startup(void)
return "STI console";
}
static int sticon_set_palette(struct vc_data *c, unsigned char *table)
static int sticon_set_palette(struct vc_data *c, const unsigned char *table)
{
return -EINVAL;
}

View File

@ -80,7 +80,6 @@ static void vgacon_deinit(struct vc_data *c);
static void vgacon_cursor(struct vc_data *c, int mode);
static int vgacon_switch(struct vc_data *c);
static int vgacon_blank(struct vc_data *c, int blank, int mode_switch);
static int vgacon_set_palette(struct vc_data *vc, unsigned char *table);
static int vgacon_scrolldelta(struct vc_data *c, int lines);
static int vgacon_set_origin(struct vc_data *c);
static void vgacon_save_screen(struct vc_data *c);
@ -847,7 +846,7 @@ static int vgacon_switch(struct vc_data *c)
return 0; /* Redrawing not needed */
}
static void vga_set_palette(struct vc_data *vc, unsigned char *table)
static void vga_set_palette(struct vc_data *vc, const unsigned char *table)
{
int i, j;
@ -860,7 +859,7 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table)
}
}
static int vgacon_set_palette(struct vc_data *vc, unsigned char *table)
static int vgacon_set_palette(struct vc_data *vc, const unsigned char *table)
{
#ifdef CAN_LOAD_PALETTE
if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked

View File

@ -47,7 +47,7 @@ struct consw {
int (*con_font_copy)(struct vc_data *, int);
int (*con_resize)(struct vc_data *, unsigned int, unsigned int,
unsigned int);
int (*con_set_palette)(struct vc_data *, unsigned char *);
int (*con_set_palette)(struct vc_data *, const unsigned char *);
int (*con_scrolldelta)(struct vc_data *, int);
int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *);

View File

@ -24,10 +24,10 @@ extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
extern int console_blanked;
extern unsigned char color_table[];
extern int default_red[];
extern int default_grn[];
extern int default_blu[];
extern const unsigned char color_table[];
extern unsigned char default_red[];
extern unsigned char default_grn[];
extern unsigned char default_blu[];
extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed);
extern u16 screen_glyph(struct vc_data *vc, int offset);

View File

@ -36,6 +36,7 @@ struct plat_serial8250_port {
void (*set_termios)(struct uart_port *,
struct ktermios *new,
struct ktermios *old);
unsigned int (*get_mctrl)(struct uart_port *);
int (*handle_irq)(struct uart_port *);
void (*pm)(struct uart_port *, unsigned int state,
unsigned old);
@ -148,6 +149,7 @@ extern int early_serial8250_setup(struct earlycon_device *device,
const char *options);
extern void serial8250_do_set_termios(struct uart_port *port,
struct ktermios *termios, struct ktermios *old);
extern unsigned int serial8250_do_get_mctrl(struct uart_port *port);
extern int serial8250_do_startup(struct uart_port *port);
extern void serial8250_do_shutdown(struct uart_port *port);
extern void serial8250_do_pm(struct uart_port *port, unsigned int state,

View File

@ -123,6 +123,7 @@ struct uart_port {
void (*set_termios)(struct uart_port *,
struct ktermios *new,
struct ktermios *old);
unsigned int (*get_mctrl)(struct uart_port *);
void (*set_mctrl)(struct uart_port *, unsigned int);
int (*startup)(struct uart_port *port);
void (*shutdown)(struct uart_port *port);
@ -281,6 +282,8 @@ struct uart_state {
enum uart_pm_state pm_state;
struct circ_buf xmit;
atomic_t refcount;
wait_queue_head_t remove_wait;
struct uart_port *uart_port;
};

View File

@ -228,7 +228,8 @@ struct tty_port {
int count; /* Usage count */
wait_queue_head_t open_wait; /* Open waiters */
wait_queue_head_t delta_msr_wait; /* Modem status change */
unsigned long flags; /* TTY flags ASY_*/
unsigned long flags; /* User TTY flags ASYNC_ */
unsigned long iflags; /* Internal flags TTY_PORT_ */
unsigned char console:1, /* port is a console */
low_latency:1; /* optional: tune for latency */
struct mutex mutex; /* Locking */
@ -242,6 +243,18 @@ struct tty_port {
struct kref kref; /* Ref counter */
};
/* tty_port::iflags bits -- use atomic bit ops */
#define TTY_PORT_INITIALIZED 0 /* device is initialized */
#define TTY_PORT_SUSPENDED 1 /* device is suspended */
#define TTY_PORT_ACTIVE 2 /* device is open */
/*
* uart drivers: use the uart_port::status field and the UPSTAT_* defines
* for s/w-based flow control steering and carrier detection status
*/
#define TTY_PORT_CTS_FLOW 3 /* h/w flow control enabled */
#define TTY_PORT_CHECK_CD 4 /* carrier detect enabled */
/*
* Where all of the state associated with a tty is kept while the tty
* is open. Since the termios state should be kept even if the tty
@ -338,7 +351,6 @@ struct tty_file_private {
#define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */
#define TTY_EXCLUSIVE 3 /* Exclusive open mode */
#define TTY_DO_WRITE_WAKEUP 5 /* Call write_wakeup after queuing new */
#define TTY_OTHER_DONE 6 /* Closed pty has completed input processing */
#define TTY_LDISC_OPEN 11 /* Line discipline is open */
#define TTY_PTY_LOCK 16 /* pty private */
#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
@ -360,6 +372,16 @@ static inline void tty_set_flow_change(struct tty_struct *tty, int val)
smp_mb();
}
static inline bool tty_io_error(struct tty_struct *tty)
{
return test_bit(TTY_IO_ERROR, &tty->flags);
}
static inline bool tty_throttled(struct tty_struct *tty)
{
return test_bit(TTY_THROTTLED, &tty->flags);
}
#ifdef CONFIG_TTY
extern void console_init(void);
extern void tty_kref_put(struct tty_struct *tty);
@ -459,6 +481,7 @@ extern void tty_buffer_init(struct tty_port *port);
extern void tty_buffer_set_lock_subclass(struct tty_port *port);
extern bool tty_buffer_restart_work(struct tty_port *port);
extern bool tty_buffer_cancel_work(struct tty_port *port);
extern void tty_buffer_flush_work(struct tty_port *port);
extern speed_t tty_termios_baud_rate(struct ktermios *termios);
extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
extern void tty_termios_encode_baud_rate(struct ktermios *termios,
@ -539,7 +562,67 @@ static inline struct tty_port *tty_port_get(struct tty_port *port)
/* If the cts flow control is enabled, return true. */
static inline bool tty_port_cts_enabled(struct tty_port *port)
{
return port->flags & ASYNC_CTS_FLOW;
return test_bit(TTY_PORT_CTS_FLOW, &port->iflags);
}
static inline void tty_port_set_cts_flow(struct tty_port *port, bool val)
{
if (val)
set_bit(TTY_PORT_CTS_FLOW, &port->iflags);
else
clear_bit(TTY_PORT_CTS_FLOW, &port->iflags);
}
static inline bool tty_port_active(struct tty_port *port)
{
return test_bit(TTY_PORT_ACTIVE, &port->iflags);
}
static inline void tty_port_set_active(struct tty_port *port, bool val)
{
if (val)
set_bit(TTY_PORT_ACTIVE, &port->iflags);
else
clear_bit(TTY_PORT_ACTIVE, &port->iflags);
}
static inline bool tty_port_check_carrier(struct tty_port *port)
{
return test_bit(TTY_PORT_CHECK_CD, &port->iflags);
}
static inline void tty_port_set_check_carrier(struct tty_port *port, bool val)
{
if (val)
set_bit(TTY_PORT_CHECK_CD, &port->iflags);
else
clear_bit(TTY_PORT_CHECK_CD, &port->iflags);
}
static inline bool tty_port_suspended(struct tty_port *port)
{
return test_bit(TTY_PORT_SUSPENDED, &port->iflags);
}
static inline void tty_port_set_suspended(struct tty_port *port, bool val)
{
if (val)
set_bit(TTY_PORT_SUSPENDED, &port->iflags);
else
clear_bit(TTY_PORT_SUSPENDED, &port->iflags);
}
static inline bool tty_port_initialized(struct tty_port *port)
{
return test_bit(TTY_PORT_INITIALIZED, &port->iflags);
}
static inline void tty_port_set_initialized(struct tty_port *port, bool val)
{
if (val)
set_bit(TTY_PORT_INITIALIZED, &port->iflags);
else
clear_bit(TTY_PORT_INITIALIZED, &port->iflags);
}
extern struct tty_struct *tty_port_tty_get(struct tty_port *port);

View File

@ -267,4 +267,7 @@
/* Microchip PIC32 UART */
#define PORT_PIC32 115
/* MPS2 UART */
#define PORT_MPS2UART 116
#endif /* _UAPILINUX_SERIAL_CORE_H */

View File

@ -32,7 +32,13 @@
#define ASYNCB_MAGIC_MULTIPLIER 16 /* Use special CLK or divisor */
#define ASYNCB_LAST_USER 16
/* Internal flags used only by kernel */
/*
* Internal flags used only by kernel (read-only)
*
* WARNING: These flags are no longer used and have been superceded by the
* TTY_PORT_ flags in the iflags field (and not userspace-visible)
*/
#ifndef _KERNEL_
#define ASYNCB_INITIALIZED 31 /* Serial port was initialized */
#define ASYNCB_SUSPENDED 30 /* Serial port is suspended */
#define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */
@ -43,7 +49,9 @@
#define ASYNCB_SHARE_IRQ 24 /* for multifunction cards, no longer used */
#define ASYNCB_CONS_FLOW 23 /* flow control for console */
#define ASYNCB_FIRST_KERNEL 22
#endif
/* Masks */
#define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY)
#define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED)
#define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
@ -72,6 +80,8 @@
#define ASYNC_SPD_WARP (ASYNC_SPD_HI|ASYNC_SPD_SHI)
#define ASYNC_SPD_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI)
#ifndef _KERNEL_
/* These flags are no longer used (and were always masked from userspace) */
#define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED)
#define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE)
#define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF)
@ -81,5 +91,6 @@
#define ASYNC_SHARE_IRQ (1U << ASYNCB_SHARE_IRQ)
#define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW)
#define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1))
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More