diff options
Diffstat (limited to 'drivers/tty')
25 files changed, 600 insertions, 476 deletions
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index bf17e90858b8..e37683e25055 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -45,7 +45,307 @@ #include <asm/io.h> #include <linux/uaccess.h> -#include "moxa.h" +#define MOXA 0x400 +#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ +#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ +#define MOXA_GETDATACOUNT (MOXA + 23) +#define MOXA_GET_IOQUEUE (MOXA + 27) +#define MOXA_FLUSH_QUEUE (MOXA + 28) +#define MOXA_GETMSTATUS (MOXA + 65) + +/* + * System Configuration + */ + +#define Magic_code 0x404 + +/* + * for C218 BIOS initialization + */ +#define C218_ConfBase 0x800 +#define C218_status (C218_ConfBase + 0) /* BIOS running status */ +#define C218_diag (C218_ConfBase + 2) /* diagnostic status */ +#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ +#define C218DLoad_len (C218_ConfBase + 6) /* WORD */ +#define C218check_sum (C218_ConfBase + 8) /* BYTE */ +#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ +#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ +#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ +#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ +#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ + +#define C218_LoadBuf 0x0F00 +#define C218_KeyCode 0x218 +#define CP204J_KeyCode 0x204 + +/* + * for C320 BIOS initialization + */ +#define C320_ConfBase 0x800 +#define C320_LoadBuf 0x0f00 +#define STS_init 0x05 /* for C320_status */ + +#define C320_status C320_ConfBase + 0 /* BIOS running status */ +#define C320_diag C320_ConfBase + 2 /* diagnostic status */ +#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ +#define C320DLoad_len C320_ConfBase + 6 /* WORD */ +#define C320check_sum C320_ConfBase + 8 /* WORD */ +#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ +#define C320bapi_len C320_ConfBase + 0x0c /* WORD */ +#define C320UART_no C320_ConfBase + 0x0e /* WORD */ + +#define C320_KeyCode 0x320 + +#define FixPage_addr 0x0000 /* starting addr of static page */ +#define DynPage_addr 0x2000 /* starting addr of dynamic page */ +#define C218_start 0x3000 /* starting addr of C218 BIOS prg */ +#define Control_reg 0x1ff0 /* select page and reset control */ +#define HW_reset 0x80 + +/* + * Function Codes + */ +#define FC_CardReset 0x80 +#define FC_ChannelReset 1 /* C320 firmware not supported */ +#define FC_EnableCH 2 +#define FC_DisableCH 3 +#define FC_SetParam 4 +#define FC_SetMode 5 +#define FC_SetRate 6 +#define FC_LineControl 7 +#define FC_LineStatus 8 +#define FC_XmitControl 9 +#define FC_FlushQueue 10 +#define FC_SendBreak 11 +#define FC_StopBreak 12 +#define FC_LoopbackON 13 +#define FC_LoopbackOFF 14 +#define FC_ClrIrqTable 15 +#define FC_SendXon 16 +#define FC_SetTermIrq 17 /* C320 firmware not supported */ +#define FC_SetCntIrq 18 /* C320 firmware not supported */ +#define FC_SetBreakIrq 19 +#define FC_SetLineIrq 20 +#define FC_SetFlowCtl 21 +#define FC_GenIrq 22 +#define FC_InCD180 23 +#define FC_OutCD180 24 +#define FC_InUARTreg 23 +#define FC_OutUARTreg 24 +#define FC_SetXonXoff 25 +#define FC_OutCD180CCR 26 +#define FC_ExtIQueue 27 +#define FC_ExtOQueue 28 +#define FC_ClrLineIrq 29 +#define FC_HWFlowCtl 30 +#define FC_GetClockRate 35 +#define FC_SetBaud 36 +#define FC_SetDataMode 41 +#define FC_GetCCSR 43 +#define FC_GetDataError 45 +#define FC_RxControl 50 +#define FC_ImmSend 51 +#define FC_SetXonState 52 +#define FC_SetXoffState 53 +#define FC_SetRxFIFOTrig 54 +#define FC_SetTxFIFOCnt 55 +#define FC_UnixRate 56 +#define FC_UnixResetTimer 57 + +#define RxFIFOTrig1 0 +#define RxFIFOTrig4 1 +#define RxFIFOTrig8 2 +#define RxFIFOTrig14 3 + +/* + * Dual-Ported RAM + */ +#define DRAM_global 0 +#define INT_data (DRAM_global + 0) +#define Config_base (DRAM_global + 0x108) + +#define IRQindex (INT_data + 0) +#define IRQpending (INT_data + 4) +#define IRQtable (INT_data + 8) + +/* + * Interrupt Status + */ +#define IntrRx 0x01 /* receiver data O.K. */ +#define IntrTx 0x02 /* transmit buffer empty */ +#define IntrFunc 0x04 /* function complete */ +#define IntrBreak 0x08 /* received break */ +#define IntrLine 0x10 /* line status change + for transmitter */ +#define IntrIntr 0x20 /* received INTR code */ +#define IntrQuit 0x40 /* received QUIT code */ +#define IntrEOF 0x80 /* received EOF code */ + +#define IntrRxTrigger 0x100 /* rx data count reach trigger value */ +#define IntrTxTrigger 0x200 /* tx data count below trigger value */ + +#define Magic_no (Config_base + 0) +#define Card_model_no (Config_base + 2) +#define Total_ports (Config_base + 4) +#define Module_cnt (Config_base + 8) +#define Module_no (Config_base + 10) +#define Timer_10ms (Config_base + 14) +#define Disable_IRQ (Config_base + 20) +#define TMS320_PORT1 (Config_base + 22) +#define TMS320_PORT2 (Config_base + 24) +#define TMS320_CLOCK (Config_base + 26) + +/* + * DATA BUFFER in DRAM + */ +#define Extern_table 0x400 /* Base address of the external table + (24 words * 64) total 3K bytes + (24 words * 128) total 6K bytes */ +#define Extern_size 0x60 /* 96 bytes */ +#define RXrptr 0x00 /* read pointer for RX buffer */ +#define RXwptr 0x02 /* write pointer for RX buffer */ +#define TXrptr 0x04 /* read pointer for TX buffer */ +#define TXwptr 0x06 /* write pointer for TX buffer */ +#define HostStat 0x08 /* IRQ flag and general flag */ +#define FlagStat 0x0A +#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ + /* x x x x | | | | */ + /* | | | + CTS flow */ + /* | | +--- RTS flow */ + /* | +------ TX Xon/Xoff */ + /* +--------- RX Xon/Xoff */ +#define Break_cnt 0x0E /* received break count */ +#define CD180TXirq 0x10 /* if non-0: enable TX irq */ +#define RX_mask 0x12 +#define TX_mask 0x14 +#define Ofs_rxb 0x16 +#define Ofs_txb 0x18 +#define Page_rxb 0x1A +#define Page_txb 0x1C +#define EndPage_rxb 0x1E +#define EndPage_txb 0x20 +#define Data_error 0x22 +#define RxTrigger 0x28 +#define TxTrigger 0x2a + +#define rRXwptr 0x34 +#define Low_water 0x36 + +#define FuncCode 0x40 +#define FuncArg 0x42 +#define FuncArg1 0x44 + +#define C218rx_size 0x2000 /* 8K bytes */ +#define C218tx_size 0x8000 /* 32K bytes */ + +#define C218rx_mask (C218rx_size - 1) +#define C218tx_mask (C218tx_size - 1) + +#define C320p8rx_size 0x2000 +#define C320p8tx_size 0x8000 +#define C320p8rx_mask (C320p8rx_size - 1) +#define C320p8tx_mask (C320p8tx_size - 1) + +#define C320p16rx_size 0x2000 +#define C320p16tx_size 0x4000 +#define C320p16rx_mask (C320p16rx_size - 1) +#define C320p16tx_mask (C320p16tx_size - 1) + +#define C320p24rx_size 0x2000 +#define C320p24tx_size 0x2000 +#define C320p24rx_mask (C320p24rx_size - 1) +#define C320p24tx_mask (C320p24tx_size - 1) + +#define C320p32rx_size 0x1000 +#define C320p32tx_size 0x1000 +#define C320p32rx_mask (C320p32rx_size - 1) +#define C320p32tx_mask (C320p32tx_size - 1) + +#define Page_size 0x2000U +#define Page_mask (Page_size - 1) +#define C218rx_spage 3 +#define C218tx_spage 4 +#define C218rx_pageno 1 +#define C218tx_pageno 4 +#define C218buf_pageno 5 + +#define C320p8rx_spage 3 +#define C320p8tx_spage 4 +#define C320p8rx_pgno 1 +#define C320p8tx_pgno 4 +#define C320p8buf_pgno 5 + +#define C320p16rx_spage 3 +#define C320p16tx_spage 4 +#define C320p16rx_pgno 1 +#define C320p16tx_pgno 2 +#define C320p16buf_pgno 3 + +#define C320p24rx_spage 3 +#define C320p24tx_spage 4 +#define C320p24rx_pgno 1 +#define C320p24tx_pgno 1 +#define C320p24buf_pgno 2 + +#define C320p32rx_spage 3 +#define C320p32tx_ofs C320p32rx_size +#define C320p32tx_spage 3 +#define C320p32buf_pgno 1 + +/* + * Host Status + */ +#define WakeupRx 0x01 +#define WakeupTx 0x02 +#define WakeupBreak 0x08 +#define WakeupLine 0x10 +#define WakeupIntr 0x20 +#define WakeupQuit 0x40 +#define WakeupEOF 0x80 /* used in VTIME control */ +#define WakeupRxTrigger 0x100 +#define WakeupTxTrigger 0x200 +/* + * Flag status + */ +#define Rx_over 0x01 +#define Xoff_state 0x02 +#define Tx_flowOff 0x04 +#define Tx_enable 0x08 +#define CTS_state 0x10 +#define DSR_state 0x20 +#define DCD_state 0x80 +/* + * FlowControl + */ +#define CTS_FlowCtl 1 +#define RTS_FlowCtl 2 +#define Tx_FlowCtl 4 +#define Rx_FlowCtl 8 +#define IXM_IXANY 0x10 + +#define LowWater 128 + +#define DTR_ON 1 +#define RTS_ON 2 +#define CTS_ON 1 +#define DSR_ON 2 +#define DCD_ON 8 + +/* mode definition */ +#define MX_CS8 0x03 +#define MX_CS7 0x02 +#define MX_CS6 0x01 +#define MX_CS5 0x00 + +#define MX_STOP1 0x00 +#define MX_STOP15 0x04 +#define MX_STOP2 0x08 + +#define MX_PARNONE 0x00 +#define MX_PAREVEN 0x40 +#define MX_PARODD 0xC0 +#define MX_PARMARK 0xA0 +#define MX_PARSPACE 0x20 #define MOXA_VERSION "6.0k" diff --git a/drivers/tty/moxa.h b/drivers/tty/moxa.h deleted file mode 100644 index f0a4381b6861..000000000000 --- a/drivers/tty/moxa.h +++ /dev/null @@ -1,307 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef MOXA_H_FILE -#define MOXA_H_FILE - -#define MOXA 0x400 -#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ -#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ -#define MOXA_GETDATACOUNT (MOXA + 23) -#define MOXA_GET_IOQUEUE (MOXA + 27) -#define MOXA_FLUSH_QUEUE (MOXA + 28) -#define MOXA_GETMSTATUS (MOXA + 65) - -/* - * System Configuration - */ - -#define Magic_code 0x404 - -/* - * for C218 BIOS initialization - */ -#define C218_ConfBase 0x800 -#define C218_status (C218_ConfBase + 0) /* BIOS running status */ -#define C218_diag (C218_ConfBase + 2) /* diagnostic status */ -#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ -#define C218DLoad_len (C218_ConfBase + 6) /* WORD */ -#define C218check_sum (C218_ConfBase + 8) /* BYTE */ -#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ -#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ -#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ -#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ -#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ - -#define C218_LoadBuf 0x0F00 -#define C218_KeyCode 0x218 -#define CP204J_KeyCode 0x204 - -/* - * for C320 BIOS initialization - */ -#define C320_ConfBase 0x800 -#define C320_LoadBuf 0x0f00 -#define STS_init 0x05 /* for C320_status */ - -#define C320_status C320_ConfBase + 0 /* BIOS running status */ -#define C320_diag C320_ConfBase + 2 /* diagnostic status */ -#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ -#define C320DLoad_len C320_ConfBase + 6 /* WORD */ -#define C320check_sum C320_ConfBase + 8 /* WORD */ -#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ -#define C320bapi_len C320_ConfBase + 0x0c /* WORD */ -#define C320UART_no C320_ConfBase + 0x0e /* WORD */ - -#define C320_KeyCode 0x320 - -#define FixPage_addr 0x0000 /* starting addr of static page */ -#define DynPage_addr 0x2000 /* starting addr of dynamic page */ -#define C218_start 0x3000 /* starting addr of C218 BIOS prg */ -#define Control_reg 0x1ff0 /* select page and reset control */ -#define HW_reset 0x80 - -/* - * Function Codes - */ -#define FC_CardReset 0x80 -#define FC_ChannelReset 1 /* C320 firmware not supported */ -#define FC_EnableCH 2 -#define FC_DisableCH 3 -#define FC_SetParam 4 -#define FC_SetMode 5 -#define FC_SetRate 6 -#define FC_LineControl 7 -#define FC_LineStatus 8 -#define FC_XmitControl 9 -#define FC_FlushQueue 10 -#define FC_SendBreak 11 -#define FC_StopBreak 12 -#define FC_LoopbackON 13 -#define FC_LoopbackOFF 14 -#define FC_ClrIrqTable 15 -#define FC_SendXon 16 -#define FC_SetTermIrq 17 /* C320 firmware not supported */ -#define FC_SetCntIrq 18 /* C320 firmware not supported */ -#define FC_SetBreakIrq 19 -#define FC_SetLineIrq 20 -#define FC_SetFlowCtl 21 -#define FC_GenIrq 22 -#define FC_InCD180 23 -#define FC_OutCD180 24 -#define FC_InUARTreg 23 -#define FC_OutUARTreg 24 -#define FC_SetXonXoff 25 -#define FC_OutCD180CCR 26 -#define FC_ExtIQueue 27 -#define FC_ExtOQueue 28 -#define FC_ClrLineIrq 29 -#define FC_HWFlowCtl 30 -#define FC_GetClockRate 35 -#define FC_SetBaud 36 -#define FC_SetDataMode 41 -#define FC_GetCCSR 43 -#define FC_GetDataError 45 -#define FC_RxControl 50 -#define FC_ImmSend 51 -#define FC_SetXonState 52 -#define FC_SetXoffState 53 -#define FC_SetRxFIFOTrig 54 -#define FC_SetTxFIFOCnt 55 -#define FC_UnixRate 56 -#define FC_UnixResetTimer 57 - -#define RxFIFOTrig1 0 -#define RxFIFOTrig4 1 -#define RxFIFOTrig8 2 -#define RxFIFOTrig14 3 - -/* - * Dual-Ported RAM - */ -#define DRAM_global 0 -#define INT_data (DRAM_global + 0) -#define Config_base (DRAM_global + 0x108) - -#define IRQindex (INT_data + 0) -#define IRQpending (INT_data + 4) -#define IRQtable (INT_data + 8) - -/* - * Interrupt Status - */ -#define IntrRx 0x01 /* receiver data O.K. */ -#define IntrTx 0x02 /* transmit buffer empty */ -#define IntrFunc 0x04 /* function complete */ -#define IntrBreak 0x08 /* received break */ -#define IntrLine 0x10 /* line status change - for transmitter */ -#define IntrIntr 0x20 /* received INTR code */ -#define IntrQuit 0x40 /* received QUIT code */ -#define IntrEOF 0x80 /* received EOF code */ - -#define IntrRxTrigger 0x100 /* rx data count reach trigger value */ -#define IntrTxTrigger 0x200 /* tx data count below trigger value */ - -#define Magic_no (Config_base + 0) -#define Card_model_no (Config_base + 2) -#define Total_ports (Config_base + 4) -#define Module_cnt (Config_base + 8) -#define Module_no (Config_base + 10) -#define Timer_10ms (Config_base + 14) -#define Disable_IRQ (Config_base + 20) -#define TMS320_PORT1 (Config_base + 22) -#define TMS320_PORT2 (Config_base + 24) -#define TMS320_CLOCK (Config_base + 26) - -/* - * DATA BUFFER in DRAM - */ -#define Extern_table 0x400 /* Base address of the external table - (24 words * 64) total 3K bytes - (24 words * 128) total 6K bytes */ -#define Extern_size 0x60 /* 96 bytes */ -#define RXrptr 0x00 /* read pointer for RX buffer */ -#define RXwptr 0x02 /* write pointer for RX buffer */ -#define TXrptr 0x04 /* read pointer for TX buffer */ -#define TXwptr 0x06 /* write pointer for TX buffer */ -#define HostStat 0x08 /* IRQ flag and general flag */ -#define FlagStat 0x0A -#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ - /* x x x x | | | | */ - /* | | | + CTS flow */ - /* | | +--- RTS flow */ - /* | +------ TX Xon/Xoff */ - /* +--------- RX Xon/Xoff */ -#define Break_cnt 0x0E /* received break count */ -#define CD180TXirq 0x10 /* if non-0: enable TX irq */ -#define RX_mask 0x12 -#define TX_mask 0x14 -#define Ofs_rxb 0x16 -#define Ofs_txb 0x18 -#define Page_rxb 0x1A -#define Page_txb 0x1C -#define EndPage_rxb 0x1E -#define EndPage_txb 0x20 -#define Data_error 0x22 -#define RxTrigger 0x28 -#define TxTrigger 0x2a - -#define rRXwptr 0x34 -#define Low_water 0x36 - -#define FuncCode 0x40 -#define FuncArg 0x42 -#define FuncArg1 0x44 - -#define C218rx_size 0x2000 /* 8K bytes */ -#define C218tx_size 0x8000 /* 32K bytes */ - -#define C218rx_mask (C218rx_size - 1) -#define C218tx_mask (C218tx_size - 1) - -#define C320p8rx_size 0x2000 -#define C320p8tx_size 0x8000 -#define C320p8rx_mask (C320p8rx_size - 1) -#define C320p8tx_mask (C320p8tx_size - 1) - -#define C320p16rx_size 0x2000 -#define C320p16tx_size 0x4000 -#define C320p16rx_mask (C320p16rx_size - 1) -#define C320p16tx_mask (C320p16tx_size - 1) - -#define C320p24rx_size 0x2000 -#define C320p24tx_size 0x2000 -#define C320p24rx_mask (C320p24rx_size - 1) -#define C320p24tx_mask (C320p24tx_size - 1) - -#define C320p32rx_size 0x1000 -#define C320p32tx_size 0x1000 -#define C320p32rx_mask (C320p32rx_size - 1) -#define C320p32tx_mask (C320p32tx_size - 1) - -#define Page_size 0x2000U -#define Page_mask (Page_size - 1) -#define C218rx_spage 3 -#define C218tx_spage 4 -#define C218rx_pageno 1 -#define C218tx_pageno 4 -#define C218buf_pageno 5 - -#define C320p8rx_spage 3 -#define C320p8tx_spage 4 -#define C320p8rx_pgno 1 -#define C320p8tx_pgno 4 -#define C320p8buf_pgno 5 - -#define C320p16rx_spage 3 -#define C320p16tx_spage 4 -#define C320p16rx_pgno 1 -#define C320p16tx_pgno 2 -#define C320p16buf_pgno 3 - -#define C320p24rx_spage 3 -#define C320p24tx_spage 4 -#define C320p24rx_pgno 1 -#define C320p24tx_pgno 1 -#define C320p24buf_pgno 2 - -#define C320p32rx_spage 3 -#define C320p32tx_ofs C320p32rx_size -#define C320p32tx_spage 3 -#define C320p32buf_pgno 1 - -/* - * Host Status - */ -#define WakeupRx 0x01 -#define WakeupTx 0x02 -#define WakeupBreak 0x08 -#define WakeupLine 0x10 -#define WakeupIntr 0x20 -#define WakeupQuit 0x40 -#define WakeupEOF 0x80 /* used in VTIME control */ -#define WakeupRxTrigger 0x100 -#define WakeupTxTrigger 0x200 -/* - * Flag status - */ -#define Rx_over 0x01 -#define Xoff_state 0x02 -#define Tx_flowOff 0x04 -#define Tx_enable 0x08 -#define CTS_state 0x10 -#define DSR_state 0x20 -#define DCD_state 0x80 -/* - * FlowControl - */ -#define CTS_FlowCtl 1 -#define RTS_FlowCtl 2 -#define Tx_FlowCtl 4 -#define Rx_FlowCtl 8 -#define IXM_IXANY 0x10 - -#define LowWater 128 - -#define DTR_ON 1 -#define RTS_ON 2 -#define CTS_ON 1 -#define DSR_ON 2 -#define DCD_ON 8 - -/* mode definition */ -#define MX_CS8 0x03 -#define MX_CS7 0x02 -#define MX_CS6 0x01 -#define MX_CS5 0x00 - -#define MX_STOP1 0x00 -#define MX_STOP15 0x04 -#define MX_STOP2 0x08 - -#define MX_PARNONE 0x00 -#define MX_PAREVEN 0x40 -#define MX_PARODD 0xC0 -#define MX_PARMARK 0xA0 -#define MX_PARSPACE 0x20 - -#endif diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 1216f3985e18..93a95a135a71 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -249,8 +249,9 @@ struct mxser_port { unsigned char x_char; /* xon/xoff character */ u8 IER; /* Interrupt Enable Register */ u8 MCR; /* Modem control register */ + u8 FCR; /* FIFO control register */ - unsigned char ldisc_stop_rx; + bool ldisc_stop_rx; struct async_icount icount; /* kernel counters for 4 input interrupts */ unsigned int timeout; @@ -559,14 +560,20 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info, * This routine is called to set the UART divisor registers to match * the specified baud rate for a serial port. */ -static void mxser_change_speed(struct tty_struct *tty) +static void mxser_change_speed(struct tty_struct *tty, struct ktermios *old_termios) { struct mxser_port *info = tty->driver_data; - unsigned cflag, cval, fcr; + unsigned cflag, cval; cflag = tty->termios.c_cflag; - mxser_set_baud(tty, tty_get_baud_rate(tty)); + if (mxser_set_baud(tty, tty_get_baud_rate(tty))) { + /* Use previous rate on a failure */ + if (old_termios) { + speed_t baud = tty_termios_baud_rate(old_termios); + tty_encode_baud_rate(tty, baud, baud); + } + } /* byte size and parity */ switch (cflag & CSIZE) { @@ -594,33 +601,26 @@ static void mxser_change_speed(struct tty_struct *tty) if (cflag & CMSPAR) cval |= UART_LCR_SPAR; - if ((info->type == PORT_8250) || (info->type == PORT_16450)) { - if (info->board->must_hwid) { - fcr = UART_FCR_ENABLE_FIFO; - fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; - mxser_set_must_fifo_value(info); - } else - fcr = 0; - } else { - fcr = UART_FCR_ENABLE_FIFO; - if (info->board->must_hwid) { - fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; - mxser_set_must_fifo_value(info); - } else { - switch (info->rx_high_water) { - case 1: - fcr |= UART_FCR_TRIGGER_1; - break; - case 4: - fcr |= UART_FCR_TRIGGER_4; - break; - case 8: - fcr |= UART_FCR_TRIGGER_8; - break; - default: - fcr |= UART_FCR_TRIGGER_14; - break; - } + info->FCR = 0; + if (info->board->must_hwid) { + info->FCR |= UART_FCR_ENABLE_FIFO | + MOXA_MUST_FCR_GDA_MODE_ENABLE; + mxser_set_must_fifo_value(info); + } else if (info->type != PORT_8250 && info->type != PORT_16450) { + info->FCR |= UART_FCR_ENABLE_FIFO; + switch (info->rx_high_water) { + case 1: + info->FCR |= UART_FCR_TRIGGER_1; + break; + case 4: + info->FCR |= UART_FCR_TRIGGER_4; + break; + case 8: + info->FCR |= UART_FCR_TRIGGER_8; + break; + default: + info->FCR |= UART_FCR_TRIGGER_14; + break; } } @@ -680,7 +680,7 @@ static void mxser_change_speed(struct tty_struct *tty) } - outb(fcr, info->ioaddr + UART_FCR); /* set fcr */ + outb(info->FCR, info->ioaddr + UART_FCR); outb(cval, info->ioaddr + UART_LCR); } @@ -707,6 +707,16 @@ static void mxser_check_modem_status(struct tty_struct *tty, mxser_handle_cts(tty, port, status); } +static void mxser_disable_and_clear_FIFO(struct mxser_port *info) +{ + u8 fcr = UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT; + + if (info->board->must_hwid) + fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; + + outb(fcr, info->ioaddr + UART_FCR); +} + static int mxser_activate(struct tty_port *port, struct tty_struct *tty) { struct mxser_port *info = container_of(port, struct mxser_port, port); @@ -731,13 +741,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty) * Clear the FIFO buffers and disable them * (they will be reenabled in mxser_change_speed()) */ - if (info->board->must_hwid) - outb((UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT | - MOXA_MUST_FCR_GDA_MODE_ENABLE), info->ioaddr + UART_FCR); - else - outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), - info->ioaddr + UART_FCR); + mxser_disable_and_clear_FIFO(info); /* * At this point there's no way the LSR could still be 0xFF; @@ -791,7 +795,7 @@ static int mxser_activate(struct tty_port *port, struct tty_struct *tty) /* * and set the speed of the serial port */ - mxser_change_speed(tty); + mxser_change_speed(tty, NULL); spin_unlock_irqrestore(&info->slock, flags); return 0; @@ -825,13 +829,7 @@ static void mxser_shutdown_port(struct tty_port *port) outb(0x00, info->ioaddr + UART_IER); /* clear Rx/Tx FIFO's */ - if (info->board->must_hwid) - outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | - MOXA_MUST_FCR_GDA_MODE_ENABLE, - info->ioaddr + UART_FCR); - else - outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, - info->ioaddr + UART_FCR); + mxser_disable_and_clear_FIFO(info); /* read data port to reset things */ (void) inb(info->ioaddr + UART_RX); @@ -862,17 +860,14 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) static void mxser_flush_buffer(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; - char fcr; unsigned long flags; spin_lock_irqsave(&info->slock, flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - fcr = inb(info->ioaddr + UART_FCR); - outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), + outb(info->FCR | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, info->ioaddr + UART_FCR); - outb(fcr, info->ioaddr + UART_FCR); spin_unlock_irqrestore(&info->slock, flags); @@ -1119,7 +1114,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, if (tty_port_initialized(port)) { if (old_speed != (port->flags & ASYNC_SPD_MASK)) { spin_lock_irqsave(&info->slock, sl_flags); - mxser_change_speed(tty); + mxser_change_speed(tty, NULL); spin_unlock_irqrestore(&info->slock, sl_flags); } } else { @@ -1335,7 +1330,7 @@ static void mxser_stoprx(struct tty_struct *tty) { struct mxser_port *info = tty->driver_data; - info->ldisc_stop_rx = 1; + info->ldisc_stop_rx = true; if (I_IXOFF(tty)) { if (info->board->must_hwid) { info->IER &= ~MOXA_MUST_RECV_ISR; @@ -1368,7 +1363,7 @@ static void mxser_unthrottle(struct tty_struct *tty) struct mxser_port *info = tty->driver_data; /* startrx */ - info->ldisc_stop_rx = 0; + info->ldisc_stop_rx = false; if (I_IXOFF(tty)) { if (info->x_char) info->x_char = 0; @@ -1425,7 +1420,7 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi unsigned long flags; spin_lock_irqsave(&info->slock, flags); - mxser_change_speed(tty); + mxser_change_speed(tty, old_termios); spin_unlock_irqrestore(&info->slock, flags); if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) { @@ -1544,11 +1539,7 @@ static bool mxser_receive_chars_new(struct tty_struct *tty, if (hwid == MOXA_OTHER_UART) return false; - if (status & UART_LSR_BRK_ERROR_BITS) - return false; - if (hwid == MOXA_MUST_MU860_HWID && (status & MOXA_MUST_LSR_RERR)) - return false; - if (status & MOXA_MUST_LSR_RERR) + if (status & (UART_LSR_BRK_ERROR_BITS | MOXA_MUST_LSR_RERR)) return false; gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); @@ -1582,8 +1573,7 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty, ch = inb(port->ioaddr + UART_RX); if (hwid && (status & UART_LSR_OE)) - outb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | - MOXA_MUST_FCR_GDA_MODE_ENABLE, + outb(port->FCR | UART_FCR_CLEAR_RCVR, port->ioaddr + UART_FCR); status &= port->read_status_mask; if (status & port->ignore_status_mask) { @@ -1695,8 +1685,7 @@ static bool mxser_port_isr(struct mxser_port *port) tty = tty_port_tty_get(&port->port); if (!tty || port->closing || !tty_port_initialized(&port->port)) { status = inb(port->ioaddr + UART_LSR); - outb(MOXA_MUST_FCR_GDA_MODE_ENABLE | UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, + outb(port->FCR | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, port->ioaddr + UART_FCR); inb(port->ioaddr + UART_MSR); @@ -1847,7 +1836,7 @@ static void mxser_initbrd(struct mxser_board *brd, bool high_baud) tty_port_init(&info->port); info->port.ops = &mxser_port_ops; info->board = brd; - info->ldisc_stop_rx = 0; + info->ldisc_stop_rx = false; /* Enhance mode enabled here */ if (brd->must_hwid != MOXA_OTHER_UART) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1d92d2a84889..0b96b14bbfe1 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -271,6 +271,10 @@ static DEFINE_SPINLOCK(gsm_mux_lock); static struct tty_driver *gsm_tty_driver; +/* Save dlci open address */ +static int addr_open[256] = { 0 }; +/* Save dlci open count */ +static int addr_cnt; /* * This section of the driver logic implements the GSM encodings * both the basic and the 'advanced'. Reliable transport is not @@ -587,6 +591,10 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control) return; } gsmld_output(gsm, cbuf, len); + if (!gsm->initiator) { + cr = cr & gsm->initiator; + control = control & ~PF; + } gsm_print_packet("-->", addr, cr, control, NULL, 0); } @@ -601,7 +609,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control) static inline void gsm_response(struct gsm_mux *gsm, int addr, int control) { - gsm_send(gsm, addr, 0, control); + gsm_send(gsm, addr, 1, control); } /** @@ -687,7 +695,7 @@ static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci) print_hex_dump_bytes("gsm_data_kick: ", DUMP_PREFIX_OFFSET, gsm->txframe, len); - if (gsmld_output(gsm, gsm->txframe, len) < 0) + if (gsmld_output(gsm, gsm->txframe, len) <= 0) break; /* FIXME: Can eliminate one SOF in many more cases */ gsm->tx_bytes -= msg->len; @@ -1177,6 +1185,7 @@ static void gsm_control_rls(struct gsm_mux *gsm, const u8 *data, int clen) } static void gsm_dlci_begin_close(struct gsm_dlci *dlci); +static void gsm_dlci_close(struct gsm_dlci *dlci); /** * gsm_control_message - DLCI 0 control processing @@ -1195,15 +1204,28 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, { u8 buf[1]; unsigned long flags; + struct gsm_dlci *dlci; + int i; + int address; switch (command) { case CMD_CLD: { - struct gsm_dlci *dlci = gsm->dlci[0]; + if (addr_cnt > 0) { + for (i = 0; i < addr_cnt; i++) { + address = addr_open[i]; + dlci = gsm->dlci[address]; + gsm_dlci_close(dlci); + addr_open[i] = 0; + } + } /* Modem wishes to close down */ + dlci = gsm->dlci[0]; if (dlci) { dlci->dead = true; gsm->dead = true; - gsm_dlci_begin_close(dlci); + gsm_dlci_close(dlci); + addr_cnt = 0; + gsm_response(gsm, 0, UA|PF); } } break; @@ -1429,6 +1451,8 @@ static void gsm_dlci_close(struct gsm_dlci *dlci) kfifo_reset(&dlci->fifo); } else dlci->gsm->dead = true; + /* Unregister gsmtty driver,report gsmtty dev remove uevent for user */ + tty_unregister_device(gsm_tty_driver, dlci->addr); wake_up(&dlci->gsm->event); /* A DLCI 0 close is a MUX termination so we need to kick that back to userspace somehow */ @@ -1450,6 +1474,8 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) dlci->state = DLCI_OPEN; if (debug & 8) pr_debug("DLCI %d goes open.\n", dlci->addr); + /* Register gsmtty driver,report gsmtty dev add uevent for user */ + tty_register_device(gsm_tty_driver, dlci->addr, NULL); wake_up(&dlci->gsm->event); } @@ -1748,6 +1774,7 @@ static void gsm_queue(struct gsm_mux *gsm) struct gsm_dlci *dlci; u8 cr; int address; + int i, j, k, address_tmp; /* We have to sneak a look at the packet body to do the FCS. A somewhat layering violation in the spec */ @@ -1779,29 +1806,59 @@ static void gsm_queue(struct gsm_mux *gsm) switch (gsm->control) { case SABM|PF: - if (cr == 0) + if (cr == 1) goto invalid; if (dlci == NULL) dlci = gsm_dlci_alloc(gsm, address); if (dlci == NULL) return; if (dlci->dead) - gsm_response(gsm, address, DM); + gsm_response(gsm, address, DM|PF); else { - gsm_response(gsm, address, UA); + gsm_response(gsm, address, UA|PF); gsm_dlci_open(dlci); + /* Save dlci open address */ + if (address) { + addr_open[addr_cnt] = address; + addr_cnt++; + } } break; case DISC|PF: - if (cr == 0) + if (cr == 1) goto invalid; if (dlci == NULL || dlci->state == DLCI_CLOSED) { - gsm_response(gsm, address, DM); + gsm_response(gsm, address, DM|PF); return; } /* Real close complete */ - gsm_response(gsm, address, UA); - gsm_dlci_close(dlci); + if (!address) { + if (addr_cnt > 0) { + for (i = 0; i < addr_cnt; i++) { + address = addr_open[i]; + dlci = gsm->dlci[address]; + gsm_dlci_close(dlci); + addr_open[i] = 0; + } + } + dlci = gsm->dlci[0]; + gsm_dlci_close(dlci); + addr_cnt = 0; + gsm_response(gsm, 0, UA|PF); + } else { + gsm_response(gsm, address, UA|PF); + gsm_dlci_close(dlci); + /* clear dlci address */ + for (j = 0; j < addr_cnt; j++) { + address_tmp = addr_open[j]; + if (address_tmp == address) { + for (k = j; k < addr_cnt; k++) + addr_open[k] = addr_open[k+1]; + addr_cnt--; + break; + } + } + } break; case UA: case UA|PF: @@ -2300,7 +2357,7 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) * configuration */ - if (need_close || need_restart) { + if (gsm->initiator && (need_close || need_restart)) { int ret; ret = gsm_disconnect(gsm); @@ -2358,8 +2415,7 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len) if (debug & 4) print_hex_dump_bytes("gsmld_output: ", DUMP_PREFIX_OFFSET, data, len); - gsm->tty->ops->write(gsm->tty, data, len); - return len; + return gsm->tty->ops->write(gsm->tty, data, len); } /** @@ -2384,17 +2440,19 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) else { /* Don't register device 0 - this is the control channel and not a usable tty interface */ - base = mux_num_to_base(gsm); /* Base for this MUX */ - for (i = 1; i < NUM_DLCI; i++) { - struct device *dev; + if (gsm->initiator) { + base = mux_num_to_base(gsm); /* Base for this MUX */ + for (i = 1; i < NUM_DLCI; i++) { + struct device *dev; - dev = tty_register_device(gsm_tty_driver, + dev = tty_register_device(gsm_tty_driver, base + i, NULL); - if (IS_ERR(dev)) { - for (i--; i >= 1; i--) - tty_unregister_device(gsm_tty_driver, - base + i); - return PTR_ERR(dev); + if (IS_ERR(dev)) { + for (i--; i >= 1; i--) + tty_unregister_device(gsm_tty_driver, + base + i); + return PTR_ERR(dev); + } } } } @@ -2416,8 +2474,10 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) int i; WARN_ON(tty != gsm->tty); - for (i = 1; i < NUM_DLCI; i++) - tty_unregister_device(gsm_tty_driver, base + i); + if (gsm->initiator) { + for (i = 1; i < NUM_DLCI; i++) + tty_unregister_device(gsm_tty_driver, base + i); + } gsm_cleanup_mux(gsm); tty_kref_put(gsm->tty); gsm->tty = NULL; @@ -2651,7 +2711,7 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file, base = mux_num_to_base(gsm); return put_user(base + 1, (__u32 __user *)arg); default: - return n_tty_ioctl_helper(tty, file, cmd, arg); + return n_tty_ioctl_helper(tty, cmd, arg); } } @@ -3000,6 +3060,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) { struct gsm_dlci *dlci = tty->driver_data; struct tty_port *port = &dlci->port; + struct gsm_mux *gsm = dlci->gsm; port->count++; tty_port_tty_set(port, tty); @@ -3009,7 +3070,8 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) a DM straight back. This is ok as that will have caused a hangup */ tty_port_set_initialized(port, 1); /* Start sending off SABM messages */ - gsm_dlci_begin_open(dlci); + if (gsm->initiator) + gsm_dlci_begin_open(dlci); /* And wait for virtual carrier */ return tty_port_block_til_ready(port, tty, filp); } diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 580a37b3fe1b..7e0884ecc74f 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -630,7 +630,7 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file, fallthrough; /* to default */ default: - error = n_tty_ioctl_helper(tty, file, cmd, arg); + error = n_tty_ioctl_helper(tty, cmd, arg); break; } return error; diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0ec93f1a61f5..5be6d02dc690 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -2418,7 +2418,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, up_write(&tty->termios_rwsem); return put_user(retval, (unsigned int __user *) arg); default: - return n_tty_ioctl_helper(tty, file, cmd, arg); + return n_tty_ioctl_helper(tty, cmd, arg); } } @@ -2450,7 +2450,6 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops) { *ops = n_tty_ops; ops->owner = NULL; - ops->flags = 0; } EXPORT_SYMBOL_GPL(n_tty_inherit_ops); diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a3a0154da567..5a2ff843ec5d 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -338,7 +338,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, rate = clk_round_rate(d->clk, newrate); if (rate > 0) { /* - * Premilinary set the uartclk to the new clock rate so the + * Preliminary set the uartclk to the new clock rate so the * clock update event handler caused by the clk_set_rate() * calling wouldn't actually update the UART divisor since * we about to do this anyway. @@ -350,11 +350,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, } clk_prepare_enable(d->clk); - p->status &= ~UPSTAT_AUTOCTS; - if (termios->c_cflag & CRTSCTS) - p->status |= UPSTAT_AUTOCTS; - - serial8250_do_set_termios(p, termios, old); + dw8250_do_set_termios(p, termios, old); } static void dw8250_set_ldisc(struct uart_port *p, struct ktermios *termios) @@ -393,8 +389,9 @@ static bool dw8250_idma_filter(struct dma_chan *chan, void *param) static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) { - if (p->dev->of_node) { - struct device_node *np = p->dev->of_node; + struct device_node *np = p->dev->of_node; + + if (np) { int id; /* get index of serial line, if found in DT aliases */ @@ -411,11 +408,13 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) data->skip_autocfg = true; } #endif - if (of_device_is_big_endian(p->dev->of_node)) { + + if (of_device_is_big_endian(np)) { p->iotype = UPIO_MEM32BE; p->serial_in = dw8250_serial_in32be; p->serial_out = dw8250_serial_out32be; } + if (of_device_is_compatible(np, "marvell,armada-38x-uart")) p->serial_out = dw8250_serial_out38x; @@ -726,7 +725,7 @@ static struct platform_driver dw8250_platform_driver = { .name = "dw-apb-uart", .pm = &dw8250_pm_ops, .of_match_table = dw8250_of_match, - .acpi_match_table = ACPI_PTR(dw8250_acpi_match), + .acpi_match_table = dw8250_acpi_match, }, .probe = dw8250_probe, .remove = dw8250_remove, diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c index 6d6a78eead3e..622d3b0d89e7 100644 --- a/drivers/tty/serial/8250/8250_dwlib.c +++ b/drivers/tty/serial/8250/8250_dwlib.c @@ -77,6 +77,16 @@ static void dw8250_set_divisor(struct uart_port *p, unsigned int baud, serial8250_do_set_divisor(p, baud, quot, quot_frac); } +void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct ktermios *old) +{ + p->status &= ~UPSTAT_AUTOCTS; + if (termios->c_cflag & CRTSCTS) + p->status |= UPSTAT_AUTOCTS; + + serial8250_do_set_termios(p, termios, old); +} +EXPORT_SYMBOL_GPL(dw8250_do_set_termios); + void dw8250_setup_port(struct uart_port *p) { struct uart_8250_port *up = up_to_u8250p(p); diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h index 9a12953832d3..83d528e5cc21 100644 --- a/drivers/tty/serial/8250/8250_dwlib.h +++ b/drivers/tty/serial/8250/8250_dwlib.h @@ -16,4 +16,5 @@ struct dw8250_port_data { u8 dlf_size; }; +void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct ktermios *old); void dw8250_setup_port(struct uart_port *p); diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index fc65a2293ce9..9c01c531349d 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -23,10 +23,6 @@ #include "8250.h" -struct fsl8250_data { - int line; -}; - int fsl8250_handle_irq(struct uart_port *port) { unsigned char lsr, orig_lsr; @@ -90,6 +86,10 @@ int fsl8250_handle_irq(struct uart_port *port) EXPORT_SYMBOL_GPL(fsl8250_handle_irq); #ifdef CONFIG_ACPI +struct fsl8250_data { + int line; +}; + static int fsl8250_acpi_probe(struct platform_device *pdev) { struct fsl8250_data *data; diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c index 848d81e3838c..d3bafec7619d 100644 --- a/drivers/tty/serial/8250/8250_lpss.c +++ b/drivers/tty/serial/8250/8250_lpss.c @@ -100,11 +100,7 @@ static void byt_set_termios(struct uart_port *p, struct ktermios *termios, reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE; writel(reg, p->membase + BYT_PRV_CLK); - p->status &= ~UPSTAT_AUTOCTS; - if (termios->c_cflag & CRTSCTS) - p->status |= UPSTAT_AUTOCTS; - - serial8250_do_set_termios(p, termios, old); + dw8250_do_set_termios(p, termios, old); } static unsigned int byt_get_mctrl(struct uart_port *port) @@ -168,6 +164,9 @@ static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port) * matching with the registered General Purpose DMA controllers. */ up->dma = dma; + + port->set_termios = dw8250_do_set_termios; + return 0; } diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 726912b16a55..93159557a2fb 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -3981,9 +3981,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) nr_ports = rc; } - priv = kzalloc(sizeof(struct serial_private) + - sizeof(unsigned int) * nr_ports, - GFP_KERNEL); + priv = kzalloc(struct_size(priv, line, nr_ports), GFP_KERNEL); if (!priv) { priv = ERR_PTR(-ENOMEM); goto err_deinit; diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 98e5ee4d0d08..1974bbadc975 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c @@ -56,10 +56,6 @@ static const struct pnp_device_id pnp_dev_table[] = { { "BRI1400", 0 }, /* Boca 33.6 Kbps Internal FD34FSVD */ { "BRI3400", 0 }, - /* Boca 33.6 Kbps Internal FD34FSVD */ - { "BRI0A49", 0 }, - /* Best Data Products Inc. Smart One 336F PnP Modem */ - { "BDP3336", 0 }, /* Computer Peripherals Inc */ /* EuroViVa CommCenter-33.6 SP PnP */ { "CPI4050", 0 }, diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 39fc96dc2531..8cd11aa63ed5 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -380,7 +380,7 @@ config SERIAL_8250_DW config SERIAL_8250_EM tristate "Support for Emma Mobile integrated serial port" depends on SERIAL_8250 && HAVE_CLK - depends on ARM || COMPILE_TEST + depends on (ARM && ARCH_RENESAS) || COMPILE_TEST help Selecting this option will add support for the integrated serial port hardware found on the Emma Mobile line of processors. diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 131a6a587acd..6ff94cfcd9db 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -239,10 +239,11 @@ config SERIAL_SAMSUNG depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || ARCH_APPLE || COMPILE_TEST select SERIAL_CORE help - Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, - providing /dev/ttySAC0, 1 and 2 (note, some machines may not - provide all of these ports, depending on how the serial port - pins are configured. + Support for the on-chip UARTs on the Samsung + S3C24xx/S3C64xx/S5Pv210/Exynos and Apple M1 SoCs, providing + /dev/ttySAC0, 1 and 2 (note, some machines may not provide all of + these ports, depending on how the serial port pins are configured. + Choose Y/M here only if you build for such SoC. config SERIAL_SAMSUNG_UARTS_4 bool diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 249ea35088d2..2c99a47a2535 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2084,7 +2084,7 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state, struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); switch (state) { - case 0: + case UART_PM_STATE_ON: /* * Enable the peripheral clock for this serial port. * This is called on uart_open() or a resume event. @@ -2094,7 +2094,7 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state, /* re-enable interrupts if we disabled some on suspend */ atmel_uart_writel(port, ATMEL_US_IER, atmel_port->backup_imr); break; - case 3: + case UART_PM_STATE_OFF: /* Back up the interrupt mask and disable all interrupts */ atmel_port->backup_imr = atmel_uart_readl(port, ATMEL_US_IMR); atmel_uart_writel(port, ATMEL_US_IDR, -1); diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 3df0788ddeb0..dde0824b2fa5 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1426,7 +1426,7 @@ out_clk: return ret; } -static int max310x_remove(struct device *dev) +static void max310x_remove(struct device *dev) { struct max310x_port *s = dev_get_drvdata(dev); int i; @@ -1441,8 +1441,6 @@ static int max310x_remove(struct device *dev) } clk_disable_unprepare(s->clk); - - return 0; } static const struct of_device_id __maybe_unused max310x_dt_ids[] = { @@ -1491,7 +1489,8 @@ static int max310x_spi_probe(struct spi_device *spi) static int max310x_spi_remove(struct spi_device *spi) { - return max310x_remove(&spi->dev); + max310x_remove(&spi->dev); + return 0; } static const struct spi_device_id max310x_id_table[] = { diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index e2f49863e9c2..ca084c10d0bb 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -65,7 +65,7 @@ enum s3c24xx_port_type { struct s3c24xx_uart_info { char *name; enum s3c24xx_port_type type; - unsigned int has_usi; + bool has_usi; unsigned int port_type; unsigned int fifosize; unsigned long rx_fifomask; @@ -2780,7 +2780,7 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { #endif #if defined(CONFIG_ARCH_EXYNOS) -#define EXYNOS_COMMON_SERIAL_DRV_DATA_USI(_has_usi) \ +#define EXYNOS_COMMON_SERIAL_DRV_DATA(_has_usi) \ .info = &(struct s3c24xx_uart_info) { \ .name = "Samsung Exynos UART", \ .type = TYPE_S3C6400, \ @@ -2804,21 +2804,18 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { .has_fracval = 1, \ } \ -#define EXYNOS_COMMON_SERIAL_DRV_DATA \ - EXYNOS_COMMON_SERIAL_DRV_DATA_USI(0) - static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { - EXYNOS_COMMON_SERIAL_DRV_DATA, + EXYNOS_COMMON_SERIAL_DRV_DATA(false), .fifosize = { 256, 64, 16, 16 }, }; static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { - EXYNOS_COMMON_SERIAL_DRV_DATA, + EXYNOS_COMMON_SERIAL_DRV_DATA(false), .fifosize = { 64, 256, 16, 256 }, }; static struct s3c24xx_serial_drv_data exynos850_serial_drv_data = { - EXYNOS_COMMON_SERIAL_DRV_DATA_USI(1), + EXYNOS_COMMON_SERIAL_DRV_DATA(true), .fifosize = { 256, 64, 64, 64 }, }; diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index acbb615dd28f..64e7e6c8145f 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1365,7 +1365,7 @@ out_clk: return ret; } -static int sc16is7xx_remove(struct device *dev) +static void sc16is7xx_remove(struct device *dev) { struct sc16is7xx_port *s = dev_get_drvdata(dev); int i; @@ -1385,8 +1385,6 @@ static int sc16is7xx_remove(struct device *dev) kthread_stop(s->kworker_task); clk_disable_unprepare(s->clk); - - return 0; } static const struct of_device_id __maybe_unused sc16is7xx_dt_ids[] = { @@ -1444,7 +1442,9 @@ static int sc16is7xx_spi_probe(struct spi_device *spi) static int sc16is7xx_spi_remove(struct spi_device *spi) { - return sc16is7xx_remove(&spi->dev); + sc16is7xx_remove(&spi->dev); + + return 0; } static const struct spi_device_id sc16is7xx_spi_id_table[] = { @@ -1497,7 +1497,9 @@ static int sc16is7xx_i2c_probe(struct i2c_client *i2c, static int sc16is7xx_i2c_remove(struct i2c_client *client) { - return sc16is7xx_remove(&client->dev); + sc16is7xx_remove(&client->dev); + + return 0; } static const struct i2c_device_id sc16is7xx_i2c_id_table[] = { diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0e2e35ab64c7..1e738f265eea 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -222,7 +222,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, if (retval == 0) { if (uart_console(uport) && uport->cons->cflag) { tty->termios.c_cflag = uport->cons->cflag; + tty->termios.c_ispeed = uport->cons->ispeed; + tty->termios.c_ospeed = uport->cons->ospeed; uport->cons->cflag = 0; + uport->cons->ispeed = 0; + uport->cons->ospeed = 0; } /* * Initialise the hardware port settings. @@ -290,8 +294,11 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) /* * Turn off DTR and RTS early. */ - if (uport && uart_console(uport) && tty) + if (uport && uart_console(uport) && tty) { uport->cons->cflag = tty->termios.c_cflag; + uport->cons->ispeed = tty->termios.c_ispeed; + uport->cons->ospeed = tty->termios.c_ospeed; + } if (!tty || C_HUPCL(tty)) uart_port_dtr_rts(uport, 0); @@ -2094,8 +2101,11 @@ uart_set_options(struct uart_port *port, struct console *co, * Allow the setting of the UART parameters with a NULL console * too: */ - if (co) + if (co) { co->cflag = termios.c_cflag; + co->ispeed = termios.c_ispeed; + co->ospeed = termios.c_ospeed; + } return 0; } @@ -2229,6 +2239,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) */ memset(&termios, 0, sizeof(struct ktermios)); termios.c_cflag = uport->cons->cflag; + termios.c_ispeed = uport->cons->ispeed; + termios.c_ospeed = uport->cons->ospeed; /* * If that's unset, use the tty termios setting. diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 0ac0371f943b..b79900d0e91a 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -887,7 +887,7 @@ static void __ssp_add_console_port(struct sifive_serial_port *ssp) static void __ssp_remove_console_port(struct sifive_serial_port *ssp) { - sifive_serial_console_ports[ssp->port.line] = 0; + sifive_serial_console_ports[ssp->port.line] = NULL; } #define SIFIVE_SERIAL_CONSOLE (&sifive_serial_console) diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index dfc1ba4e1572..d3d9566e5dbd 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -8,6 +8,7 @@ #include <linux/platform_device.h> #include <linux/module.h> +#include <linux/bitfield.h> #include <linux/console.h> #include <linux/serial.h> #include <linux/serial_core.h> @@ -63,9 +64,18 @@ static struct uart_port *console_port; #endif +/** + * struct uartlite_data: Driver private data + * reg_ops: Functions to read/write registers + * clk: Our parent clock, if present + * baud: The baud rate configured when this device was synthesized + * cflags: The cflags for parity and data bits + */ struct uartlite_data { const struct uartlite_reg_ops *reg_ops; struct clk *clk; + unsigned int baud; + tcflag_t cflags; }; struct uartlite_reg_ops { @@ -119,6 +129,8 @@ static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) static struct uart_port ulite_ports[ULITE_NR_UARTS]; +static struct uart_driver ulite_uart_driver; + /* --------------------------------------------------------------------- * Core UART driver operations */ @@ -306,7 +318,12 @@ static void ulite_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; - unsigned int baud; + struct uartlite_data *pdata = port->private_data; + + /* Set termios to what the hardware supports */ + termios->c_cflag &= ~(BRKINT | CSTOPB | PARENB | PARODD | CSIZE); + termios->c_cflag |= pdata->cflags & (PARENB | PARODD | CSIZE); + tty_termios_encode_baud_rate(termios, pdata->baud, pdata->baud); spin_lock_irqsave(&port->lock, flags); @@ -329,8 +346,7 @@ static void ulite_set_termios(struct uart_port *port, struct ktermios *termios, | ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN; /* update timeout */ - baud = uart_get_baud_rate(port, termios, old, 0, 460800); - uart_update_timeout(port, termios->c_cflag, baud); + uart_update_timeout(port, termios->c_cflag, pdata->baud); spin_unlock_irqrestore(&port->lock, flags); } @@ -532,8 +548,6 @@ static int ulite_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -static struct uart_driver ulite_uart_driver; - static struct console ulite_console = { .name = ULITE_NAME, .write = ulite_console_write, @@ -765,18 +779,73 @@ static int ulite_probe(struct platform_device *pdev) struct uartlite_data *pdata; int irq, ret; int id = pdev->id; -#ifdef CONFIG_OF - const __be32 *prop; - prop = of_get_property(pdev->dev.of_node, "port-number", NULL); - if (prop) - id = be32_to_cpup(prop); -#endif pdata = devm_kzalloc(&pdev->dev, sizeof(struct uartlite_data), GFP_KERNEL); if (!pdata) return -ENOMEM; + if (IS_ENABLED(CONFIG_OF)) { + const char *prop; + struct device_node *np = pdev->dev.of_node; + u32 val = 0; + + prop = "port-number"; + ret = of_property_read_u32(np, prop, &id); + if (ret && ret != -EINVAL) +of_err: + return dev_err_probe(&pdev->dev, ret, + "could not read %s\n", prop); + + prop = "current-speed"; + ret = of_property_read_u32(np, prop, &pdata->baud); + if (ret) + goto of_err; + + prop = "xlnx,use-parity"; + ret = of_property_read_u32(np, prop, &val); + if (ret && ret != -EINVAL) + goto of_err; + + if (val) { + prop = "xlnx,odd-parity"; + ret = of_property_read_u32(np, prop, &val); + if (ret) + goto of_err; + + if (val) + pdata->cflags |= PARODD; + pdata->cflags |= PARENB; + } + + val = 8; + prop = "xlnx,data-bits"; + ret = of_property_read_u32(np, prop, &val); + if (ret && ret != -EINVAL) + goto of_err; + + switch (val) { + case 5: + pdata->cflags |= CS5; + break; + case 6: + pdata->cflags |= CS6; + break; + case 7: + pdata->cflags |= CS7; + break; + case 8: + pdata->cflags |= CS8; + break; + default: + return dev_err_probe(&pdev->dev, -EINVAL, + "bad data bits %d\n", val); + } + } else { + pdata->baud = 9600; + pdata->cflags = CS8; + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index c911196ac893..4d3dbe62daf8 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -843,6 +843,8 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, sysrq->shift = KEY_RESERVED; else if (value != 2) sysrq->shift = code; + if (sysrq->active) + sysrq->shift_use = sysrq->shift; break; case KEY_SYSRQ: diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c index 426b1252781a..d903e111dbcb 100644 --- a/drivers/tty/tty_baudrate.c +++ b/drivers/tty/tty_baudrate.c @@ -154,7 +154,7 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, termios->c_ospeed = obaud; #ifdef IBSHIFT - if ((termios->c_cflag >> IBSHIFT) & CBAUD) + if (((termios->c_cflag >> IBSHIFT) & CBAUD) != B0) ibinput = 1; /* An input speed was specified */ #endif #ifdef BOTHER diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 507a25d692bb..63181925ec1a 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -675,7 +675,6 @@ static int tty_change_softcar(struct tty_struct *tty, int arg) /** * tty_mode_ioctl - mode related ioctls * @tty: tty for the ioctl - * @file: file pointer for the tty * @cmd: command * @arg: ioctl argument * @@ -684,16 +683,13 @@ static int tty_change_softcar(struct tty_struct *tty, int arg) * consistent mode setting. */ -int tty_mode_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) +int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct tty_struct *real_tty; void __user *p = (void __user *)arg; int ret = 0; struct ktermios kterm; - BUG_ON(file == NULL); - if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) real_tty = tty->link; @@ -858,8 +854,8 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) } EXPORT_SYMBOL_GPL(tty_perform_flush); -int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) +int n_tty_ioctl_helper(struct tty_struct *tty, unsigned int cmd, + unsigned long arg) { int retval; @@ -904,7 +900,7 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, return __tty_perform_flush(tty, arg); default: /* Try the mode commands */ - return tty_mode_ioctl(tty, file, cmd, arg); + return tty_mode_ioctl(tty, cmd, arg); } } EXPORT_SYMBOL(n_tty_ioctl_helper); |