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