mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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:
commit
e10abc629f
19
Documentation/devicetree/bindings/serial/arm,mps2-uart.txt
Normal file
19
Documentation/devicetree/bindings/serial/arm,mps2-uart.txt
Normal 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>;
|
||||
};
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
57
Documentation/devicetree/bindings/serial/serial.txt
Normal file
57
Documentation/devicetree/bindings/serial/serial.txt
Normal 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";
|
||||
};
|
@ -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>;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 .. */
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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)))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) &&
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
625
drivers/tty/serial/mps2-uart.c
Normal file
625
drivers/tty/serial/mps2-uart.c
Normal 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);
|
@ -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);
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
*
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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, ¶m);
|
||||
|
||||
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
|
||||
vcs_make_sysfs(currcons);
|
||||
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m);
|
||||
}
|
||||
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 = ®istered_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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -267,4 +267,7 @@
|
||||
/* Microchip PIC32 UART */
|
||||
#define PORT_PIC32 115
|
||||
|
||||
/* MPS2 UART */
|
||||
#define PORT_MPS2UART 116
|
||||
|
||||
#endif /* _UAPILINUX_SERIAL_CORE_H */
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user