xref: /OK3568_Linux_fs/kernel/drivers/tty/serial/pch_uart.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #include <linux/kernel.h>
6*4882a593Smuzhiyun #include <linux/serial_reg.h>
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/pci.h>
10*4882a593Smuzhiyun #include <linux/console.h>
11*4882a593Smuzhiyun #include <linux/serial_core.h>
12*4882a593Smuzhiyun #include <linux/tty.h>
13*4882a593Smuzhiyun #include <linux/tty_flip.h>
14*4882a593Smuzhiyun #include <linux/interrupt.h>
15*4882a593Smuzhiyun #include <linux/io.h>
16*4882a593Smuzhiyun #include <linux/dmi.h>
17*4882a593Smuzhiyun #include <linux/nmi.h>
18*4882a593Smuzhiyun #include <linux/delay.h>
19*4882a593Smuzhiyun #include <linux/of.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include <linux/debugfs.h>
22*4882a593Smuzhiyun #include <linux/dmaengine.h>
23*4882a593Smuzhiyun #include <linux/pch_dma.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun enum {
26*4882a593Smuzhiyun 	PCH_UART_HANDLED_RX_INT_SHIFT,
27*4882a593Smuzhiyun 	PCH_UART_HANDLED_TX_INT_SHIFT,
28*4882a593Smuzhiyun 	PCH_UART_HANDLED_RX_ERR_INT_SHIFT,
29*4882a593Smuzhiyun 	PCH_UART_HANDLED_RX_TRG_INT_SHIFT,
30*4882a593Smuzhiyun 	PCH_UART_HANDLED_MS_INT_SHIFT,
31*4882a593Smuzhiyun 	PCH_UART_HANDLED_LS_INT_SHIFT,
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define PCH_UART_DRIVER_DEVICE "ttyPCH"
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* Set the max number of UART port
37*4882a593Smuzhiyun  * Intel EG20T PCH: 4 port
38*4882a593Smuzhiyun  * LAPIS Semiconductor ML7213 IOH: 3 port
39*4882a593Smuzhiyun  * LAPIS Semiconductor ML7223 IOH: 2 port
40*4882a593Smuzhiyun */
41*4882a593Smuzhiyun #define PCH_UART_NR	4
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define PCH_UART_HANDLED_RX_INT	(1<<((PCH_UART_HANDLED_RX_INT_SHIFT)<<1))
44*4882a593Smuzhiyun #define PCH_UART_HANDLED_TX_INT	(1<<((PCH_UART_HANDLED_TX_INT_SHIFT)<<1))
45*4882a593Smuzhiyun #define PCH_UART_HANDLED_RX_ERR_INT	(1<<((\
46*4882a593Smuzhiyun 					PCH_UART_HANDLED_RX_ERR_INT_SHIFT)<<1))
47*4882a593Smuzhiyun #define PCH_UART_HANDLED_RX_TRG_INT	(1<<((\
48*4882a593Smuzhiyun 					PCH_UART_HANDLED_RX_TRG_INT_SHIFT)<<1))
49*4882a593Smuzhiyun #define PCH_UART_HANDLED_MS_INT	(1<<((PCH_UART_HANDLED_MS_INT_SHIFT)<<1))
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define PCH_UART_HANDLED_LS_INT	(1<<((PCH_UART_HANDLED_LS_INT_SHIFT)<<1))
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define PCH_UART_RBR		0x00
54*4882a593Smuzhiyun #define PCH_UART_THR		0x00
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun #define PCH_UART_IER_MASK	(PCH_UART_IER_ERBFI|PCH_UART_IER_ETBEI|\
57*4882a593Smuzhiyun 				PCH_UART_IER_ELSI|PCH_UART_IER_EDSSI)
58*4882a593Smuzhiyun #define PCH_UART_IER_ERBFI	0x00000001
59*4882a593Smuzhiyun #define PCH_UART_IER_ETBEI	0x00000002
60*4882a593Smuzhiyun #define PCH_UART_IER_ELSI	0x00000004
61*4882a593Smuzhiyun #define PCH_UART_IER_EDSSI	0x00000008
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #define PCH_UART_IIR_IP			0x00000001
64*4882a593Smuzhiyun #define PCH_UART_IIR_IID		0x00000006
65*4882a593Smuzhiyun #define PCH_UART_IIR_MSI		0x00000000
66*4882a593Smuzhiyun #define PCH_UART_IIR_TRI		0x00000002
67*4882a593Smuzhiyun #define PCH_UART_IIR_RRI		0x00000004
68*4882a593Smuzhiyun #define PCH_UART_IIR_REI		0x00000006
69*4882a593Smuzhiyun #define PCH_UART_IIR_TOI		0x00000008
70*4882a593Smuzhiyun #define PCH_UART_IIR_FIFO256		0x00000020
71*4882a593Smuzhiyun #define PCH_UART_IIR_FIFO64		PCH_UART_IIR_FIFO256
72*4882a593Smuzhiyun #define PCH_UART_IIR_FE			0x000000C0
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #define PCH_UART_FCR_FIFOE		0x00000001
75*4882a593Smuzhiyun #define PCH_UART_FCR_RFR		0x00000002
76*4882a593Smuzhiyun #define PCH_UART_FCR_TFR		0x00000004
77*4882a593Smuzhiyun #define PCH_UART_FCR_DMS		0x00000008
78*4882a593Smuzhiyun #define PCH_UART_FCR_FIFO256		0x00000020
79*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL		0x000000C0
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL1		0x00000000
82*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL64		0x00000040
83*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL128		0x00000080
84*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL224		0x000000C0
85*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL16		PCH_UART_FCR_RFTL64
86*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL32		PCH_UART_FCR_RFTL128
87*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL56		PCH_UART_FCR_RFTL224
88*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL4		PCH_UART_FCR_RFTL64
89*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL8		PCH_UART_FCR_RFTL128
90*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL14		PCH_UART_FCR_RFTL224
91*4882a593Smuzhiyun #define PCH_UART_FCR_RFTL_SHIFT		6
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun #define PCH_UART_LCR_WLS	0x00000003
94*4882a593Smuzhiyun #define PCH_UART_LCR_STB	0x00000004
95*4882a593Smuzhiyun #define PCH_UART_LCR_PEN	0x00000008
96*4882a593Smuzhiyun #define PCH_UART_LCR_EPS	0x00000010
97*4882a593Smuzhiyun #define PCH_UART_LCR_SP		0x00000020
98*4882a593Smuzhiyun #define PCH_UART_LCR_SB		0x00000040
99*4882a593Smuzhiyun #define PCH_UART_LCR_DLAB	0x00000080
100*4882a593Smuzhiyun #define PCH_UART_LCR_NP		0x00000000
101*4882a593Smuzhiyun #define PCH_UART_LCR_OP		PCH_UART_LCR_PEN
102*4882a593Smuzhiyun #define PCH_UART_LCR_EP		(PCH_UART_LCR_PEN | PCH_UART_LCR_EPS)
103*4882a593Smuzhiyun #define PCH_UART_LCR_1P		(PCH_UART_LCR_PEN | PCH_UART_LCR_SP)
104*4882a593Smuzhiyun #define PCH_UART_LCR_0P		(PCH_UART_LCR_PEN | PCH_UART_LCR_EPS |\
105*4882a593Smuzhiyun 				PCH_UART_LCR_SP)
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun #define PCH_UART_LCR_5BIT	0x00000000
108*4882a593Smuzhiyun #define PCH_UART_LCR_6BIT	0x00000001
109*4882a593Smuzhiyun #define PCH_UART_LCR_7BIT	0x00000002
110*4882a593Smuzhiyun #define PCH_UART_LCR_8BIT	0x00000003
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun #define PCH_UART_MCR_DTR	0x00000001
113*4882a593Smuzhiyun #define PCH_UART_MCR_RTS	0x00000002
114*4882a593Smuzhiyun #define PCH_UART_MCR_OUT	0x0000000C
115*4882a593Smuzhiyun #define PCH_UART_MCR_LOOP	0x00000010
116*4882a593Smuzhiyun #define PCH_UART_MCR_AFE	0x00000020
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun #define PCH_UART_LSR_DR		0x00000001
119*4882a593Smuzhiyun #define PCH_UART_LSR_ERR	(1<<7)
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun #define PCH_UART_MSR_DCTS	0x00000001
122*4882a593Smuzhiyun #define PCH_UART_MSR_DDSR	0x00000002
123*4882a593Smuzhiyun #define PCH_UART_MSR_TERI	0x00000004
124*4882a593Smuzhiyun #define PCH_UART_MSR_DDCD	0x00000008
125*4882a593Smuzhiyun #define PCH_UART_MSR_CTS	0x00000010
126*4882a593Smuzhiyun #define PCH_UART_MSR_DSR	0x00000020
127*4882a593Smuzhiyun #define PCH_UART_MSR_RI		0x00000040
128*4882a593Smuzhiyun #define PCH_UART_MSR_DCD	0x00000080
129*4882a593Smuzhiyun #define PCH_UART_MSR_DELTA	(PCH_UART_MSR_DCTS | PCH_UART_MSR_DDSR |\
130*4882a593Smuzhiyun 				PCH_UART_MSR_TERI | PCH_UART_MSR_DDCD)
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun #define PCH_UART_DLL		0x00
133*4882a593Smuzhiyun #define PCH_UART_DLM		0x01
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun #define PCH_UART_BRCSR		0x0E
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun #define PCH_UART_IID_RLS	(PCH_UART_IIR_REI)
138*4882a593Smuzhiyun #define PCH_UART_IID_RDR	(PCH_UART_IIR_RRI)
139*4882a593Smuzhiyun #define PCH_UART_IID_RDR_TO	(PCH_UART_IIR_RRI | PCH_UART_IIR_TOI)
140*4882a593Smuzhiyun #define PCH_UART_IID_THRE	(PCH_UART_IIR_TRI)
141*4882a593Smuzhiyun #define PCH_UART_IID_MS		(PCH_UART_IIR_MSI)
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define PCH_UART_HAL_PARITY_NONE	(PCH_UART_LCR_NP)
144*4882a593Smuzhiyun #define PCH_UART_HAL_PARITY_ODD		(PCH_UART_LCR_OP)
145*4882a593Smuzhiyun #define PCH_UART_HAL_PARITY_EVEN	(PCH_UART_LCR_EP)
146*4882a593Smuzhiyun #define PCH_UART_HAL_PARITY_FIX1	(PCH_UART_LCR_1P)
147*4882a593Smuzhiyun #define PCH_UART_HAL_PARITY_FIX0	(PCH_UART_LCR_0P)
148*4882a593Smuzhiyun #define PCH_UART_HAL_5BIT		(PCH_UART_LCR_5BIT)
149*4882a593Smuzhiyun #define PCH_UART_HAL_6BIT		(PCH_UART_LCR_6BIT)
150*4882a593Smuzhiyun #define PCH_UART_HAL_7BIT		(PCH_UART_LCR_7BIT)
151*4882a593Smuzhiyun #define PCH_UART_HAL_8BIT		(PCH_UART_LCR_8BIT)
152*4882a593Smuzhiyun #define PCH_UART_HAL_STB1		0
153*4882a593Smuzhiyun #define PCH_UART_HAL_STB2		(PCH_UART_LCR_STB)
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun #define PCH_UART_HAL_CLR_TX_FIFO	(PCH_UART_FCR_TFR)
156*4882a593Smuzhiyun #define PCH_UART_HAL_CLR_RX_FIFO	(PCH_UART_FCR_RFR)
157*4882a593Smuzhiyun #define PCH_UART_HAL_CLR_ALL_FIFO	(PCH_UART_HAL_CLR_TX_FIFO | \
158*4882a593Smuzhiyun 					PCH_UART_HAL_CLR_RX_FIFO)
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #define PCH_UART_HAL_DMA_MODE0		0
161*4882a593Smuzhiyun #define PCH_UART_HAL_FIFO_DIS		0
162*4882a593Smuzhiyun #define PCH_UART_HAL_FIFO16		(PCH_UART_FCR_FIFOE)
163*4882a593Smuzhiyun #define PCH_UART_HAL_FIFO256		(PCH_UART_FCR_FIFOE | \
164*4882a593Smuzhiyun 					PCH_UART_FCR_FIFO256)
165*4882a593Smuzhiyun #define PCH_UART_HAL_FIFO64		(PCH_UART_HAL_FIFO256)
166*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER1		(PCH_UART_FCR_RFTL1)
167*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER64		(PCH_UART_FCR_RFTL64)
168*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER128		(PCH_UART_FCR_RFTL128)
169*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER224		(PCH_UART_FCR_RFTL224)
170*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER16		(PCH_UART_FCR_RFTL16)
171*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER32		(PCH_UART_FCR_RFTL32)
172*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER56		(PCH_UART_FCR_RFTL56)
173*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER4		(PCH_UART_FCR_RFTL4)
174*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER8		(PCH_UART_FCR_RFTL8)
175*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER14		(PCH_UART_FCR_RFTL14)
176*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER_L		(PCH_UART_FCR_RFTL64)
177*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER_M		(PCH_UART_FCR_RFTL128)
178*4882a593Smuzhiyun #define PCH_UART_HAL_TRIGGER_H		(PCH_UART_FCR_RFTL224)
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun #define PCH_UART_HAL_RX_INT		(PCH_UART_IER_ERBFI)
181*4882a593Smuzhiyun #define PCH_UART_HAL_TX_INT		(PCH_UART_IER_ETBEI)
182*4882a593Smuzhiyun #define PCH_UART_HAL_RX_ERR_INT		(PCH_UART_IER_ELSI)
183*4882a593Smuzhiyun #define PCH_UART_HAL_MS_INT		(PCH_UART_IER_EDSSI)
184*4882a593Smuzhiyun #define PCH_UART_HAL_ALL_INT		(PCH_UART_IER_MASK)
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun #define PCH_UART_HAL_DTR		(PCH_UART_MCR_DTR)
187*4882a593Smuzhiyun #define PCH_UART_HAL_RTS		(PCH_UART_MCR_RTS)
188*4882a593Smuzhiyun #define PCH_UART_HAL_OUT		(PCH_UART_MCR_OUT)
189*4882a593Smuzhiyun #define PCH_UART_HAL_LOOP		(PCH_UART_MCR_LOOP)
190*4882a593Smuzhiyun #define PCH_UART_HAL_AFE		(PCH_UART_MCR_AFE)
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun #define DEFAULT_UARTCLK   1843200 /*   1.8432 MHz */
195*4882a593Smuzhiyun #define CMITC_UARTCLK   192000000 /* 192.0000 MHz */
196*4882a593Smuzhiyun #define FRI2_64_UARTCLK  64000000 /*  64.0000 MHz */
197*4882a593Smuzhiyun #define FRI2_48_UARTCLK  48000000 /*  48.0000 MHz */
198*4882a593Smuzhiyun #define NTC1_UARTCLK     64000000 /*  64.0000 MHz */
199*4882a593Smuzhiyun #define MINNOW_UARTCLK   50000000 /*  50.0000 MHz */
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun struct pch_uart_buffer {
202*4882a593Smuzhiyun 	unsigned char *buf;
203*4882a593Smuzhiyun 	int size;
204*4882a593Smuzhiyun };
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun struct eg20t_port {
207*4882a593Smuzhiyun 	struct uart_port port;
208*4882a593Smuzhiyun 	int port_type;
209*4882a593Smuzhiyun 	void __iomem *membase;
210*4882a593Smuzhiyun 	resource_size_t mapbase;
211*4882a593Smuzhiyun 	unsigned int iobase;
212*4882a593Smuzhiyun 	struct pci_dev *pdev;
213*4882a593Smuzhiyun 	int fifo_size;
214*4882a593Smuzhiyun 	unsigned int uartclk;
215*4882a593Smuzhiyun 	int start_tx;
216*4882a593Smuzhiyun 	int start_rx;
217*4882a593Smuzhiyun 	int tx_empty;
218*4882a593Smuzhiyun 	int trigger;
219*4882a593Smuzhiyun 	int trigger_level;
220*4882a593Smuzhiyun 	struct pch_uart_buffer rxbuf;
221*4882a593Smuzhiyun 	unsigned int dmsr;
222*4882a593Smuzhiyun 	unsigned int fcr;
223*4882a593Smuzhiyun 	unsigned int mcr;
224*4882a593Smuzhiyun 	unsigned int use_dma;
225*4882a593Smuzhiyun 	struct dma_async_tx_descriptor	*desc_tx;
226*4882a593Smuzhiyun 	struct dma_async_tx_descriptor	*desc_rx;
227*4882a593Smuzhiyun 	struct pch_dma_slave		param_tx;
228*4882a593Smuzhiyun 	struct pch_dma_slave		param_rx;
229*4882a593Smuzhiyun 	struct dma_chan			*chan_tx;
230*4882a593Smuzhiyun 	struct dma_chan			*chan_rx;
231*4882a593Smuzhiyun 	struct scatterlist		*sg_tx_p;
232*4882a593Smuzhiyun 	int				nent;
233*4882a593Smuzhiyun 	int				orig_nent;
234*4882a593Smuzhiyun 	struct scatterlist		sg_rx;
235*4882a593Smuzhiyun 	int				tx_dma_use;
236*4882a593Smuzhiyun 	void				*rx_buf_virt;
237*4882a593Smuzhiyun 	dma_addr_t			rx_buf_dma;
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	struct dentry	*debugfs;
240*4882a593Smuzhiyun #define IRQ_NAME_SIZE 17
241*4882a593Smuzhiyun 	char				irq_name[IRQ_NAME_SIZE];
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	/* protect the eg20t_port private structure and io access to membase */
244*4882a593Smuzhiyun 	spinlock_t lock;
245*4882a593Smuzhiyun };
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun /**
248*4882a593Smuzhiyun  * struct pch_uart_driver_data - private data structure for UART-DMA
249*4882a593Smuzhiyun  * @port_type:			The type of UART port
250*4882a593Smuzhiyun  * @line_no:			UART port line number (0, 1, 2...)
251*4882a593Smuzhiyun  */
252*4882a593Smuzhiyun struct pch_uart_driver_data {
253*4882a593Smuzhiyun 	int port_type;
254*4882a593Smuzhiyun 	int line_no;
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun enum pch_uart_num_t {
258*4882a593Smuzhiyun 	pch_et20t_uart0 = 0,
259*4882a593Smuzhiyun 	pch_et20t_uart1,
260*4882a593Smuzhiyun 	pch_et20t_uart2,
261*4882a593Smuzhiyun 	pch_et20t_uart3,
262*4882a593Smuzhiyun 	pch_ml7213_uart0,
263*4882a593Smuzhiyun 	pch_ml7213_uart1,
264*4882a593Smuzhiyun 	pch_ml7213_uart2,
265*4882a593Smuzhiyun 	pch_ml7223_uart0,
266*4882a593Smuzhiyun 	pch_ml7223_uart1,
267*4882a593Smuzhiyun 	pch_ml7831_uart0,
268*4882a593Smuzhiyun 	pch_ml7831_uart1,
269*4882a593Smuzhiyun };
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun static struct pch_uart_driver_data drv_dat[] = {
272*4882a593Smuzhiyun 	[pch_et20t_uart0] = {PORT_PCH_8LINE, 0},
273*4882a593Smuzhiyun 	[pch_et20t_uart1] = {PORT_PCH_2LINE, 1},
274*4882a593Smuzhiyun 	[pch_et20t_uart2] = {PORT_PCH_2LINE, 2},
275*4882a593Smuzhiyun 	[pch_et20t_uart3] = {PORT_PCH_2LINE, 3},
276*4882a593Smuzhiyun 	[pch_ml7213_uart0] = {PORT_PCH_8LINE, 0},
277*4882a593Smuzhiyun 	[pch_ml7213_uart1] = {PORT_PCH_2LINE, 1},
278*4882a593Smuzhiyun 	[pch_ml7213_uart2] = {PORT_PCH_2LINE, 2},
279*4882a593Smuzhiyun 	[pch_ml7223_uart0] = {PORT_PCH_8LINE, 0},
280*4882a593Smuzhiyun 	[pch_ml7223_uart1] = {PORT_PCH_2LINE, 1},
281*4882a593Smuzhiyun 	[pch_ml7831_uart0] = {PORT_PCH_8LINE, 0},
282*4882a593Smuzhiyun 	[pch_ml7831_uart1] = {PORT_PCH_2LINE, 1},
283*4882a593Smuzhiyun };
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
286*4882a593Smuzhiyun static struct eg20t_port *pch_uart_ports[PCH_UART_NR];
287*4882a593Smuzhiyun #endif
288*4882a593Smuzhiyun static unsigned int default_baud = 9600;
289*4882a593Smuzhiyun static unsigned int user_uartclk = 0;
290*4882a593Smuzhiyun static const int trigger_level_256[4] = { 1, 64, 128, 224 };
291*4882a593Smuzhiyun static const int trigger_level_64[4] = { 1, 16, 32, 56 };
292*4882a593Smuzhiyun static const int trigger_level_16[4] = { 1, 4, 8, 14 };
293*4882a593Smuzhiyun static const int trigger_level_1[4] = { 1, 1, 1, 1 };
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun #define PCH_REGS_BUFSIZE	1024
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 
port_show_regs(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)300*4882a593Smuzhiyun static ssize_t port_show_regs(struct file *file, char __user *user_buf,
301*4882a593Smuzhiyun 				size_t count, loff_t *ppos)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun 	struct eg20t_port *priv = file->private_data;
304*4882a593Smuzhiyun 	char *buf;
305*4882a593Smuzhiyun 	u32 len = 0;
306*4882a593Smuzhiyun 	ssize_t ret;
307*4882a593Smuzhiyun 	unsigned char lcr;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	buf = kzalloc(PCH_REGS_BUFSIZE, GFP_KERNEL);
310*4882a593Smuzhiyun 	if (!buf)
311*4882a593Smuzhiyun 		return 0;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
314*4882a593Smuzhiyun 			"PCH EG20T port[%d] regs:\n", priv->port.line);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
317*4882a593Smuzhiyun 			"=================================\n");
318*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
319*4882a593Smuzhiyun 			"IER: \t0x%02x\n", ioread8(priv->membase + UART_IER));
320*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
321*4882a593Smuzhiyun 			"IIR: \t0x%02x\n", ioread8(priv->membase + UART_IIR));
322*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
323*4882a593Smuzhiyun 			"LCR: \t0x%02x\n", ioread8(priv->membase + UART_LCR));
324*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
325*4882a593Smuzhiyun 			"MCR: \t0x%02x\n", ioread8(priv->membase + UART_MCR));
326*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
327*4882a593Smuzhiyun 			"LSR: \t0x%02x\n", ioread8(priv->membase + UART_LSR));
328*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
329*4882a593Smuzhiyun 			"MSR: \t0x%02x\n", ioread8(priv->membase + UART_MSR));
330*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
331*4882a593Smuzhiyun 			"BRCSR: \t0x%02x\n",
332*4882a593Smuzhiyun 			ioread8(priv->membase + PCH_UART_BRCSR));
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	lcr = ioread8(priv->membase + UART_LCR);
335*4882a593Smuzhiyun 	iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR);
336*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
337*4882a593Smuzhiyun 			"DLL: \t0x%02x\n", ioread8(priv->membase + UART_DLL));
338*4882a593Smuzhiyun 	len += scnprintf(buf + len, PCH_REGS_BUFSIZE - len,
339*4882a593Smuzhiyun 			"DLM: \t0x%02x\n", ioread8(priv->membase + UART_DLM));
340*4882a593Smuzhiyun 	iowrite8(lcr, priv->membase + UART_LCR);
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	if (len > PCH_REGS_BUFSIZE)
343*4882a593Smuzhiyun 		len = PCH_REGS_BUFSIZE;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	ret =  simple_read_from_buffer(user_buf, count, ppos, buf, len);
346*4882a593Smuzhiyun 	kfree(buf);
347*4882a593Smuzhiyun 	return ret;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun static const struct file_operations port_regs_ops = {
351*4882a593Smuzhiyun 	.owner		= THIS_MODULE,
352*4882a593Smuzhiyun 	.open		= simple_open,
353*4882a593Smuzhiyun 	.read		= port_show_regs,
354*4882a593Smuzhiyun 	.llseek		= default_llseek,
355*4882a593Smuzhiyun };
356*4882a593Smuzhiyun #endif	/* CONFIG_DEBUG_FS */
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun static const struct dmi_system_id pch_uart_dmi_table[] = {
359*4882a593Smuzhiyun 	{
360*4882a593Smuzhiyun 		.ident = "CM-iTC",
361*4882a593Smuzhiyun 		{
362*4882a593Smuzhiyun 			DMI_MATCH(DMI_BOARD_NAME, "CM-iTC"),
363*4882a593Smuzhiyun 		},
364*4882a593Smuzhiyun 		(void *)CMITC_UARTCLK,
365*4882a593Smuzhiyun 	},
366*4882a593Smuzhiyun 	{
367*4882a593Smuzhiyun 		.ident = "FRI2",
368*4882a593Smuzhiyun 		{
369*4882a593Smuzhiyun 			DMI_MATCH(DMI_BIOS_VERSION, "FRI2"),
370*4882a593Smuzhiyun 		},
371*4882a593Smuzhiyun 		(void *)FRI2_64_UARTCLK,
372*4882a593Smuzhiyun 	},
373*4882a593Smuzhiyun 	{
374*4882a593Smuzhiyun 		.ident = "Fish River Island II",
375*4882a593Smuzhiyun 		{
376*4882a593Smuzhiyun 			DMI_MATCH(DMI_PRODUCT_NAME, "Fish River Island II"),
377*4882a593Smuzhiyun 		},
378*4882a593Smuzhiyun 		(void *)FRI2_48_UARTCLK,
379*4882a593Smuzhiyun 	},
380*4882a593Smuzhiyun 	{
381*4882a593Smuzhiyun 		.ident = "COMe-mTT",
382*4882a593Smuzhiyun 		{
383*4882a593Smuzhiyun 			DMI_MATCH(DMI_BOARD_NAME, "COMe-mTT"),
384*4882a593Smuzhiyun 		},
385*4882a593Smuzhiyun 		(void *)NTC1_UARTCLK,
386*4882a593Smuzhiyun 	},
387*4882a593Smuzhiyun 	{
388*4882a593Smuzhiyun 		.ident = "nanoETXexpress-TT",
389*4882a593Smuzhiyun 		{
390*4882a593Smuzhiyun 			DMI_MATCH(DMI_BOARD_NAME, "nanoETXexpress-TT"),
391*4882a593Smuzhiyun 		},
392*4882a593Smuzhiyun 		(void *)NTC1_UARTCLK,
393*4882a593Smuzhiyun 	},
394*4882a593Smuzhiyun 	{
395*4882a593Smuzhiyun 		.ident = "MinnowBoard",
396*4882a593Smuzhiyun 		{
397*4882a593Smuzhiyun 			DMI_MATCH(DMI_BOARD_NAME, "MinnowBoard"),
398*4882a593Smuzhiyun 		},
399*4882a593Smuzhiyun 		(void *)MINNOW_UARTCLK,
400*4882a593Smuzhiyun 	},
401*4882a593Smuzhiyun 	{ }
402*4882a593Smuzhiyun };
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun /* Return UART clock, checking for board specific clocks. */
pch_uart_get_uartclk(void)405*4882a593Smuzhiyun static unsigned int pch_uart_get_uartclk(void)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	const struct dmi_system_id *d;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	if (user_uartclk)
410*4882a593Smuzhiyun 		return user_uartclk;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	d = dmi_first_match(pch_uart_dmi_table);
413*4882a593Smuzhiyun 	if (d)
414*4882a593Smuzhiyun 		return (unsigned long)d->driver_data;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	return DEFAULT_UARTCLK;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
pch_uart_hal_enable_interrupt(struct eg20t_port * priv,unsigned int flag)419*4882a593Smuzhiyun static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv,
420*4882a593Smuzhiyun 					  unsigned int flag)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun 	u8 ier = ioread8(priv->membase + UART_IER);
423*4882a593Smuzhiyun 	ier |= flag & PCH_UART_IER_MASK;
424*4882a593Smuzhiyun 	iowrite8(ier, priv->membase + UART_IER);
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
pch_uart_hal_disable_interrupt(struct eg20t_port * priv,unsigned int flag)427*4882a593Smuzhiyun static void pch_uart_hal_disable_interrupt(struct eg20t_port *priv,
428*4882a593Smuzhiyun 					   unsigned int flag)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	u8 ier = ioread8(priv->membase + UART_IER);
431*4882a593Smuzhiyun 	ier &= ~(flag & PCH_UART_IER_MASK);
432*4882a593Smuzhiyun 	iowrite8(ier, priv->membase + UART_IER);
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun 
pch_uart_hal_set_line(struct eg20t_port * priv,unsigned int baud,unsigned int parity,unsigned int bits,unsigned int stb)435*4882a593Smuzhiyun static int pch_uart_hal_set_line(struct eg20t_port *priv, unsigned int baud,
436*4882a593Smuzhiyun 				 unsigned int parity, unsigned int bits,
437*4882a593Smuzhiyun 				 unsigned int stb)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 	unsigned int dll, dlm, lcr;
440*4882a593Smuzhiyun 	int div;
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	div = DIV_ROUND_CLOSEST(priv->uartclk / 16, baud);
443*4882a593Smuzhiyun 	if (div < 0 || USHRT_MAX <= div) {
444*4882a593Smuzhiyun 		dev_err(priv->port.dev, "Invalid Baud(div=0x%x)\n", div);
445*4882a593Smuzhiyun 		return -EINVAL;
446*4882a593Smuzhiyun 	}
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	dll = (unsigned int)div & 0x00FFU;
449*4882a593Smuzhiyun 	dlm = ((unsigned int)div >> 8) & 0x00FFU;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	if (parity & ~(PCH_UART_LCR_PEN | PCH_UART_LCR_EPS | PCH_UART_LCR_SP)) {
452*4882a593Smuzhiyun 		dev_err(priv->port.dev, "Invalid parity(0x%x)\n", parity);
453*4882a593Smuzhiyun 		return -EINVAL;
454*4882a593Smuzhiyun 	}
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	if (bits & ~PCH_UART_LCR_WLS) {
457*4882a593Smuzhiyun 		dev_err(priv->port.dev, "Invalid bits(0x%x)\n", bits);
458*4882a593Smuzhiyun 		return -EINVAL;
459*4882a593Smuzhiyun 	}
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	if (stb & ~PCH_UART_LCR_STB) {
462*4882a593Smuzhiyun 		dev_err(priv->port.dev, "Invalid STB(0x%x)\n", stb);
463*4882a593Smuzhiyun 		return -EINVAL;
464*4882a593Smuzhiyun 	}
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	lcr = parity;
467*4882a593Smuzhiyun 	lcr |= bits;
468*4882a593Smuzhiyun 	lcr |= stb;
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	dev_dbg(priv->port.dev, "%s:baud = %u, div = %04x, lcr = %02x (%lu)\n",
471*4882a593Smuzhiyun 		 __func__, baud, div, lcr, jiffies);
472*4882a593Smuzhiyun 	iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR);
473*4882a593Smuzhiyun 	iowrite8(dll, priv->membase + PCH_UART_DLL);
474*4882a593Smuzhiyun 	iowrite8(dlm, priv->membase + PCH_UART_DLM);
475*4882a593Smuzhiyun 	iowrite8(lcr, priv->membase + UART_LCR);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	return 0;
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun 
pch_uart_hal_fifo_reset(struct eg20t_port * priv,unsigned int flag)480*4882a593Smuzhiyun static int pch_uart_hal_fifo_reset(struct eg20t_port *priv,
481*4882a593Smuzhiyun 				    unsigned int flag)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun 	if (flag & ~(PCH_UART_FCR_TFR | PCH_UART_FCR_RFR)) {
484*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:Invalid flag(0x%x)\n",
485*4882a593Smuzhiyun 			__func__, flag);
486*4882a593Smuzhiyun 		return -EINVAL;
487*4882a593Smuzhiyun 	}
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun 	iowrite8(PCH_UART_FCR_FIFOE | priv->fcr, priv->membase + UART_FCR);
490*4882a593Smuzhiyun 	iowrite8(PCH_UART_FCR_FIFOE | priv->fcr | flag,
491*4882a593Smuzhiyun 		 priv->membase + UART_FCR);
492*4882a593Smuzhiyun 	iowrite8(priv->fcr, priv->membase + UART_FCR);
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	return 0;
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun 
pch_uart_hal_set_fifo(struct eg20t_port * priv,unsigned int dmamode,unsigned int fifo_size,unsigned int trigger)497*4882a593Smuzhiyun static int pch_uart_hal_set_fifo(struct eg20t_port *priv,
498*4882a593Smuzhiyun 				 unsigned int dmamode,
499*4882a593Smuzhiyun 				 unsigned int fifo_size, unsigned int trigger)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun 	u8 fcr;
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	if (dmamode & ~PCH_UART_FCR_DMS) {
504*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:Invalid DMA Mode(0x%x)\n",
505*4882a593Smuzhiyun 			__func__, dmamode);
506*4882a593Smuzhiyun 		return -EINVAL;
507*4882a593Smuzhiyun 	}
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	if (fifo_size & ~(PCH_UART_FCR_FIFOE | PCH_UART_FCR_FIFO256)) {
510*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:Invalid FIFO SIZE(0x%x)\n",
511*4882a593Smuzhiyun 			__func__, fifo_size);
512*4882a593Smuzhiyun 		return -EINVAL;
513*4882a593Smuzhiyun 	}
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	if (trigger & ~PCH_UART_FCR_RFTL) {
516*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:Invalid TRIGGER(0x%x)\n",
517*4882a593Smuzhiyun 			__func__, trigger);
518*4882a593Smuzhiyun 		return -EINVAL;
519*4882a593Smuzhiyun 	}
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	switch (priv->fifo_size) {
522*4882a593Smuzhiyun 	case 256:
523*4882a593Smuzhiyun 		priv->trigger_level =
524*4882a593Smuzhiyun 		    trigger_level_256[trigger >> PCH_UART_FCR_RFTL_SHIFT];
525*4882a593Smuzhiyun 		break;
526*4882a593Smuzhiyun 	case 64:
527*4882a593Smuzhiyun 		priv->trigger_level =
528*4882a593Smuzhiyun 		    trigger_level_64[trigger >> PCH_UART_FCR_RFTL_SHIFT];
529*4882a593Smuzhiyun 		break;
530*4882a593Smuzhiyun 	case 16:
531*4882a593Smuzhiyun 		priv->trigger_level =
532*4882a593Smuzhiyun 		    trigger_level_16[trigger >> PCH_UART_FCR_RFTL_SHIFT];
533*4882a593Smuzhiyun 		break;
534*4882a593Smuzhiyun 	default:
535*4882a593Smuzhiyun 		priv->trigger_level =
536*4882a593Smuzhiyun 		    trigger_level_1[trigger >> PCH_UART_FCR_RFTL_SHIFT];
537*4882a593Smuzhiyun 		break;
538*4882a593Smuzhiyun 	}
539*4882a593Smuzhiyun 	fcr =
540*4882a593Smuzhiyun 	    dmamode | fifo_size | trigger | PCH_UART_FCR_RFR | PCH_UART_FCR_TFR;
541*4882a593Smuzhiyun 	iowrite8(PCH_UART_FCR_FIFOE, priv->membase + UART_FCR);
542*4882a593Smuzhiyun 	iowrite8(PCH_UART_FCR_FIFOE | PCH_UART_FCR_RFR | PCH_UART_FCR_TFR,
543*4882a593Smuzhiyun 		 priv->membase + UART_FCR);
544*4882a593Smuzhiyun 	iowrite8(fcr, priv->membase + UART_FCR);
545*4882a593Smuzhiyun 	priv->fcr = fcr;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	return 0;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun 
pch_uart_hal_get_modem(struct eg20t_port * priv)550*4882a593Smuzhiyun static u8 pch_uart_hal_get_modem(struct eg20t_port *priv)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	unsigned int msr = ioread8(priv->membase + UART_MSR);
553*4882a593Smuzhiyun 	priv->dmsr = msr & PCH_UART_MSR_DELTA;
554*4882a593Smuzhiyun 	return (u8)msr;
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun 
pch_uart_hal_write(struct eg20t_port * priv,const unsigned char * buf,int tx_size)557*4882a593Smuzhiyun static void pch_uart_hal_write(struct eg20t_port *priv,
558*4882a593Smuzhiyun 			      const unsigned char *buf, int tx_size)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun 	int i;
561*4882a593Smuzhiyun 	unsigned int thr;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	for (i = 0; i < tx_size;) {
564*4882a593Smuzhiyun 		thr = buf[i++];
565*4882a593Smuzhiyun 		iowrite8(thr, priv->membase + PCH_UART_THR);
566*4882a593Smuzhiyun 	}
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun 
pch_uart_hal_read(struct eg20t_port * priv,unsigned char * buf,int rx_size)569*4882a593Smuzhiyun static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf,
570*4882a593Smuzhiyun 			     int rx_size)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun 	int i;
573*4882a593Smuzhiyun 	u8 rbr, lsr;
574*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	lsr = ioread8(priv->membase + UART_LSR);
577*4882a593Smuzhiyun 	for (i = 0, lsr = ioread8(priv->membase + UART_LSR);
578*4882a593Smuzhiyun 	     i < rx_size && lsr & (UART_LSR_DR | UART_LSR_BI);
579*4882a593Smuzhiyun 	     lsr = ioread8(priv->membase + UART_LSR)) {
580*4882a593Smuzhiyun 		rbr = ioread8(priv->membase + PCH_UART_RBR);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 		if (lsr & UART_LSR_BI) {
583*4882a593Smuzhiyun 			port->icount.brk++;
584*4882a593Smuzhiyun 			if (uart_handle_break(port))
585*4882a593Smuzhiyun 				continue;
586*4882a593Smuzhiyun 		}
587*4882a593Smuzhiyun 		if (uart_handle_sysrq_char(port, rbr))
588*4882a593Smuzhiyun 			continue;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 		buf[i++] = rbr;
591*4882a593Smuzhiyun 	}
592*4882a593Smuzhiyun 	return i;
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun 
pch_uart_hal_get_iid(struct eg20t_port * priv)595*4882a593Smuzhiyun static unsigned char pch_uart_hal_get_iid(struct eg20t_port *priv)
596*4882a593Smuzhiyun {
597*4882a593Smuzhiyun 	return ioread8(priv->membase + UART_IIR) &\
598*4882a593Smuzhiyun 		      (PCH_UART_IIR_IID | PCH_UART_IIR_TOI | PCH_UART_IIR_IP);
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun 
pch_uart_hal_get_line_status(struct eg20t_port * priv)601*4882a593Smuzhiyun static u8 pch_uart_hal_get_line_status(struct eg20t_port *priv)
602*4882a593Smuzhiyun {
603*4882a593Smuzhiyun 	return ioread8(priv->membase + UART_LSR);
604*4882a593Smuzhiyun }
605*4882a593Smuzhiyun 
pch_uart_hal_set_break(struct eg20t_port * priv,int on)606*4882a593Smuzhiyun static void pch_uart_hal_set_break(struct eg20t_port *priv, int on)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun 	unsigned int lcr;
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	lcr = ioread8(priv->membase + UART_LCR);
611*4882a593Smuzhiyun 	if (on)
612*4882a593Smuzhiyun 		lcr |= PCH_UART_LCR_SB;
613*4882a593Smuzhiyun 	else
614*4882a593Smuzhiyun 		lcr &= ~PCH_UART_LCR_SB;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	iowrite8(lcr, priv->membase + UART_LCR);
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun 
push_rx(struct eg20t_port * priv,const unsigned char * buf,int size)619*4882a593Smuzhiyun static int push_rx(struct eg20t_port *priv, const unsigned char *buf,
620*4882a593Smuzhiyun 		   int size)
621*4882a593Smuzhiyun {
622*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
623*4882a593Smuzhiyun 	struct tty_port *tport = &port->state->port;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	tty_insert_flip_string(tport, buf, size);
626*4882a593Smuzhiyun 	tty_flip_buffer_push(tport);
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	return 0;
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun 
dma_push_rx(struct eg20t_port * priv,int size)631*4882a593Smuzhiyun static int dma_push_rx(struct eg20t_port *priv, int size)
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun 	int room;
634*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
635*4882a593Smuzhiyun 	struct tty_port *tport = &port->state->port;
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	room = tty_buffer_request_room(tport, size);
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 	if (room < size)
640*4882a593Smuzhiyun 		dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
641*4882a593Smuzhiyun 			 size - room);
642*4882a593Smuzhiyun 	if (!room)
643*4882a593Smuzhiyun 		return 0;
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	tty_insert_flip_string(tport, sg_virt(&priv->sg_rx), size);
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	port->icount.rx += room;
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	return room;
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun 
pch_free_dma(struct uart_port * port)652*4882a593Smuzhiyun static void pch_free_dma(struct uart_port *port)
653*4882a593Smuzhiyun {
654*4882a593Smuzhiyun 	struct eg20t_port *priv;
655*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	if (priv->chan_tx) {
658*4882a593Smuzhiyun 		dma_release_channel(priv->chan_tx);
659*4882a593Smuzhiyun 		priv->chan_tx = NULL;
660*4882a593Smuzhiyun 	}
661*4882a593Smuzhiyun 	if (priv->chan_rx) {
662*4882a593Smuzhiyun 		dma_release_channel(priv->chan_rx);
663*4882a593Smuzhiyun 		priv->chan_rx = NULL;
664*4882a593Smuzhiyun 	}
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun 	if (priv->rx_buf_dma) {
667*4882a593Smuzhiyun 		dma_free_coherent(port->dev, port->fifosize, priv->rx_buf_virt,
668*4882a593Smuzhiyun 				  priv->rx_buf_dma);
669*4882a593Smuzhiyun 		priv->rx_buf_virt = NULL;
670*4882a593Smuzhiyun 		priv->rx_buf_dma = 0;
671*4882a593Smuzhiyun 	}
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	return;
674*4882a593Smuzhiyun }
675*4882a593Smuzhiyun 
filter(struct dma_chan * chan,void * slave)676*4882a593Smuzhiyun static bool filter(struct dma_chan *chan, void *slave)
677*4882a593Smuzhiyun {
678*4882a593Smuzhiyun 	struct pch_dma_slave *param = slave;
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	if ((chan->chan_id == param->chan_id) && (param->dma_dev ==
681*4882a593Smuzhiyun 						  chan->device->dev)) {
682*4882a593Smuzhiyun 		chan->private = param;
683*4882a593Smuzhiyun 		return true;
684*4882a593Smuzhiyun 	} else {
685*4882a593Smuzhiyun 		return false;
686*4882a593Smuzhiyun 	}
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun 
pch_request_dma(struct uart_port * port)689*4882a593Smuzhiyun static void pch_request_dma(struct uart_port *port)
690*4882a593Smuzhiyun {
691*4882a593Smuzhiyun 	dma_cap_mask_t mask;
692*4882a593Smuzhiyun 	struct dma_chan *chan;
693*4882a593Smuzhiyun 	struct pci_dev *dma_dev;
694*4882a593Smuzhiyun 	struct pch_dma_slave *param;
695*4882a593Smuzhiyun 	struct eg20t_port *priv =
696*4882a593Smuzhiyun 				container_of(port, struct eg20t_port, port);
697*4882a593Smuzhiyun 	dma_cap_zero(mask);
698*4882a593Smuzhiyun 	dma_cap_set(DMA_SLAVE, mask);
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	/* Get DMA's dev information */
701*4882a593Smuzhiyun 	dma_dev = pci_get_slot(priv->pdev->bus,
702*4882a593Smuzhiyun 			PCI_DEVFN(PCI_SLOT(priv->pdev->devfn), 0));
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	/* Set Tx DMA */
705*4882a593Smuzhiyun 	param = &priv->param_tx;
706*4882a593Smuzhiyun 	param->dma_dev = &dma_dev->dev;
707*4882a593Smuzhiyun 	param->chan_id = priv->port.line * 2; /* Tx = 0, 2, 4, ... */
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	param->tx_reg = port->mapbase + UART_TX;
710*4882a593Smuzhiyun 	chan = dma_request_channel(mask, filter, param);
711*4882a593Smuzhiyun 	if (!chan) {
712*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
713*4882a593Smuzhiyun 			__func__);
714*4882a593Smuzhiyun 		return;
715*4882a593Smuzhiyun 	}
716*4882a593Smuzhiyun 	priv->chan_tx = chan;
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	/* Set Rx DMA */
719*4882a593Smuzhiyun 	param = &priv->param_rx;
720*4882a593Smuzhiyun 	param->dma_dev = &dma_dev->dev;
721*4882a593Smuzhiyun 	param->chan_id = priv->port.line * 2 + 1; /* Rx = Tx + 1 */
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	param->rx_reg = port->mapbase + UART_RX;
724*4882a593Smuzhiyun 	chan = dma_request_channel(mask, filter, param);
725*4882a593Smuzhiyun 	if (!chan) {
726*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",
727*4882a593Smuzhiyun 			__func__);
728*4882a593Smuzhiyun 		dma_release_channel(priv->chan_tx);
729*4882a593Smuzhiyun 		priv->chan_tx = NULL;
730*4882a593Smuzhiyun 		return;
731*4882a593Smuzhiyun 	}
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	/* Get Consistent memory for DMA */
734*4882a593Smuzhiyun 	priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
735*4882a593Smuzhiyun 				    &priv->rx_buf_dma, GFP_KERNEL);
736*4882a593Smuzhiyun 	priv->chan_rx = chan;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun 
pch_dma_rx_complete(void * arg)739*4882a593Smuzhiyun static void pch_dma_rx_complete(void *arg)
740*4882a593Smuzhiyun {
741*4882a593Smuzhiyun 	struct eg20t_port *priv = arg;
742*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
743*4882a593Smuzhiyun 	int count;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 	dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE);
746*4882a593Smuzhiyun 	count = dma_push_rx(priv, priv->trigger_level);
747*4882a593Smuzhiyun 	if (count)
748*4882a593Smuzhiyun 		tty_flip_buffer_push(&port->state->port);
749*4882a593Smuzhiyun 	async_tx_ack(priv->desc_rx);
750*4882a593Smuzhiyun 	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT |
751*4882a593Smuzhiyun 					    PCH_UART_HAL_RX_ERR_INT);
752*4882a593Smuzhiyun }
753*4882a593Smuzhiyun 
pch_dma_tx_complete(void * arg)754*4882a593Smuzhiyun static void pch_dma_tx_complete(void *arg)
755*4882a593Smuzhiyun {
756*4882a593Smuzhiyun 	struct eg20t_port *priv = arg;
757*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
758*4882a593Smuzhiyun 	struct circ_buf *xmit = &port->state->xmit;
759*4882a593Smuzhiyun 	struct scatterlist *sg = priv->sg_tx_p;
760*4882a593Smuzhiyun 	int i;
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	for (i = 0; i < priv->nent; i++, sg++) {
763*4882a593Smuzhiyun 		xmit->tail += sg_dma_len(sg);
764*4882a593Smuzhiyun 		port->icount.tx += sg_dma_len(sg);
765*4882a593Smuzhiyun 	}
766*4882a593Smuzhiyun 	xmit->tail &= UART_XMIT_SIZE - 1;
767*4882a593Smuzhiyun 	async_tx_ack(priv->desc_tx);
768*4882a593Smuzhiyun 	dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE);
769*4882a593Smuzhiyun 	priv->tx_dma_use = 0;
770*4882a593Smuzhiyun 	priv->nent = 0;
771*4882a593Smuzhiyun 	priv->orig_nent = 0;
772*4882a593Smuzhiyun 	kfree(priv->sg_tx_p);
773*4882a593Smuzhiyun 	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT);
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun 
pop_tx(struct eg20t_port * priv,int size)776*4882a593Smuzhiyun static int pop_tx(struct eg20t_port *priv, int size)
777*4882a593Smuzhiyun {
778*4882a593Smuzhiyun 	int count = 0;
779*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
780*4882a593Smuzhiyun 	struct circ_buf *xmit = &port->state->xmit;
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	if (uart_tx_stopped(port) || uart_circ_empty(xmit) || count >= size)
783*4882a593Smuzhiyun 		goto pop_tx_end;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	do {
786*4882a593Smuzhiyun 		int cnt_to_end =
787*4882a593Smuzhiyun 		    CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
788*4882a593Smuzhiyun 		int sz = min(size - count, cnt_to_end);
789*4882a593Smuzhiyun 		pch_uart_hal_write(priv, &xmit->buf[xmit->tail], sz);
790*4882a593Smuzhiyun 		xmit->tail = (xmit->tail + sz) & (UART_XMIT_SIZE - 1);
791*4882a593Smuzhiyun 		count += sz;
792*4882a593Smuzhiyun 	} while (!uart_circ_empty(xmit) && count < size);
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun pop_tx_end:
795*4882a593Smuzhiyun 	dev_dbg(priv->port.dev, "%d characters. Remained %d characters.(%lu)\n",
796*4882a593Smuzhiyun 		 count, size - count, jiffies);
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun 	return count;
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun 
handle_rx_to(struct eg20t_port * priv)801*4882a593Smuzhiyun static int handle_rx_to(struct eg20t_port *priv)
802*4882a593Smuzhiyun {
803*4882a593Smuzhiyun 	struct pch_uart_buffer *buf;
804*4882a593Smuzhiyun 	int rx_size;
805*4882a593Smuzhiyun 	int ret;
806*4882a593Smuzhiyun 	if (!priv->start_rx) {
807*4882a593Smuzhiyun 		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT |
808*4882a593Smuzhiyun 						     PCH_UART_HAL_RX_ERR_INT);
809*4882a593Smuzhiyun 		return 0;
810*4882a593Smuzhiyun 	}
811*4882a593Smuzhiyun 	buf = &priv->rxbuf;
812*4882a593Smuzhiyun 	do {
813*4882a593Smuzhiyun 		rx_size = pch_uart_hal_read(priv, buf->buf, buf->size);
814*4882a593Smuzhiyun 		ret = push_rx(priv, buf->buf, rx_size);
815*4882a593Smuzhiyun 		if (ret)
816*4882a593Smuzhiyun 			return 0;
817*4882a593Smuzhiyun 	} while (rx_size == buf->size);
818*4882a593Smuzhiyun 
819*4882a593Smuzhiyun 	return PCH_UART_HANDLED_RX_INT;
820*4882a593Smuzhiyun }
821*4882a593Smuzhiyun 
handle_rx(struct eg20t_port * priv)822*4882a593Smuzhiyun static int handle_rx(struct eg20t_port *priv)
823*4882a593Smuzhiyun {
824*4882a593Smuzhiyun 	return handle_rx_to(priv);
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun 
dma_handle_rx(struct eg20t_port * priv)827*4882a593Smuzhiyun static int dma_handle_rx(struct eg20t_port *priv)
828*4882a593Smuzhiyun {
829*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
830*4882a593Smuzhiyun 	struct dma_async_tx_descriptor *desc;
831*4882a593Smuzhiyun 	struct scatterlist *sg;
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
834*4882a593Smuzhiyun 	sg = &priv->sg_rx;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	sg_init_table(&priv->sg_rx, 1); /* Initialize SG table */
837*4882a593Smuzhiyun 
838*4882a593Smuzhiyun 	sg_dma_len(sg) = priv->trigger_level;
839*4882a593Smuzhiyun 
840*4882a593Smuzhiyun 	sg_set_page(&priv->sg_rx, virt_to_page(priv->rx_buf_virt),
841*4882a593Smuzhiyun 		     sg_dma_len(sg), offset_in_page(priv->rx_buf_virt));
842*4882a593Smuzhiyun 
843*4882a593Smuzhiyun 	sg_dma_address(sg) = priv->rx_buf_dma;
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	desc = dmaengine_prep_slave_sg(priv->chan_rx,
846*4882a593Smuzhiyun 			sg, 1, DMA_DEV_TO_MEM,
847*4882a593Smuzhiyun 			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 	if (!desc)
850*4882a593Smuzhiyun 		return 0;
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 	priv->desc_rx = desc;
853*4882a593Smuzhiyun 	desc->callback = pch_dma_rx_complete;
854*4882a593Smuzhiyun 	desc->callback_param = priv;
855*4882a593Smuzhiyun 	desc->tx_submit(desc);
856*4882a593Smuzhiyun 	dma_async_issue_pending(priv->chan_rx);
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun 	return PCH_UART_HANDLED_RX_INT;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun 
handle_tx(struct eg20t_port * priv)861*4882a593Smuzhiyun static unsigned int handle_tx(struct eg20t_port *priv)
862*4882a593Smuzhiyun {
863*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
864*4882a593Smuzhiyun 	struct circ_buf *xmit = &port->state->xmit;
865*4882a593Smuzhiyun 	int fifo_size;
866*4882a593Smuzhiyun 	int tx_size;
867*4882a593Smuzhiyun 	int size;
868*4882a593Smuzhiyun 	int tx_empty;
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 	if (!priv->start_tx) {
871*4882a593Smuzhiyun 		dev_info(priv->port.dev, "%s:Tx isn't started. (%lu)\n",
872*4882a593Smuzhiyun 			__func__, jiffies);
873*4882a593Smuzhiyun 		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT);
874*4882a593Smuzhiyun 		priv->tx_empty = 1;
875*4882a593Smuzhiyun 		return 0;
876*4882a593Smuzhiyun 	}
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	fifo_size = max(priv->fifo_size, 1);
879*4882a593Smuzhiyun 	tx_empty = 1;
880*4882a593Smuzhiyun 	if (port->x_char) {
881*4882a593Smuzhiyun 		pch_uart_hal_write(priv, &port->x_char, 1);
882*4882a593Smuzhiyun 		port->icount.tx++;
883*4882a593Smuzhiyun 		port->x_char = 0;
884*4882a593Smuzhiyun 		tx_empty = 0;
885*4882a593Smuzhiyun 		fifo_size--;
886*4882a593Smuzhiyun 	}
887*4882a593Smuzhiyun 	size = min(xmit->head - xmit->tail, fifo_size);
888*4882a593Smuzhiyun 	if (size < 0)
889*4882a593Smuzhiyun 		size = fifo_size;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	tx_size = pop_tx(priv, size);
892*4882a593Smuzhiyun 	if (tx_size > 0) {
893*4882a593Smuzhiyun 		port->icount.tx += tx_size;
894*4882a593Smuzhiyun 		tx_empty = 0;
895*4882a593Smuzhiyun 	}
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	priv->tx_empty = tx_empty;
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun 	if (tx_empty) {
900*4882a593Smuzhiyun 		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT);
901*4882a593Smuzhiyun 		uart_write_wakeup(port);
902*4882a593Smuzhiyun 	}
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun 	return PCH_UART_HANDLED_TX_INT;
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun 
dma_handle_tx(struct eg20t_port * priv)907*4882a593Smuzhiyun static unsigned int dma_handle_tx(struct eg20t_port *priv)
908*4882a593Smuzhiyun {
909*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
910*4882a593Smuzhiyun 	struct circ_buf *xmit = &port->state->xmit;
911*4882a593Smuzhiyun 	struct scatterlist *sg;
912*4882a593Smuzhiyun 	int nent;
913*4882a593Smuzhiyun 	int fifo_size;
914*4882a593Smuzhiyun 	struct dma_async_tx_descriptor *desc;
915*4882a593Smuzhiyun 	int num;
916*4882a593Smuzhiyun 	int i;
917*4882a593Smuzhiyun 	int bytes;
918*4882a593Smuzhiyun 	int size;
919*4882a593Smuzhiyun 	int rem;
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 	if (!priv->start_tx) {
922*4882a593Smuzhiyun 		dev_info(priv->port.dev, "%s:Tx isn't started. (%lu)\n",
923*4882a593Smuzhiyun 			__func__, jiffies);
924*4882a593Smuzhiyun 		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT);
925*4882a593Smuzhiyun 		priv->tx_empty = 1;
926*4882a593Smuzhiyun 		return 0;
927*4882a593Smuzhiyun 	}
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun 	if (priv->tx_dma_use) {
930*4882a593Smuzhiyun 		dev_dbg(priv->port.dev, "%s:Tx is not completed. (%lu)\n",
931*4882a593Smuzhiyun 			__func__, jiffies);
932*4882a593Smuzhiyun 		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT);
933*4882a593Smuzhiyun 		priv->tx_empty = 1;
934*4882a593Smuzhiyun 		return 0;
935*4882a593Smuzhiyun 	}
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	fifo_size = max(priv->fifo_size, 1);
938*4882a593Smuzhiyun 
939*4882a593Smuzhiyun 	if (port->x_char) {
940*4882a593Smuzhiyun 		pch_uart_hal_write(priv, &port->x_char, 1);
941*4882a593Smuzhiyun 		port->icount.tx++;
942*4882a593Smuzhiyun 		port->x_char = 0;
943*4882a593Smuzhiyun 		fifo_size--;
944*4882a593Smuzhiyun 	}
945*4882a593Smuzhiyun 
946*4882a593Smuzhiyun 	bytes = min((int)CIRC_CNT(xmit->head, xmit->tail,
947*4882a593Smuzhiyun 			     UART_XMIT_SIZE), CIRC_CNT_TO_END(xmit->head,
948*4882a593Smuzhiyun 			     xmit->tail, UART_XMIT_SIZE));
949*4882a593Smuzhiyun 	if (!bytes) {
950*4882a593Smuzhiyun 		dev_dbg(priv->port.dev, "%s 0 bytes return\n", __func__);
951*4882a593Smuzhiyun 		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT);
952*4882a593Smuzhiyun 		uart_write_wakeup(port);
953*4882a593Smuzhiyun 		return 0;
954*4882a593Smuzhiyun 	}
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	if (bytes > fifo_size) {
957*4882a593Smuzhiyun 		num = bytes / fifo_size + 1;
958*4882a593Smuzhiyun 		size = fifo_size;
959*4882a593Smuzhiyun 		rem = bytes % fifo_size;
960*4882a593Smuzhiyun 	} else {
961*4882a593Smuzhiyun 		num = 1;
962*4882a593Smuzhiyun 		size = bytes;
963*4882a593Smuzhiyun 		rem = bytes;
964*4882a593Smuzhiyun 	}
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun 	dev_dbg(priv->port.dev, "%s num=%d size=%d rem=%d\n",
967*4882a593Smuzhiyun 		__func__, num, size, rem);
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun 	priv->tx_dma_use = 1;
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun 	priv->sg_tx_p = kmalloc_array(num, sizeof(struct scatterlist), GFP_ATOMIC);
972*4882a593Smuzhiyun 	if (!priv->sg_tx_p) {
973*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__);
974*4882a593Smuzhiyun 		return 0;
975*4882a593Smuzhiyun 	}
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun 	sg_init_table(priv->sg_tx_p, num); /* Initialize SG table */
978*4882a593Smuzhiyun 	sg = priv->sg_tx_p;
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun 	for (i = 0; i < num; i++, sg++) {
981*4882a593Smuzhiyun 		if (i == (num - 1))
982*4882a593Smuzhiyun 			sg_set_page(sg, virt_to_page(xmit->buf),
983*4882a593Smuzhiyun 				    rem, fifo_size * i);
984*4882a593Smuzhiyun 		else
985*4882a593Smuzhiyun 			sg_set_page(sg, virt_to_page(xmit->buf),
986*4882a593Smuzhiyun 				    size, fifo_size * i);
987*4882a593Smuzhiyun 	}
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 	sg = priv->sg_tx_p;
990*4882a593Smuzhiyun 	nent = dma_map_sg(port->dev, sg, num, DMA_TO_DEVICE);
991*4882a593Smuzhiyun 	if (!nent) {
992*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:dma_map_sg Failed\n", __func__);
993*4882a593Smuzhiyun 		return 0;
994*4882a593Smuzhiyun 	}
995*4882a593Smuzhiyun 	priv->orig_nent = num;
996*4882a593Smuzhiyun 	priv->nent = nent;
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 	for (i = 0; i < nent; i++, sg++) {
999*4882a593Smuzhiyun 		sg->offset = (xmit->tail & (UART_XMIT_SIZE - 1)) +
1000*4882a593Smuzhiyun 			      fifo_size * i;
1001*4882a593Smuzhiyun 		sg_dma_address(sg) = (sg_dma_address(sg) &
1002*4882a593Smuzhiyun 				    ~(UART_XMIT_SIZE - 1)) + sg->offset;
1003*4882a593Smuzhiyun 		if (i == (nent - 1))
1004*4882a593Smuzhiyun 			sg_dma_len(sg) = rem;
1005*4882a593Smuzhiyun 		else
1006*4882a593Smuzhiyun 			sg_dma_len(sg) = size;
1007*4882a593Smuzhiyun 	}
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 	desc = dmaengine_prep_slave_sg(priv->chan_tx,
1010*4882a593Smuzhiyun 					priv->sg_tx_p, nent, DMA_MEM_TO_DEV,
1011*4882a593Smuzhiyun 					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1012*4882a593Smuzhiyun 	if (!desc) {
1013*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s:dmaengine_prep_slave_sg Failed\n",
1014*4882a593Smuzhiyun 			__func__);
1015*4882a593Smuzhiyun 		return 0;
1016*4882a593Smuzhiyun 	}
1017*4882a593Smuzhiyun 	dma_sync_sg_for_device(port->dev, priv->sg_tx_p, nent, DMA_TO_DEVICE);
1018*4882a593Smuzhiyun 	priv->desc_tx = desc;
1019*4882a593Smuzhiyun 	desc->callback = pch_dma_tx_complete;
1020*4882a593Smuzhiyun 	desc->callback_param = priv;
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	desc->tx_submit(desc);
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun 	dma_async_issue_pending(priv->chan_tx);
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	return PCH_UART_HANDLED_TX_INT;
1027*4882a593Smuzhiyun }
1028*4882a593Smuzhiyun 
pch_uart_err_ir(struct eg20t_port * priv,unsigned int lsr)1029*4882a593Smuzhiyun static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr)
1030*4882a593Smuzhiyun {
1031*4882a593Smuzhiyun 	struct uart_port *port = &priv->port;
1032*4882a593Smuzhiyun 	struct tty_struct *tty = tty_port_tty_get(&port->state->port);
1033*4882a593Smuzhiyun 	char   *error_msg[5] = {};
1034*4882a593Smuzhiyun 	int    i = 0;
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 	if (lsr & PCH_UART_LSR_ERR)
1037*4882a593Smuzhiyun 		error_msg[i++] = "Error data in FIFO\n";
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 	if (lsr & UART_LSR_FE) {
1040*4882a593Smuzhiyun 		port->icount.frame++;
1041*4882a593Smuzhiyun 		error_msg[i++] = "  Framing Error\n";
1042*4882a593Smuzhiyun 	}
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun 	if (lsr & UART_LSR_PE) {
1045*4882a593Smuzhiyun 		port->icount.parity++;
1046*4882a593Smuzhiyun 		error_msg[i++] = "  Parity Error\n";
1047*4882a593Smuzhiyun 	}
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 	if (lsr & UART_LSR_OE) {
1050*4882a593Smuzhiyun 		port->icount.overrun++;
1051*4882a593Smuzhiyun 		error_msg[i++] = "  Overrun Error\n";
1052*4882a593Smuzhiyun 	}
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 	if (tty == NULL) {
1055*4882a593Smuzhiyun 		for (i = 0; error_msg[i] != NULL; i++)
1056*4882a593Smuzhiyun 			dev_err(&priv->pdev->dev, error_msg[i]);
1057*4882a593Smuzhiyun 	} else {
1058*4882a593Smuzhiyun 		tty_kref_put(tty);
1059*4882a593Smuzhiyun 	}
1060*4882a593Smuzhiyun }
1061*4882a593Smuzhiyun 
pch_uart_interrupt(int irq,void * dev_id)1062*4882a593Smuzhiyun static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
1063*4882a593Smuzhiyun {
1064*4882a593Smuzhiyun 	struct eg20t_port *priv = dev_id;
1065*4882a593Smuzhiyun 	unsigned int handled;
1066*4882a593Smuzhiyun 	u8 lsr;
1067*4882a593Smuzhiyun 	int ret = 0;
1068*4882a593Smuzhiyun 	unsigned char iid;
1069*4882a593Smuzhiyun 	unsigned long flags;
1070*4882a593Smuzhiyun 	int next = 1;
1071*4882a593Smuzhiyun 	u8 msr;
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->lock, flags);
1074*4882a593Smuzhiyun 	handled = 0;
1075*4882a593Smuzhiyun 	while (next) {
1076*4882a593Smuzhiyun 		iid = pch_uart_hal_get_iid(priv);
1077*4882a593Smuzhiyun 		if (iid & PCH_UART_IIR_IP) /* No Interrupt */
1078*4882a593Smuzhiyun 			break;
1079*4882a593Smuzhiyun 		switch (iid) {
1080*4882a593Smuzhiyun 		case PCH_UART_IID_RLS:	/* Receiver Line Status */
1081*4882a593Smuzhiyun 			lsr = pch_uart_hal_get_line_status(priv);
1082*4882a593Smuzhiyun 			if (lsr & (PCH_UART_LSR_ERR | UART_LSR_FE |
1083*4882a593Smuzhiyun 						UART_LSR_PE | UART_LSR_OE)) {
1084*4882a593Smuzhiyun 				pch_uart_err_ir(priv, lsr);
1085*4882a593Smuzhiyun 				ret = PCH_UART_HANDLED_RX_ERR_INT;
1086*4882a593Smuzhiyun 			} else {
1087*4882a593Smuzhiyun 				ret = PCH_UART_HANDLED_LS_INT;
1088*4882a593Smuzhiyun 			}
1089*4882a593Smuzhiyun 			break;
1090*4882a593Smuzhiyun 		case PCH_UART_IID_RDR:	/* Received Data Ready */
1091*4882a593Smuzhiyun 			if (priv->use_dma) {
1092*4882a593Smuzhiyun 				pch_uart_hal_disable_interrupt(priv,
1093*4882a593Smuzhiyun 						PCH_UART_HAL_RX_INT |
1094*4882a593Smuzhiyun 						PCH_UART_HAL_RX_ERR_INT);
1095*4882a593Smuzhiyun 				ret = dma_handle_rx(priv);
1096*4882a593Smuzhiyun 				if (!ret)
1097*4882a593Smuzhiyun 					pch_uart_hal_enable_interrupt(priv,
1098*4882a593Smuzhiyun 						PCH_UART_HAL_RX_INT |
1099*4882a593Smuzhiyun 						PCH_UART_HAL_RX_ERR_INT);
1100*4882a593Smuzhiyun 			} else {
1101*4882a593Smuzhiyun 				ret = handle_rx(priv);
1102*4882a593Smuzhiyun 			}
1103*4882a593Smuzhiyun 			break;
1104*4882a593Smuzhiyun 		case PCH_UART_IID_RDR_TO:	/* Received Data Ready
1105*4882a593Smuzhiyun 						   (FIFO Timeout) */
1106*4882a593Smuzhiyun 			ret = handle_rx_to(priv);
1107*4882a593Smuzhiyun 			break;
1108*4882a593Smuzhiyun 		case PCH_UART_IID_THRE:	/* Transmitter Holding Register
1109*4882a593Smuzhiyun 						   Empty */
1110*4882a593Smuzhiyun 			if (priv->use_dma)
1111*4882a593Smuzhiyun 				ret = dma_handle_tx(priv);
1112*4882a593Smuzhiyun 			else
1113*4882a593Smuzhiyun 				ret = handle_tx(priv);
1114*4882a593Smuzhiyun 			break;
1115*4882a593Smuzhiyun 		case PCH_UART_IID_MS:	/* Modem Status */
1116*4882a593Smuzhiyun 			msr = pch_uart_hal_get_modem(priv);
1117*4882a593Smuzhiyun 			next = 0; /* MS ir prioirty is the lowest. So, MS ir
1118*4882a593Smuzhiyun 				     means final interrupt */
1119*4882a593Smuzhiyun 			if ((msr & UART_MSR_ANY_DELTA) == 0)
1120*4882a593Smuzhiyun 				break;
1121*4882a593Smuzhiyun 			ret |= PCH_UART_HANDLED_MS_INT;
1122*4882a593Smuzhiyun 			break;
1123*4882a593Smuzhiyun 		default:	/* Never junp to this label */
1124*4882a593Smuzhiyun 			dev_err(priv->port.dev, "%s:iid=%02x (%lu)\n", __func__,
1125*4882a593Smuzhiyun 				iid, jiffies);
1126*4882a593Smuzhiyun 			ret = -1;
1127*4882a593Smuzhiyun 			next = 0;
1128*4882a593Smuzhiyun 			break;
1129*4882a593Smuzhiyun 		}
1130*4882a593Smuzhiyun 		handled |= (unsigned int)ret;
1131*4882a593Smuzhiyun 	}
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->lock, flags);
1134*4882a593Smuzhiyun 	return IRQ_RETVAL(handled);
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun 
1137*4882a593Smuzhiyun /* This function tests whether the transmitter fifo and shifter for the port
1138*4882a593Smuzhiyun 						described by 'port' is empty. */
pch_uart_tx_empty(struct uart_port * port)1139*4882a593Smuzhiyun static unsigned int pch_uart_tx_empty(struct uart_port *port)
1140*4882a593Smuzhiyun {
1141*4882a593Smuzhiyun 	struct eg20t_port *priv;
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1144*4882a593Smuzhiyun 	if (priv->tx_empty)
1145*4882a593Smuzhiyun 		return TIOCSER_TEMT;
1146*4882a593Smuzhiyun 	else
1147*4882a593Smuzhiyun 		return 0;
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun /* Returns the current state of modem control inputs. */
pch_uart_get_mctrl(struct uart_port * port)1151*4882a593Smuzhiyun static unsigned int pch_uart_get_mctrl(struct uart_port *port)
1152*4882a593Smuzhiyun {
1153*4882a593Smuzhiyun 	struct eg20t_port *priv;
1154*4882a593Smuzhiyun 	u8 modem;
1155*4882a593Smuzhiyun 	unsigned int ret = 0;
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1158*4882a593Smuzhiyun 	modem = pch_uart_hal_get_modem(priv);
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 	if (modem & UART_MSR_DCD)
1161*4882a593Smuzhiyun 		ret |= TIOCM_CAR;
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun 	if (modem & UART_MSR_RI)
1164*4882a593Smuzhiyun 		ret |= TIOCM_RNG;
1165*4882a593Smuzhiyun 
1166*4882a593Smuzhiyun 	if (modem & UART_MSR_DSR)
1167*4882a593Smuzhiyun 		ret |= TIOCM_DSR;
1168*4882a593Smuzhiyun 
1169*4882a593Smuzhiyun 	if (modem & UART_MSR_CTS)
1170*4882a593Smuzhiyun 		ret |= TIOCM_CTS;
1171*4882a593Smuzhiyun 
1172*4882a593Smuzhiyun 	return ret;
1173*4882a593Smuzhiyun }
1174*4882a593Smuzhiyun 
pch_uart_set_mctrl(struct uart_port * port,unsigned int mctrl)1175*4882a593Smuzhiyun static void pch_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
1176*4882a593Smuzhiyun {
1177*4882a593Smuzhiyun 	u32 mcr = 0;
1178*4882a593Smuzhiyun 	struct eg20t_port *priv = container_of(port, struct eg20t_port, port);
1179*4882a593Smuzhiyun 
1180*4882a593Smuzhiyun 	if (mctrl & TIOCM_DTR)
1181*4882a593Smuzhiyun 		mcr |= UART_MCR_DTR;
1182*4882a593Smuzhiyun 	if (mctrl & TIOCM_RTS)
1183*4882a593Smuzhiyun 		mcr |= UART_MCR_RTS;
1184*4882a593Smuzhiyun 	if (mctrl & TIOCM_LOOP)
1185*4882a593Smuzhiyun 		mcr |= UART_MCR_LOOP;
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 	if (priv->mcr & UART_MCR_AFE)
1188*4882a593Smuzhiyun 		mcr |= UART_MCR_AFE;
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun 	if (mctrl)
1191*4882a593Smuzhiyun 		iowrite8(mcr, priv->membase + UART_MCR);
1192*4882a593Smuzhiyun }
1193*4882a593Smuzhiyun 
pch_uart_stop_tx(struct uart_port * port)1194*4882a593Smuzhiyun static void pch_uart_stop_tx(struct uart_port *port)
1195*4882a593Smuzhiyun {
1196*4882a593Smuzhiyun 	struct eg20t_port *priv;
1197*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1198*4882a593Smuzhiyun 	priv->start_tx = 0;
1199*4882a593Smuzhiyun 	priv->tx_dma_use = 0;
1200*4882a593Smuzhiyun }
1201*4882a593Smuzhiyun 
pch_uart_start_tx(struct uart_port * port)1202*4882a593Smuzhiyun static void pch_uart_start_tx(struct uart_port *port)
1203*4882a593Smuzhiyun {
1204*4882a593Smuzhiyun 	struct eg20t_port *priv;
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1207*4882a593Smuzhiyun 
1208*4882a593Smuzhiyun 	if (priv->use_dma) {
1209*4882a593Smuzhiyun 		if (priv->tx_dma_use) {
1210*4882a593Smuzhiyun 			dev_dbg(priv->port.dev, "%s : Tx DMA is NOT empty.\n",
1211*4882a593Smuzhiyun 				__func__);
1212*4882a593Smuzhiyun 			return;
1213*4882a593Smuzhiyun 		}
1214*4882a593Smuzhiyun 	}
1215*4882a593Smuzhiyun 
1216*4882a593Smuzhiyun 	priv->start_tx = 1;
1217*4882a593Smuzhiyun 	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_TX_INT);
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun 
pch_uart_stop_rx(struct uart_port * port)1220*4882a593Smuzhiyun static void pch_uart_stop_rx(struct uart_port *port)
1221*4882a593Smuzhiyun {
1222*4882a593Smuzhiyun 	struct eg20t_port *priv;
1223*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1224*4882a593Smuzhiyun 	priv->start_rx = 0;
1225*4882a593Smuzhiyun 	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT |
1226*4882a593Smuzhiyun 					     PCH_UART_HAL_RX_ERR_INT);
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun /* Enable the modem status interrupts. */
pch_uart_enable_ms(struct uart_port * port)1230*4882a593Smuzhiyun static void pch_uart_enable_ms(struct uart_port *port)
1231*4882a593Smuzhiyun {
1232*4882a593Smuzhiyun 	struct eg20t_port *priv;
1233*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1234*4882a593Smuzhiyun 	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_MS_INT);
1235*4882a593Smuzhiyun }
1236*4882a593Smuzhiyun 
1237*4882a593Smuzhiyun /* Control the transmission of a break signal. */
pch_uart_break_ctl(struct uart_port * port,int ctl)1238*4882a593Smuzhiyun static void pch_uart_break_ctl(struct uart_port *port, int ctl)
1239*4882a593Smuzhiyun {
1240*4882a593Smuzhiyun 	struct eg20t_port *priv;
1241*4882a593Smuzhiyun 	unsigned long flags;
1242*4882a593Smuzhiyun 
1243*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1244*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->lock, flags);
1245*4882a593Smuzhiyun 	pch_uart_hal_set_break(priv, ctl);
1246*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->lock, flags);
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun /* Grab any interrupt resources and initialise any low level driver state. */
pch_uart_startup(struct uart_port * port)1250*4882a593Smuzhiyun static int pch_uart_startup(struct uart_port *port)
1251*4882a593Smuzhiyun {
1252*4882a593Smuzhiyun 	struct eg20t_port *priv;
1253*4882a593Smuzhiyun 	int ret;
1254*4882a593Smuzhiyun 	int fifo_size;
1255*4882a593Smuzhiyun 	int trigger_level;
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1258*4882a593Smuzhiyun 	priv->tx_empty = 1;
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 	if (port->uartclk)
1261*4882a593Smuzhiyun 		priv->uartclk = port->uartclk;
1262*4882a593Smuzhiyun 	else
1263*4882a593Smuzhiyun 		port->uartclk = priv->uartclk;
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun 	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
1266*4882a593Smuzhiyun 	ret = pch_uart_hal_set_line(priv, default_baud,
1267*4882a593Smuzhiyun 			      PCH_UART_HAL_PARITY_NONE, PCH_UART_HAL_8BIT,
1268*4882a593Smuzhiyun 			      PCH_UART_HAL_STB1);
1269*4882a593Smuzhiyun 	if (ret)
1270*4882a593Smuzhiyun 		return ret;
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun 	switch (priv->fifo_size) {
1273*4882a593Smuzhiyun 	case 256:
1274*4882a593Smuzhiyun 		fifo_size = PCH_UART_HAL_FIFO256;
1275*4882a593Smuzhiyun 		break;
1276*4882a593Smuzhiyun 	case 64:
1277*4882a593Smuzhiyun 		fifo_size = PCH_UART_HAL_FIFO64;
1278*4882a593Smuzhiyun 		break;
1279*4882a593Smuzhiyun 	case 16:
1280*4882a593Smuzhiyun 		fifo_size = PCH_UART_HAL_FIFO16;
1281*4882a593Smuzhiyun 		break;
1282*4882a593Smuzhiyun 	case 1:
1283*4882a593Smuzhiyun 	default:
1284*4882a593Smuzhiyun 		fifo_size = PCH_UART_HAL_FIFO_DIS;
1285*4882a593Smuzhiyun 		break;
1286*4882a593Smuzhiyun 	}
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun 	switch (priv->trigger) {
1289*4882a593Smuzhiyun 	case PCH_UART_HAL_TRIGGER1:
1290*4882a593Smuzhiyun 		trigger_level = 1;
1291*4882a593Smuzhiyun 		break;
1292*4882a593Smuzhiyun 	case PCH_UART_HAL_TRIGGER_L:
1293*4882a593Smuzhiyun 		trigger_level = priv->fifo_size / 4;
1294*4882a593Smuzhiyun 		break;
1295*4882a593Smuzhiyun 	case PCH_UART_HAL_TRIGGER_M:
1296*4882a593Smuzhiyun 		trigger_level = priv->fifo_size / 2;
1297*4882a593Smuzhiyun 		break;
1298*4882a593Smuzhiyun 	case PCH_UART_HAL_TRIGGER_H:
1299*4882a593Smuzhiyun 	default:
1300*4882a593Smuzhiyun 		trigger_level = priv->fifo_size - (priv->fifo_size / 8);
1301*4882a593Smuzhiyun 		break;
1302*4882a593Smuzhiyun 	}
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun 	priv->trigger_level = trigger_level;
1305*4882a593Smuzhiyun 	ret = pch_uart_hal_set_fifo(priv, PCH_UART_HAL_DMA_MODE0,
1306*4882a593Smuzhiyun 				    fifo_size, priv->trigger);
1307*4882a593Smuzhiyun 	if (ret < 0)
1308*4882a593Smuzhiyun 		return ret;
1309*4882a593Smuzhiyun 
1310*4882a593Smuzhiyun 	ret = request_irq(priv->port.irq, pch_uart_interrupt, IRQF_SHARED,
1311*4882a593Smuzhiyun 			priv->irq_name, priv);
1312*4882a593Smuzhiyun 	if (ret < 0)
1313*4882a593Smuzhiyun 		return ret;
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun 	if (priv->use_dma)
1316*4882a593Smuzhiyun 		pch_request_dma(port);
1317*4882a593Smuzhiyun 
1318*4882a593Smuzhiyun 	priv->start_rx = 1;
1319*4882a593Smuzhiyun 	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT |
1320*4882a593Smuzhiyun 					    PCH_UART_HAL_RX_ERR_INT);
1321*4882a593Smuzhiyun 	uart_update_timeout(port, CS8, default_baud);
1322*4882a593Smuzhiyun 
1323*4882a593Smuzhiyun 	return 0;
1324*4882a593Smuzhiyun }
1325*4882a593Smuzhiyun 
pch_uart_shutdown(struct uart_port * port)1326*4882a593Smuzhiyun static void pch_uart_shutdown(struct uart_port *port)
1327*4882a593Smuzhiyun {
1328*4882a593Smuzhiyun 	struct eg20t_port *priv;
1329*4882a593Smuzhiyun 	int ret;
1330*4882a593Smuzhiyun 
1331*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1332*4882a593Smuzhiyun 	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
1333*4882a593Smuzhiyun 	pch_uart_hal_fifo_reset(priv, PCH_UART_HAL_CLR_ALL_FIFO);
1334*4882a593Smuzhiyun 	ret = pch_uart_hal_set_fifo(priv, PCH_UART_HAL_DMA_MODE0,
1335*4882a593Smuzhiyun 			      PCH_UART_HAL_FIFO_DIS, PCH_UART_HAL_TRIGGER1);
1336*4882a593Smuzhiyun 	if (ret)
1337*4882a593Smuzhiyun 		dev_err(priv->port.dev,
1338*4882a593Smuzhiyun 			"pch_uart_hal_set_fifo Failed(ret=%d)\n", ret);
1339*4882a593Smuzhiyun 
1340*4882a593Smuzhiyun 	pch_free_dma(port);
1341*4882a593Smuzhiyun 
1342*4882a593Smuzhiyun 	free_irq(priv->port.irq, priv);
1343*4882a593Smuzhiyun }
1344*4882a593Smuzhiyun 
1345*4882a593Smuzhiyun /* Change the port parameters, including word length, parity, stop
1346*4882a593Smuzhiyun  *bits.  Update read_status_mask and ignore_status_mask to indicate
1347*4882a593Smuzhiyun  *the types of events we are interested in receiving.  */
pch_uart_set_termios(struct uart_port * port,struct ktermios * termios,struct ktermios * old)1348*4882a593Smuzhiyun static void pch_uart_set_termios(struct uart_port *port,
1349*4882a593Smuzhiyun 				 struct ktermios *termios, struct ktermios *old)
1350*4882a593Smuzhiyun {
1351*4882a593Smuzhiyun 	int rtn;
1352*4882a593Smuzhiyun 	unsigned int baud, parity, bits, stb;
1353*4882a593Smuzhiyun 	struct eg20t_port *priv;
1354*4882a593Smuzhiyun 	unsigned long flags;
1355*4882a593Smuzhiyun 
1356*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1357*4882a593Smuzhiyun 	switch (termios->c_cflag & CSIZE) {
1358*4882a593Smuzhiyun 	case CS5:
1359*4882a593Smuzhiyun 		bits = PCH_UART_HAL_5BIT;
1360*4882a593Smuzhiyun 		break;
1361*4882a593Smuzhiyun 	case CS6:
1362*4882a593Smuzhiyun 		bits = PCH_UART_HAL_6BIT;
1363*4882a593Smuzhiyun 		break;
1364*4882a593Smuzhiyun 	case CS7:
1365*4882a593Smuzhiyun 		bits = PCH_UART_HAL_7BIT;
1366*4882a593Smuzhiyun 		break;
1367*4882a593Smuzhiyun 	default:		/* CS8 */
1368*4882a593Smuzhiyun 		bits = PCH_UART_HAL_8BIT;
1369*4882a593Smuzhiyun 		break;
1370*4882a593Smuzhiyun 	}
1371*4882a593Smuzhiyun 	if (termios->c_cflag & CSTOPB)
1372*4882a593Smuzhiyun 		stb = PCH_UART_HAL_STB2;
1373*4882a593Smuzhiyun 	else
1374*4882a593Smuzhiyun 		stb = PCH_UART_HAL_STB1;
1375*4882a593Smuzhiyun 
1376*4882a593Smuzhiyun 	if (termios->c_cflag & PARENB) {
1377*4882a593Smuzhiyun 		if (termios->c_cflag & PARODD)
1378*4882a593Smuzhiyun 			parity = PCH_UART_HAL_PARITY_ODD;
1379*4882a593Smuzhiyun 		else
1380*4882a593Smuzhiyun 			parity = PCH_UART_HAL_PARITY_EVEN;
1381*4882a593Smuzhiyun 
1382*4882a593Smuzhiyun 	} else
1383*4882a593Smuzhiyun 		parity = PCH_UART_HAL_PARITY_NONE;
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun 	/* Only UART0 has auto hardware flow function */
1386*4882a593Smuzhiyun 	if ((termios->c_cflag & CRTSCTS) && (priv->fifo_size == 256))
1387*4882a593Smuzhiyun 		priv->mcr |= UART_MCR_AFE;
1388*4882a593Smuzhiyun 	else
1389*4882a593Smuzhiyun 		priv->mcr &= ~UART_MCR_AFE;
1390*4882a593Smuzhiyun 
1391*4882a593Smuzhiyun 	termios->c_cflag &= ~CMSPAR; /* Mark/Space parity is not supported */
1392*4882a593Smuzhiyun 
1393*4882a593Smuzhiyun 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
1394*4882a593Smuzhiyun 
1395*4882a593Smuzhiyun 	spin_lock_irqsave(&priv->lock, flags);
1396*4882a593Smuzhiyun 	spin_lock(&port->lock);
1397*4882a593Smuzhiyun 
1398*4882a593Smuzhiyun 	uart_update_timeout(port, termios->c_cflag, baud);
1399*4882a593Smuzhiyun 	rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb);
1400*4882a593Smuzhiyun 	if (rtn)
1401*4882a593Smuzhiyun 		goto out;
1402*4882a593Smuzhiyun 
1403*4882a593Smuzhiyun 	pch_uart_set_mctrl(&priv->port, priv->port.mctrl);
1404*4882a593Smuzhiyun 	/* Don't rewrite B0 */
1405*4882a593Smuzhiyun 	if (tty_termios_baud_rate(termios))
1406*4882a593Smuzhiyun 		tty_termios_encode_baud_rate(termios, baud, baud);
1407*4882a593Smuzhiyun 
1408*4882a593Smuzhiyun out:
1409*4882a593Smuzhiyun 	spin_unlock(&port->lock);
1410*4882a593Smuzhiyun 	spin_unlock_irqrestore(&priv->lock, flags);
1411*4882a593Smuzhiyun }
1412*4882a593Smuzhiyun 
pch_uart_type(struct uart_port * port)1413*4882a593Smuzhiyun static const char *pch_uart_type(struct uart_port *port)
1414*4882a593Smuzhiyun {
1415*4882a593Smuzhiyun 	return KBUILD_MODNAME;
1416*4882a593Smuzhiyun }
1417*4882a593Smuzhiyun 
pch_uart_release_port(struct uart_port * port)1418*4882a593Smuzhiyun static void pch_uart_release_port(struct uart_port *port)
1419*4882a593Smuzhiyun {
1420*4882a593Smuzhiyun 	struct eg20t_port *priv;
1421*4882a593Smuzhiyun 
1422*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1423*4882a593Smuzhiyun 	pci_iounmap(priv->pdev, priv->membase);
1424*4882a593Smuzhiyun 	pci_release_regions(priv->pdev);
1425*4882a593Smuzhiyun }
1426*4882a593Smuzhiyun 
pch_uart_request_port(struct uart_port * port)1427*4882a593Smuzhiyun static int pch_uart_request_port(struct uart_port *port)
1428*4882a593Smuzhiyun {
1429*4882a593Smuzhiyun 	struct eg20t_port *priv;
1430*4882a593Smuzhiyun 	int ret;
1431*4882a593Smuzhiyun 	void __iomem *membase;
1432*4882a593Smuzhiyun 
1433*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1434*4882a593Smuzhiyun 	ret = pci_request_regions(priv->pdev, KBUILD_MODNAME);
1435*4882a593Smuzhiyun 	if (ret < 0)
1436*4882a593Smuzhiyun 		return -EBUSY;
1437*4882a593Smuzhiyun 
1438*4882a593Smuzhiyun 	membase = pci_iomap(priv->pdev, 1, 0);
1439*4882a593Smuzhiyun 	if (!membase) {
1440*4882a593Smuzhiyun 		pci_release_regions(priv->pdev);
1441*4882a593Smuzhiyun 		return -EBUSY;
1442*4882a593Smuzhiyun 	}
1443*4882a593Smuzhiyun 	priv->membase = port->membase = membase;
1444*4882a593Smuzhiyun 
1445*4882a593Smuzhiyun 	return 0;
1446*4882a593Smuzhiyun }
1447*4882a593Smuzhiyun 
pch_uart_config_port(struct uart_port * port,int type)1448*4882a593Smuzhiyun static void pch_uart_config_port(struct uart_port *port, int type)
1449*4882a593Smuzhiyun {
1450*4882a593Smuzhiyun 	struct eg20t_port *priv;
1451*4882a593Smuzhiyun 
1452*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1453*4882a593Smuzhiyun 	if (type & UART_CONFIG_TYPE) {
1454*4882a593Smuzhiyun 		port->type = priv->port_type;
1455*4882a593Smuzhiyun 		pch_uart_request_port(port);
1456*4882a593Smuzhiyun 	}
1457*4882a593Smuzhiyun }
1458*4882a593Smuzhiyun 
pch_uart_verify_port(struct uart_port * port,struct serial_struct * serinfo)1459*4882a593Smuzhiyun static int pch_uart_verify_port(struct uart_port *port,
1460*4882a593Smuzhiyun 				struct serial_struct *serinfo)
1461*4882a593Smuzhiyun {
1462*4882a593Smuzhiyun 	struct eg20t_port *priv;
1463*4882a593Smuzhiyun 
1464*4882a593Smuzhiyun 	priv = container_of(port, struct eg20t_port, port);
1465*4882a593Smuzhiyun 	if (serinfo->flags & UPF_LOW_LATENCY) {
1466*4882a593Smuzhiyun 		dev_info(priv->port.dev,
1467*4882a593Smuzhiyun 			"PCH UART : Use PIO Mode (without DMA)\n");
1468*4882a593Smuzhiyun 		priv->use_dma = 0;
1469*4882a593Smuzhiyun 		serinfo->flags &= ~UPF_LOW_LATENCY;
1470*4882a593Smuzhiyun 	} else {
1471*4882a593Smuzhiyun #ifndef CONFIG_PCH_DMA
1472*4882a593Smuzhiyun 		dev_err(priv->port.dev, "%s : PCH DMA is not Loaded.\n",
1473*4882a593Smuzhiyun 			__func__);
1474*4882a593Smuzhiyun 		return -EOPNOTSUPP;
1475*4882a593Smuzhiyun #endif
1476*4882a593Smuzhiyun 		if (!priv->use_dma) {
1477*4882a593Smuzhiyun 			pch_request_dma(port);
1478*4882a593Smuzhiyun 			if (priv->chan_rx)
1479*4882a593Smuzhiyun 				priv->use_dma = 1;
1480*4882a593Smuzhiyun 		}
1481*4882a593Smuzhiyun 		dev_info(priv->port.dev, "PCH UART: %s\n",
1482*4882a593Smuzhiyun 				priv->use_dma ?
1483*4882a593Smuzhiyun 				"Use DMA Mode" : "No DMA");
1484*4882a593Smuzhiyun 	}
1485*4882a593Smuzhiyun 
1486*4882a593Smuzhiyun 	return 0;
1487*4882a593Smuzhiyun }
1488*4882a593Smuzhiyun 
1489*4882a593Smuzhiyun #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_PCH_UART_CONSOLE)
1490*4882a593Smuzhiyun /*
1491*4882a593Smuzhiyun  *	Wait for transmitter & holding register to empty
1492*4882a593Smuzhiyun  */
wait_for_xmitr(struct eg20t_port * up,int bits)1493*4882a593Smuzhiyun static void wait_for_xmitr(struct eg20t_port *up, int bits)
1494*4882a593Smuzhiyun {
1495*4882a593Smuzhiyun 	unsigned int status, tmout = 10000;
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 	/* Wait up to 10ms for the character(s) to be sent. */
1498*4882a593Smuzhiyun 	for (;;) {
1499*4882a593Smuzhiyun 		status = ioread8(up->membase + UART_LSR);
1500*4882a593Smuzhiyun 
1501*4882a593Smuzhiyun 		if ((status & bits) == bits)
1502*4882a593Smuzhiyun 			break;
1503*4882a593Smuzhiyun 		if (--tmout == 0)
1504*4882a593Smuzhiyun 			break;
1505*4882a593Smuzhiyun 		udelay(1);
1506*4882a593Smuzhiyun 	}
1507*4882a593Smuzhiyun 
1508*4882a593Smuzhiyun 	/* Wait up to 1s for flow control if necessary */
1509*4882a593Smuzhiyun 	if (up->port.flags & UPF_CONS_FLOW) {
1510*4882a593Smuzhiyun 		unsigned int tmout;
1511*4882a593Smuzhiyun 		for (tmout = 1000000; tmout; tmout--) {
1512*4882a593Smuzhiyun 			unsigned int msr = ioread8(up->membase + UART_MSR);
1513*4882a593Smuzhiyun 			if (msr & UART_MSR_CTS)
1514*4882a593Smuzhiyun 				break;
1515*4882a593Smuzhiyun 			udelay(1);
1516*4882a593Smuzhiyun 			touch_nmi_watchdog();
1517*4882a593Smuzhiyun 		}
1518*4882a593Smuzhiyun 	}
1519*4882a593Smuzhiyun }
1520*4882a593Smuzhiyun #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_PCH_UART_CONSOLE */
1521*4882a593Smuzhiyun 
1522*4882a593Smuzhiyun #ifdef CONFIG_CONSOLE_POLL
1523*4882a593Smuzhiyun /*
1524*4882a593Smuzhiyun  * Console polling routines for communicate via uart while
1525*4882a593Smuzhiyun  * in an interrupt or debug context.
1526*4882a593Smuzhiyun  */
pch_uart_get_poll_char(struct uart_port * port)1527*4882a593Smuzhiyun static int pch_uart_get_poll_char(struct uart_port *port)
1528*4882a593Smuzhiyun {
1529*4882a593Smuzhiyun 	struct eg20t_port *priv =
1530*4882a593Smuzhiyun 		container_of(port, struct eg20t_port, port);
1531*4882a593Smuzhiyun 	u8 lsr = ioread8(priv->membase + UART_LSR);
1532*4882a593Smuzhiyun 
1533*4882a593Smuzhiyun 	if (!(lsr & UART_LSR_DR))
1534*4882a593Smuzhiyun 		return NO_POLL_CHAR;
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 	return ioread8(priv->membase + PCH_UART_RBR);
1537*4882a593Smuzhiyun }
1538*4882a593Smuzhiyun 
1539*4882a593Smuzhiyun 
pch_uart_put_poll_char(struct uart_port * port,unsigned char c)1540*4882a593Smuzhiyun static void pch_uart_put_poll_char(struct uart_port *port,
1541*4882a593Smuzhiyun 			 unsigned char c)
1542*4882a593Smuzhiyun {
1543*4882a593Smuzhiyun 	unsigned int ier;
1544*4882a593Smuzhiyun 	struct eg20t_port *priv =
1545*4882a593Smuzhiyun 		container_of(port, struct eg20t_port, port);
1546*4882a593Smuzhiyun 
1547*4882a593Smuzhiyun 	/*
1548*4882a593Smuzhiyun 	 * First save the IER then disable the interrupts
1549*4882a593Smuzhiyun 	 */
1550*4882a593Smuzhiyun 	ier = ioread8(priv->membase + UART_IER);
1551*4882a593Smuzhiyun 	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun 	wait_for_xmitr(priv, UART_LSR_THRE);
1554*4882a593Smuzhiyun 	/*
1555*4882a593Smuzhiyun 	 * Send the character out.
1556*4882a593Smuzhiyun 	 */
1557*4882a593Smuzhiyun 	iowrite8(c, priv->membase + PCH_UART_THR);
1558*4882a593Smuzhiyun 
1559*4882a593Smuzhiyun 	/*
1560*4882a593Smuzhiyun 	 * Finally, wait for transmitter to become empty
1561*4882a593Smuzhiyun 	 * and restore the IER
1562*4882a593Smuzhiyun 	 */
1563*4882a593Smuzhiyun 	wait_for_xmitr(priv, BOTH_EMPTY);
1564*4882a593Smuzhiyun 	iowrite8(ier, priv->membase + UART_IER);
1565*4882a593Smuzhiyun }
1566*4882a593Smuzhiyun #endif /* CONFIG_CONSOLE_POLL */
1567*4882a593Smuzhiyun 
1568*4882a593Smuzhiyun static const struct uart_ops pch_uart_ops = {
1569*4882a593Smuzhiyun 	.tx_empty = pch_uart_tx_empty,
1570*4882a593Smuzhiyun 	.set_mctrl = pch_uart_set_mctrl,
1571*4882a593Smuzhiyun 	.get_mctrl = pch_uart_get_mctrl,
1572*4882a593Smuzhiyun 	.stop_tx = pch_uart_stop_tx,
1573*4882a593Smuzhiyun 	.start_tx = pch_uart_start_tx,
1574*4882a593Smuzhiyun 	.stop_rx = pch_uart_stop_rx,
1575*4882a593Smuzhiyun 	.enable_ms = pch_uart_enable_ms,
1576*4882a593Smuzhiyun 	.break_ctl = pch_uart_break_ctl,
1577*4882a593Smuzhiyun 	.startup = pch_uart_startup,
1578*4882a593Smuzhiyun 	.shutdown = pch_uart_shutdown,
1579*4882a593Smuzhiyun 	.set_termios = pch_uart_set_termios,
1580*4882a593Smuzhiyun /*	.pm		= pch_uart_pm,		Not supported yet */
1581*4882a593Smuzhiyun 	.type = pch_uart_type,
1582*4882a593Smuzhiyun 	.release_port = pch_uart_release_port,
1583*4882a593Smuzhiyun 	.request_port = pch_uart_request_port,
1584*4882a593Smuzhiyun 	.config_port = pch_uart_config_port,
1585*4882a593Smuzhiyun 	.verify_port = pch_uart_verify_port,
1586*4882a593Smuzhiyun #ifdef CONFIG_CONSOLE_POLL
1587*4882a593Smuzhiyun 	.poll_get_char = pch_uart_get_poll_char,
1588*4882a593Smuzhiyun 	.poll_put_char = pch_uart_put_poll_char,
1589*4882a593Smuzhiyun #endif
1590*4882a593Smuzhiyun };
1591*4882a593Smuzhiyun 
1592*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1593*4882a593Smuzhiyun 
pch_console_putchar(struct uart_port * port,int ch)1594*4882a593Smuzhiyun static void pch_console_putchar(struct uart_port *port, int ch)
1595*4882a593Smuzhiyun {
1596*4882a593Smuzhiyun 	struct eg20t_port *priv =
1597*4882a593Smuzhiyun 		container_of(port, struct eg20t_port, port);
1598*4882a593Smuzhiyun 
1599*4882a593Smuzhiyun 	wait_for_xmitr(priv, UART_LSR_THRE);
1600*4882a593Smuzhiyun 	iowrite8(ch, priv->membase + PCH_UART_THR);
1601*4882a593Smuzhiyun }
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun /*
1604*4882a593Smuzhiyun  *	Print a string to the serial port trying not to disturb
1605*4882a593Smuzhiyun  *	any possible real use of the port...
1606*4882a593Smuzhiyun  *
1607*4882a593Smuzhiyun  *	The console_lock must be held when we get here.
1608*4882a593Smuzhiyun  */
1609*4882a593Smuzhiyun static void
pch_console_write(struct console * co,const char * s,unsigned int count)1610*4882a593Smuzhiyun pch_console_write(struct console *co, const char *s, unsigned int count)
1611*4882a593Smuzhiyun {
1612*4882a593Smuzhiyun 	struct eg20t_port *priv;
1613*4882a593Smuzhiyun 	unsigned long flags;
1614*4882a593Smuzhiyun 	int priv_locked = 1;
1615*4882a593Smuzhiyun 	int port_locked = 1;
1616*4882a593Smuzhiyun 	u8 ier;
1617*4882a593Smuzhiyun 
1618*4882a593Smuzhiyun 	priv = pch_uart_ports[co->index];
1619*4882a593Smuzhiyun 
1620*4882a593Smuzhiyun 	touch_nmi_watchdog();
1621*4882a593Smuzhiyun 
1622*4882a593Smuzhiyun 	local_irq_save(flags);
1623*4882a593Smuzhiyun 	if (priv->port.sysrq) {
1624*4882a593Smuzhiyun 		/* call to uart_handle_sysrq_char already took the priv lock */
1625*4882a593Smuzhiyun 		priv_locked = 0;
1626*4882a593Smuzhiyun 		/* serial8250_handle_port() already took the port lock */
1627*4882a593Smuzhiyun 		port_locked = 0;
1628*4882a593Smuzhiyun 	} else if (oops_in_progress) {
1629*4882a593Smuzhiyun 		priv_locked = spin_trylock(&priv->lock);
1630*4882a593Smuzhiyun 		port_locked = spin_trylock(&priv->port.lock);
1631*4882a593Smuzhiyun 	} else {
1632*4882a593Smuzhiyun 		spin_lock(&priv->lock);
1633*4882a593Smuzhiyun 		spin_lock(&priv->port.lock);
1634*4882a593Smuzhiyun 	}
1635*4882a593Smuzhiyun 
1636*4882a593Smuzhiyun 	/*
1637*4882a593Smuzhiyun 	 *	First save the IER then disable the interrupts
1638*4882a593Smuzhiyun 	 */
1639*4882a593Smuzhiyun 	ier = ioread8(priv->membase + UART_IER);
1640*4882a593Smuzhiyun 
1641*4882a593Smuzhiyun 	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT);
1642*4882a593Smuzhiyun 
1643*4882a593Smuzhiyun 	uart_console_write(&priv->port, s, count, pch_console_putchar);
1644*4882a593Smuzhiyun 
1645*4882a593Smuzhiyun 	/*
1646*4882a593Smuzhiyun 	 *	Finally, wait for transmitter to become empty
1647*4882a593Smuzhiyun 	 *	and restore the IER
1648*4882a593Smuzhiyun 	 */
1649*4882a593Smuzhiyun 	wait_for_xmitr(priv, BOTH_EMPTY);
1650*4882a593Smuzhiyun 	iowrite8(ier, priv->membase + UART_IER);
1651*4882a593Smuzhiyun 
1652*4882a593Smuzhiyun 	if (port_locked)
1653*4882a593Smuzhiyun 		spin_unlock(&priv->port.lock);
1654*4882a593Smuzhiyun 	if (priv_locked)
1655*4882a593Smuzhiyun 		spin_unlock(&priv->lock);
1656*4882a593Smuzhiyun 	local_irq_restore(flags);
1657*4882a593Smuzhiyun }
1658*4882a593Smuzhiyun 
pch_console_setup(struct console * co,char * options)1659*4882a593Smuzhiyun static int __init pch_console_setup(struct console *co, char *options)
1660*4882a593Smuzhiyun {
1661*4882a593Smuzhiyun 	struct uart_port *port;
1662*4882a593Smuzhiyun 	int baud = default_baud;
1663*4882a593Smuzhiyun 	int bits = 8;
1664*4882a593Smuzhiyun 	int parity = 'n';
1665*4882a593Smuzhiyun 	int flow = 'n';
1666*4882a593Smuzhiyun 
1667*4882a593Smuzhiyun 	/*
1668*4882a593Smuzhiyun 	 * Check whether an invalid uart number has been specified, and
1669*4882a593Smuzhiyun 	 * if so, search for the first available port that does have
1670*4882a593Smuzhiyun 	 * console support.
1671*4882a593Smuzhiyun 	 */
1672*4882a593Smuzhiyun 	if (co->index >= PCH_UART_NR)
1673*4882a593Smuzhiyun 		co->index = 0;
1674*4882a593Smuzhiyun 	port = &pch_uart_ports[co->index]->port;
1675*4882a593Smuzhiyun 
1676*4882a593Smuzhiyun 	if (!port || (!port->iobase && !port->membase))
1677*4882a593Smuzhiyun 		return -ENODEV;
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 	port->uartclk = pch_uart_get_uartclk();
1680*4882a593Smuzhiyun 
1681*4882a593Smuzhiyun 	if (options)
1682*4882a593Smuzhiyun 		uart_parse_options(options, &baud, &parity, &bits, &flow);
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun 	return uart_set_options(port, co, baud, parity, bits, flow);
1685*4882a593Smuzhiyun }
1686*4882a593Smuzhiyun 
1687*4882a593Smuzhiyun static struct uart_driver pch_uart_driver;
1688*4882a593Smuzhiyun 
1689*4882a593Smuzhiyun static struct console pch_console = {
1690*4882a593Smuzhiyun 	.name		= PCH_UART_DRIVER_DEVICE,
1691*4882a593Smuzhiyun 	.write		= pch_console_write,
1692*4882a593Smuzhiyun 	.device		= uart_console_device,
1693*4882a593Smuzhiyun 	.setup		= pch_console_setup,
1694*4882a593Smuzhiyun 	.flags		= CON_PRINTBUFFER | CON_ANYTIME,
1695*4882a593Smuzhiyun 	.index		= -1,
1696*4882a593Smuzhiyun 	.data		= &pch_uart_driver,
1697*4882a593Smuzhiyun };
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun #define PCH_CONSOLE	(&pch_console)
1700*4882a593Smuzhiyun #else
1701*4882a593Smuzhiyun #define PCH_CONSOLE	NULL
1702*4882a593Smuzhiyun #endif	/* CONFIG_SERIAL_PCH_UART_CONSOLE */
1703*4882a593Smuzhiyun 
1704*4882a593Smuzhiyun static struct uart_driver pch_uart_driver = {
1705*4882a593Smuzhiyun 	.owner = THIS_MODULE,
1706*4882a593Smuzhiyun 	.driver_name = KBUILD_MODNAME,
1707*4882a593Smuzhiyun 	.dev_name = PCH_UART_DRIVER_DEVICE,
1708*4882a593Smuzhiyun 	.major = 0,
1709*4882a593Smuzhiyun 	.minor = 0,
1710*4882a593Smuzhiyun 	.nr = PCH_UART_NR,
1711*4882a593Smuzhiyun 	.cons = PCH_CONSOLE,
1712*4882a593Smuzhiyun };
1713*4882a593Smuzhiyun 
pch_uart_init_port(struct pci_dev * pdev,const struct pci_device_id * id)1714*4882a593Smuzhiyun static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
1715*4882a593Smuzhiyun 					     const struct pci_device_id *id)
1716*4882a593Smuzhiyun {
1717*4882a593Smuzhiyun 	struct eg20t_port *priv;
1718*4882a593Smuzhiyun 	int ret;
1719*4882a593Smuzhiyun 	unsigned int iobase;
1720*4882a593Smuzhiyun 	unsigned int mapbase;
1721*4882a593Smuzhiyun 	unsigned char *rxbuf;
1722*4882a593Smuzhiyun 	int fifosize;
1723*4882a593Smuzhiyun 	int port_type;
1724*4882a593Smuzhiyun 	struct pch_uart_driver_data *board;
1725*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
1726*4882a593Smuzhiyun 	char name[32];	/* for debugfs file name */
1727*4882a593Smuzhiyun #endif
1728*4882a593Smuzhiyun 
1729*4882a593Smuzhiyun 	board = &drv_dat[id->driver_data];
1730*4882a593Smuzhiyun 	port_type = board->port_type;
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun 	priv = kzalloc(sizeof(struct eg20t_port), GFP_KERNEL);
1733*4882a593Smuzhiyun 	if (priv == NULL)
1734*4882a593Smuzhiyun 		goto init_port_alloc_err;
1735*4882a593Smuzhiyun 
1736*4882a593Smuzhiyun 	rxbuf = (unsigned char *)__get_free_page(GFP_KERNEL);
1737*4882a593Smuzhiyun 	if (!rxbuf)
1738*4882a593Smuzhiyun 		goto init_port_free_txbuf;
1739*4882a593Smuzhiyun 
1740*4882a593Smuzhiyun 	switch (port_type) {
1741*4882a593Smuzhiyun 	case PORT_PCH_8LINE:
1742*4882a593Smuzhiyun 		fifosize = 256; /* EG20T/ML7213: UART0 */
1743*4882a593Smuzhiyun 		break;
1744*4882a593Smuzhiyun 	case PORT_PCH_2LINE:
1745*4882a593Smuzhiyun 		fifosize = 64; /* EG20T:UART1~3  ML7213: UART1~2*/
1746*4882a593Smuzhiyun 		break;
1747*4882a593Smuzhiyun 	default:
1748*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Invalid Port Type(=%d)\n", port_type);
1749*4882a593Smuzhiyun 		goto init_port_hal_free;
1750*4882a593Smuzhiyun 	}
1751*4882a593Smuzhiyun 
1752*4882a593Smuzhiyun 	pci_enable_msi(pdev);
1753*4882a593Smuzhiyun 	pci_set_master(pdev);
1754*4882a593Smuzhiyun 
1755*4882a593Smuzhiyun 	spin_lock_init(&priv->lock);
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun 	iobase = pci_resource_start(pdev, 0);
1758*4882a593Smuzhiyun 	mapbase = pci_resource_start(pdev, 1);
1759*4882a593Smuzhiyun 	priv->mapbase = mapbase;
1760*4882a593Smuzhiyun 	priv->iobase = iobase;
1761*4882a593Smuzhiyun 	priv->pdev = pdev;
1762*4882a593Smuzhiyun 	priv->tx_empty = 1;
1763*4882a593Smuzhiyun 	priv->rxbuf.buf = rxbuf;
1764*4882a593Smuzhiyun 	priv->rxbuf.size = PAGE_SIZE;
1765*4882a593Smuzhiyun 
1766*4882a593Smuzhiyun 	priv->fifo_size = fifosize;
1767*4882a593Smuzhiyun 	priv->uartclk = pch_uart_get_uartclk();
1768*4882a593Smuzhiyun 	priv->port_type = port_type;
1769*4882a593Smuzhiyun 	priv->port.dev = &pdev->dev;
1770*4882a593Smuzhiyun 	priv->port.iobase = iobase;
1771*4882a593Smuzhiyun 	priv->port.membase = NULL;
1772*4882a593Smuzhiyun 	priv->port.mapbase = mapbase;
1773*4882a593Smuzhiyun 	priv->port.irq = pdev->irq;
1774*4882a593Smuzhiyun 	priv->port.iotype = UPIO_PORT;
1775*4882a593Smuzhiyun 	priv->port.ops = &pch_uart_ops;
1776*4882a593Smuzhiyun 	priv->port.flags = UPF_BOOT_AUTOCONF;
1777*4882a593Smuzhiyun 	priv->port.fifosize = fifosize;
1778*4882a593Smuzhiyun 	priv->port.line = board->line_no;
1779*4882a593Smuzhiyun 	priv->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_PCH_UART_CONSOLE);
1780*4882a593Smuzhiyun 	priv->trigger = PCH_UART_HAL_TRIGGER_M;
1781*4882a593Smuzhiyun 
1782*4882a593Smuzhiyun 	snprintf(priv->irq_name, IRQ_NAME_SIZE,
1783*4882a593Smuzhiyun 		 KBUILD_MODNAME ":" PCH_UART_DRIVER_DEVICE "%d",
1784*4882a593Smuzhiyun 		 priv->port.line);
1785*4882a593Smuzhiyun 
1786*4882a593Smuzhiyun 	spin_lock_init(&priv->port.lock);
1787*4882a593Smuzhiyun 
1788*4882a593Smuzhiyun 	pci_set_drvdata(pdev, priv);
1789*4882a593Smuzhiyun 	priv->trigger_level = 1;
1790*4882a593Smuzhiyun 	priv->fcr = 0;
1791*4882a593Smuzhiyun 
1792*4882a593Smuzhiyun 	if (pdev->dev.of_node)
1793*4882a593Smuzhiyun 		of_property_read_u32(pdev->dev.of_node, "clock-frequency"
1794*4882a593Smuzhiyun 					 , &user_uartclk);
1795*4882a593Smuzhiyun 
1796*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1797*4882a593Smuzhiyun 	pch_uart_ports[board->line_no] = priv;
1798*4882a593Smuzhiyun #endif
1799*4882a593Smuzhiyun 	ret = uart_add_one_port(&pch_uart_driver, &priv->port);
1800*4882a593Smuzhiyun 	if (ret < 0)
1801*4882a593Smuzhiyun 		goto init_port_hal_free;
1802*4882a593Smuzhiyun 
1803*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
1804*4882a593Smuzhiyun 	snprintf(name, sizeof(name), "uart%d_regs", board->line_no);
1805*4882a593Smuzhiyun 	priv->debugfs = debugfs_create_file(name, S_IFREG | S_IRUGO,
1806*4882a593Smuzhiyun 				NULL, priv, &port_regs_ops);
1807*4882a593Smuzhiyun #endif
1808*4882a593Smuzhiyun 
1809*4882a593Smuzhiyun 	return priv;
1810*4882a593Smuzhiyun 
1811*4882a593Smuzhiyun init_port_hal_free:
1812*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1813*4882a593Smuzhiyun 	pch_uart_ports[board->line_no] = NULL;
1814*4882a593Smuzhiyun #endif
1815*4882a593Smuzhiyun 	free_page((unsigned long)rxbuf);
1816*4882a593Smuzhiyun init_port_free_txbuf:
1817*4882a593Smuzhiyun 	kfree(priv);
1818*4882a593Smuzhiyun init_port_alloc_err:
1819*4882a593Smuzhiyun 
1820*4882a593Smuzhiyun 	return NULL;
1821*4882a593Smuzhiyun }
1822*4882a593Smuzhiyun 
pch_uart_exit_port(struct eg20t_port * priv)1823*4882a593Smuzhiyun static void pch_uart_exit_port(struct eg20t_port *priv)
1824*4882a593Smuzhiyun {
1825*4882a593Smuzhiyun 
1826*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
1827*4882a593Smuzhiyun 	debugfs_remove(priv->debugfs);
1828*4882a593Smuzhiyun #endif
1829*4882a593Smuzhiyun 	uart_remove_one_port(&pch_uart_driver, &priv->port);
1830*4882a593Smuzhiyun 	free_page((unsigned long)priv->rxbuf.buf);
1831*4882a593Smuzhiyun }
1832*4882a593Smuzhiyun 
pch_uart_pci_remove(struct pci_dev * pdev)1833*4882a593Smuzhiyun static void pch_uart_pci_remove(struct pci_dev *pdev)
1834*4882a593Smuzhiyun {
1835*4882a593Smuzhiyun 	struct eg20t_port *priv = pci_get_drvdata(pdev);
1836*4882a593Smuzhiyun 
1837*4882a593Smuzhiyun 	pci_disable_msi(pdev);
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
1840*4882a593Smuzhiyun 	pch_uart_ports[priv->port.line] = NULL;
1841*4882a593Smuzhiyun #endif
1842*4882a593Smuzhiyun 	pch_uart_exit_port(priv);
1843*4882a593Smuzhiyun 	pci_disable_device(pdev);
1844*4882a593Smuzhiyun 	kfree(priv);
1845*4882a593Smuzhiyun 	return;
1846*4882a593Smuzhiyun }
1847*4882a593Smuzhiyun 
pch_uart_pci_suspend(struct device * dev)1848*4882a593Smuzhiyun static int __maybe_unused pch_uart_pci_suspend(struct device *dev)
1849*4882a593Smuzhiyun {
1850*4882a593Smuzhiyun 	struct eg20t_port *priv = dev_get_drvdata(dev);
1851*4882a593Smuzhiyun 
1852*4882a593Smuzhiyun 	uart_suspend_port(&pch_uart_driver, &priv->port);
1853*4882a593Smuzhiyun 
1854*4882a593Smuzhiyun 	return 0;
1855*4882a593Smuzhiyun }
1856*4882a593Smuzhiyun 
pch_uart_pci_resume(struct device * dev)1857*4882a593Smuzhiyun static int __maybe_unused pch_uart_pci_resume(struct device *dev)
1858*4882a593Smuzhiyun {
1859*4882a593Smuzhiyun 	struct eg20t_port *priv = dev_get_drvdata(dev);
1860*4882a593Smuzhiyun 
1861*4882a593Smuzhiyun 	uart_resume_port(&pch_uart_driver, &priv->port);
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun 	return 0;
1864*4882a593Smuzhiyun }
1865*4882a593Smuzhiyun 
1866*4882a593Smuzhiyun static const struct pci_device_id pch_uart_pci_id[] = {
1867*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811),
1868*4882a593Smuzhiyun 	 .driver_data = pch_et20t_uart0},
1869*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8812),
1870*4882a593Smuzhiyun 	 .driver_data = pch_et20t_uart1},
1871*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8813),
1872*4882a593Smuzhiyun 	 .driver_data = pch_et20t_uart2},
1873*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8814),
1874*4882a593Smuzhiyun 	 .driver_data = pch_et20t_uart3},
1875*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8027),
1876*4882a593Smuzhiyun 	 .driver_data = pch_ml7213_uart0},
1877*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8028),
1878*4882a593Smuzhiyun 	 .driver_data = pch_ml7213_uart1},
1879*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029),
1880*4882a593Smuzhiyun 	 .driver_data = pch_ml7213_uart2},
1881*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800C),
1882*4882a593Smuzhiyun 	 .driver_data = pch_ml7223_uart0},
1883*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
1884*4882a593Smuzhiyun 	 .driver_data = pch_ml7223_uart1},
1885*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811),
1886*4882a593Smuzhiyun 	 .driver_data = pch_ml7831_uart0},
1887*4882a593Smuzhiyun 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812),
1888*4882a593Smuzhiyun 	 .driver_data = pch_ml7831_uart1},
1889*4882a593Smuzhiyun 	{0,},
1890*4882a593Smuzhiyun };
1891*4882a593Smuzhiyun 
pch_uart_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)1892*4882a593Smuzhiyun static int pch_uart_pci_probe(struct pci_dev *pdev,
1893*4882a593Smuzhiyun 					const struct pci_device_id *id)
1894*4882a593Smuzhiyun {
1895*4882a593Smuzhiyun 	int ret;
1896*4882a593Smuzhiyun 	struct eg20t_port *priv;
1897*4882a593Smuzhiyun 
1898*4882a593Smuzhiyun 	ret = pci_enable_device(pdev);
1899*4882a593Smuzhiyun 	if (ret < 0)
1900*4882a593Smuzhiyun 		goto probe_error;
1901*4882a593Smuzhiyun 
1902*4882a593Smuzhiyun 	priv = pch_uart_init_port(pdev, id);
1903*4882a593Smuzhiyun 	if (!priv) {
1904*4882a593Smuzhiyun 		ret = -EBUSY;
1905*4882a593Smuzhiyun 		goto probe_disable_device;
1906*4882a593Smuzhiyun 	}
1907*4882a593Smuzhiyun 	pci_set_drvdata(pdev, priv);
1908*4882a593Smuzhiyun 
1909*4882a593Smuzhiyun 	return ret;
1910*4882a593Smuzhiyun 
1911*4882a593Smuzhiyun probe_disable_device:
1912*4882a593Smuzhiyun 	pci_disable_msi(pdev);
1913*4882a593Smuzhiyun 	pci_disable_device(pdev);
1914*4882a593Smuzhiyun probe_error:
1915*4882a593Smuzhiyun 	return ret;
1916*4882a593Smuzhiyun }
1917*4882a593Smuzhiyun 
1918*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops,
1919*4882a593Smuzhiyun 			 pch_uart_pci_suspend,
1920*4882a593Smuzhiyun 			 pch_uart_pci_resume);
1921*4882a593Smuzhiyun 
1922*4882a593Smuzhiyun static struct pci_driver pch_uart_pci_driver = {
1923*4882a593Smuzhiyun 	.name = "pch_uart",
1924*4882a593Smuzhiyun 	.id_table = pch_uart_pci_id,
1925*4882a593Smuzhiyun 	.probe = pch_uart_pci_probe,
1926*4882a593Smuzhiyun 	.remove = pch_uart_pci_remove,
1927*4882a593Smuzhiyun 	.driver.pm = &pch_uart_pci_pm_ops,
1928*4882a593Smuzhiyun };
1929*4882a593Smuzhiyun 
pch_uart_module_init(void)1930*4882a593Smuzhiyun static int __init pch_uart_module_init(void)
1931*4882a593Smuzhiyun {
1932*4882a593Smuzhiyun 	int ret;
1933*4882a593Smuzhiyun 
1934*4882a593Smuzhiyun 	/* register as UART driver */
1935*4882a593Smuzhiyun 	ret = uart_register_driver(&pch_uart_driver);
1936*4882a593Smuzhiyun 	if (ret < 0)
1937*4882a593Smuzhiyun 		return ret;
1938*4882a593Smuzhiyun 
1939*4882a593Smuzhiyun 	/* register as PCI driver */
1940*4882a593Smuzhiyun 	ret = pci_register_driver(&pch_uart_pci_driver);
1941*4882a593Smuzhiyun 	if (ret < 0)
1942*4882a593Smuzhiyun 		uart_unregister_driver(&pch_uart_driver);
1943*4882a593Smuzhiyun 
1944*4882a593Smuzhiyun 	return ret;
1945*4882a593Smuzhiyun }
1946*4882a593Smuzhiyun module_init(pch_uart_module_init);
1947*4882a593Smuzhiyun 
pch_uart_module_exit(void)1948*4882a593Smuzhiyun static void __exit pch_uart_module_exit(void)
1949*4882a593Smuzhiyun {
1950*4882a593Smuzhiyun 	pci_unregister_driver(&pch_uart_pci_driver);
1951*4882a593Smuzhiyun 	uart_unregister_driver(&pch_uart_driver);
1952*4882a593Smuzhiyun }
1953*4882a593Smuzhiyun module_exit(pch_uart_module_exit);
1954*4882a593Smuzhiyun 
1955*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1956*4882a593Smuzhiyun MODULE_DESCRIPTION("Intel EG20T PCH UART PCI Driver");
1957*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, pch_uart_pci_id);
1958*4882a593Smuzhiyun 
1959*4882a593Smuzhiyun module_param(default_baud, uint, S_IRUGO);
1960*4882a593Smuzhiyun MODULE_PARM_DESC(default_baud,
1961*4882a593Smuzhiyun                  "Default BAUD for initial driver state and console (default 9600)");
1962*4882a593Smuzhiyun module_param(user_uartclk, uint, S_IRUGO);
1963*4882a593Smuzhiyun MODULE_PARM_DESC(user_uartclk,
1964*4882a593Smuzhiyun                  "Override UART default or board specific UART clock");
1965