diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-uart.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-uart.patch | 1589 |
1 files changed, 1589 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-uart.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-uart.patch new file mode 100644 index 0000000000..b1e1f4832f --- /dev/null +++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-uart.patch | |||
@@ -0,0 +1,1589 @@ | |||
1 | |||
2 | |||
3 | From: Masayuki Ohtake <masa-korg@dsn.okisemi.com> | ||
4 | Subject: OKI Semiconductor PCH UART driver | ||
5 | |||
6 | This driver implements UART controls for PCH. | ||
7 | |||
8 | Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com> | ||
9 | Acked-by: Wang Qi <qi.wang@intel.com> | ||
10 | |||
11 | --- | ||
12 | drivers/serial/8250.c | 8 | ||
13 | drivers/serial/8250_pch.h | 57 | ||
14 | drivers/serial/8250_pci.c | | ||
15 | drivers/serial/Kconfig | 15 | ||
16 | drivers/serial/Makefile | 11 | ||
17 | +++++++++++++++++++++++++++++++ 5 files changed, zz insertions(+) | ||
18 | diff -urN linux-2.6.33.1/drivers/serial/8250.c topcliff-2.6.33.1/drivers/serial/8250.c | ||
19 | --- linux-2.6.33.1/drivers/serial/8250.c 2010-03-16 01:09:39.000000000 +0900 | ||
20 | +++ topcliff-2.6.33.1/drivers/serial/8250.c 2010-03-23 10:34:44.000000000 +0900 | ||
21 | @@ -39,11 +39,19 @@ | ||
22 | #include <linux/nmi.h> | ||
23 | #include <linux/mutex.h> | ||
24 | |||
25 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
26 | +/* For using DMA features. */ | ||
27 | +#include <linux/pci.h> | ||
28 | +#include <linux/pci_ids.h> | ||
29 | +#include <linux/dma-mapping.h> | ||
30 | +#include "pch_dma_main.h" | ||
31 | +#endif | ||
32 | + | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/irq.h> | ||
35 | |||
36 | #include "8250.h" | ||
37 | - | ||
38 | +#include "8250_pch.h" | ||
39 | #ifdef CONFIG_SPARC | ||
40 | #include "suncore.h" | ||
41 | #endif | ||
42 | @@ -129,6 +137,18 @@ | ||
43 | static unsigned int probe_rsa_count; | ||
44 | #endif /* CONFIG_SERIAL_8250_RSA */ | ||
45 | |||
46 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
47 | +/* Structure for storing the DMA channel related information. */ | ||
48 | +struct ioh_dma_feature { | ||
49 | + u32 buf; | ||
50 | + u32 phy_addr; | ||
51 | + s32 channel; | ||
52 | + u32 size; | ||
53 | +}; | ||
54 | +#endif | ||
55 | + | ||
56 | + | ||
57 | + | ||
58 | struct uart_8250_port { | ||
59 | struct uart_port port; | ||
60 | struct timer_list timer; /* "no irq" timer */ | ||
61 | @@ -159,6 +179,17 @@ | ||
62 | */ | ||
63 | void (*pm)(struct uart_port *port, | ||
64 | unsigned int state, unsigned int old); | ||
65 | + | ||
66 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
67 | + struct ioh_dma_feature rx_dma; /* DMA operation for Receive. */ | ||
68 | + struct ioh_dma_feature tx_dma; /* DMA operation for Transmit. */ | ||
69 | + unsigned int buffer; /* The buffer for DMA descriptors.*/ | ||
70 | + unsigned int buffer_phy; /* The physical address of the buffer.*/ | ||
71 | + unsigned int dma_flag;/* DMA flag variable for enabling DMA transfer. */ | ||
72 | + unsigned int rx_fifo_size; /* The UART Rx fifo size.*/ | ||
73 | + unsigned int dma_progress; /* The DMA in progress flag.*/ | ||
74 | + unsigned int dma_enabled; /* The DMA enable flag. */ | ||
75 | +#endif | ||
76 | }; | ||
77 | |||
78 | struct irq_info { | ||
79 | @@ -299,6 +330,25 @@ | ||
80 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, | ||
81 | .flags = UART_CAP_FIFO | UART_CAP_AFE, | ||
82 | }, | ||
83 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
84 | + [PORT_IOH_256FIFO] = { | ||
85 | + .name = "IOH_256FIFO", | ||
86 | + .fifo_size = 256, | ||
87 | + .tx_loadsz = 256, | ||
88 | + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | | ||
89 | + UART_FCR7_256BYTE, | ||
90 | + .flags = UART_CAP_FIFO | UART_CAP_AFE, | ||
91 | + }, | ||
92 | + | ||
93 | + [PORT_IOH_64FIFO] = { | ||
94 | + .name = "IOH_64FIFO", | ||
95 | + .fifo_size = 64, | ||
96 | + .tx_loadsz = 64, | ||
97 | + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | | ||
98 | + UART_FCR7_64BYTE, | ||
99 | + .flags = UART_CAP_FIFO | UART_BUG_NOMSR, | ||
100 | + }, | ||
101 | +#endif | ||
102 | }; | ||
103 | |||
104 | #if defined (CONFIG_SERIAL_8250_AU1X00) | ||
105 | @@ -383,6 +433,78 @@ | ||
106 | |||
107 | #endif | ||
108 | |||
109 | + | ||
110 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
111 | + | ||
112 | +/* Function for calculating the Rx FIFO size of the IOH UART. */ | ||
113 | +void get_rx_fifo_size(struct uart_8250_port *up, u8 fcr_value) | ||
114 | +{ | ||
115 | + unsigned fifo_size; | ||
116 | + | ||
117 | +#ifdef DEBUG | ||
118 | + printk(KERN_DEBUG"get_rx_fifo -> The FCR register value: %x.\n", | ||
119 | + fcr_value); | ||
120 | +#endif | ||
121 | +/* check if the UART is a 64 byte FIFO UART */ | ||
122 | + if ((up->port.flags & UPF_IOH_UART_64_FIFO) != 0) { | ||
123 | + switch ((fcr_value & 0xC0)) { | ||
124 | + case 0: | ||
125 | + fifo_size = 1; | ||
126 | + break; | ||
127 | + | ||
128 | + case 0x40: | ||
129 | + fifo_size = 16; | ||
130 | + break; | ||
131 | + | ||
132 | + case 0x80: | ||
133 | + fifo_size = 32; | ||
134 | + break; | ||
135 | + | ||
136 | + case 0xC0: | ||
137 | + fifo_size = 56; | ||
138 | + break; | ||
139 | + | ||
140 | + default: | ||
141 | + fifo_size = 1; | ||
142 | + break; | ||
143 | + } | ||
144 | + } else { | ||
145 | +/* UART is 256 byte byte FIFO UART */ | ||
146 | + switch ((fcr_value & 0xC0)) { | ||
147 | + case 0: | ||
148 | + fifo_size = 1; | ||
149 | + break; | ||
150 | + | ||
151 | + case 0x40: | ||
152 | + fifo_size = 64; | ||
153 | + break; | ||
154 | + | ||
155 | + case 0x80: | ||
156 | + fifo_size = 128; | ||
157 | + break; | ||
158 | + | ||
159 | + case 0xC0: | ||
160 | + fifo_size = 224; | ||
161 | + break; | ||
162 | + | ||
163 | + default: | ||
164 | + fifo_size = 1; | ||
165 | + break; | ||
166 | + } | ||
167 | + } | ||
168 | +/* save the fifo size for reference */ | ||
169 | + up->rx_fifo_size = fifo_size; | ||
170 | +#ifdef DEBUG | ||
171 | + printk(KERN_DEBUG"Function get_rx_fifo_size stores fifo_size as: %u.\n", | ||
172 | + fifo_size); | ||
173 | +#endif | ||
174 | +} | ||
175 | + | ||
176 | +#endif | ||
177 | + | ||
178 | + | ||
179 | + | ||
180 | + | ||
181 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) | ||
182 | { | ||
183 | offset = map_8250_in_reg(p, offset) << p->regshift; | ||
184 | @@ -550,15 +672,285 @@ | ||
185 | (up->port.serial_in(&(up)->port, (offset))) | ||
186 | #define serial_out(up, offset, value) \ | ||
187 | (up->port.serial_out(&(up)->port, (offset), (value))) | ||
188 | + | ||
189 | /* | ||
190 | * We used to support using pause I/O for certain machines. We | ||
191 | * haven't supported this for a while, but just in case it's badly | ||
192 | * needed for certain old 386 machines, I've left these #define's | ||
193 | * in.... | ||
194 | */ | ||
195 | + | ||
196 | #define serial_inp(up, offset) serial_in(up, offset) | ||
197 | #define serial_outp(up, offset, value) serial_out(up, offset, value) | ||
198 | |||
199 | + | ||
200 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
201 | + | ||
202 | +/* DMA TX callback function */ | ||
203 | +void ioh_dma_tx_callback(int status, unsigned long data) | ||
204 | +{ | ||
205 | + struct uart_8250_port *up = (struct uart_8250_port *)data; | ||
206 | +/* struct circ_buf *xmit = &up->port.info->xmit;*/ | ||
207 | + struct circ_buf *xmit = &up->port.state->xmit;/*for 2.6.33-rc3*/ | ||
208 | + u8 value; | ||
209 | + | ||
210 | +#ifdef DEBUG | ||
211 | + if (status == IOH_DMA_END) { | ||
212 | + printk(KERN_DEBUG"ioh_dma_tx_callback -> DMA END interrupt\ | ||
213 | + obtained " \ | ||
214 | + "for transmission.\n"); | ||
215 | + | ||
216 | + } | ||
217 | +#endif | ||
218 | + if (status == IOH_DMA_ABORT) { | ||
219 | + printk(KERN_ERR"ioh_dma_tx_callback -> DMA ABORT interrupt\ | ||
220 | + obtained " \ | ||
221 | + "for transmission.\n"); | ||
222 | + } | ||
223 | + | ||
224 | + /* Un-mapping the DMA buffer. */ | ||
225 | + if (up->tx_dma.phy_addr > 0) | ||
226 | + dma_unmap_single(up->port.dev, up->tx_dma.phy_addr, | ||
227 | + up->tx_dma.size, DMA_TO_DEVICE); | ||
228 | + | ||
229 | + dma_unmap_single(up->port.dev, up->buffer_phy, | ||
230 | + PAGE_SIZE, DMA_TO_DEVICE); | ||
231 | + | ||
232 | + /*Enable TX interrupt.*/ | ||
233 | + if (uart_circ_chars_pending(xmit)) { | ||
234 | + value = (u8)serial_in(up, UART_IER); | ||
235 | + serial_out(up, UART_IER, (value | 0x02)); | ||
236 | + up->ier = serial_in(up, UART_IER); | ||
237 | + } | ||
238 | +#ifdef DEBUG | ||
239 | + printk(KERN_DEBUG"Function ioh_dma_tx_callback invoked.\n"); | ||
240 | +#endif | ||
241 | +} | ||
242 | + | ||
243 | +/* Function for DMA setting for Scatter Gather Mode. */ | ||
244 | +void set_scatter_gather_dma_mode(struct uart_8250_port *up, unsigned count) | ||
245 | +{ | ||
246 | + u32 in_address; | ||
247 | + u32 out_address; | ||
248 | + u32 desc_address; | ||
249 | + u32 total_desc; | ||
250 | + u32 i, j; | ||
251 | + u8 value; | ||
252 | + struct ioh_dma_desc *desc; | ||
253 | + int channel = up->tx_dma.channel; | ||
254 | + struct ioh_dma_mode_param mode = { | ||
255 | + .TransferDirection = IOH_DMA_DIR_OUT_TO_IN, | ||
256 | + .DMASizeType = IOH_DMA_SIZE_TYPE_8BIT, | ||
257 | + .DMATransferMode = DMA_SCATTER_GATHER_MODE | ||
258 | + }; | ||
259 | + | ||
260 | + desc = (struct ioh_dma_desc *)up->tx_dma.buf; | ||
261 | + | ||
262 | + /* Mapping the DMA buffer for transfer. */ | ||
263 | + out_address = dma_map_single(up->port.dev, (void *)up->buffer, | ||
264 | + PAGE_SIZE, DMA_TO_DEVICE); | ||
265 | + in_address = up->port.mapbase + (map_8250_in_reg(up, UART_TX)); | ||
266 | + desc_address = dma_map_single(up->port.dev, (void *)up->tx_dma.buf, | ||
267 | + up->tx_dma.size, DMA_TO_DEVICE); | ||
268 | + up->buffer_phy = out_address; | ||
269 | + up->tx_dma.phy_addr = desc_address; | ||
270 | + | ||
271 | + /* Disable Transmit hardware interrupt.*/ | ||
272 | + value = (u8)serial_in(up, UART_IER); | ||
273 | + serial_out(up, UART_IER, (value & 0xFD)); | ||
274 | + up->ier = serial_in(up, UART_IER); | ||
275 | + | ||
276 | + total_desc = count/(up->tx_loadsz); | ||
277 | + | ||
278 | + if ((count % (up->tx_loadsz)) > 0) | ||
279 | + total_desc++; | ||
280 | + | ||
281 | + dma_sync_single_for_cpu(up->port.dev, desc_address, up->tx_dma.size, | ||
282 | + DMA_TO_DEVICE); | ||
283 | + | ||
284 | + /* Organising the DMA descriptors. */ | ||
285 | + for (i = 0, j = 0; (i < total_desc && count > 0); i++) { | ||
286 | + desc[i].insideAddress = in_address; | ||
287 | + desc[i].outsideAddress = (out_address + j); | ||
288 | + | ||
289 | + if ((int)(count - (up->tx_loadsz)) > 0) { | ||
290 | + desc[i].size = up->tx_loadsz | IOH_DMA_SIZE_TYPE_8BIT; | ||
291 | + count = count - (up->tx_loadsz); | ||
292 | + j += (up->tx_loadsz); | ||
293 | + } else { | ||
294 | + desc[i].size = count | IOH_DMA_SIZE_TYPE_8BIT; | ||
295 | + j += count; | ||
296 | + count = 0; | ||
297 | + } | ||
298 | + | ||
299 | + desc[i].nextDesc = ((((u32)((desc_address + | ||
300 | + ((i + 1)*(sizeof(struct ioh_dma_desc)))))) & 0xFFFFFFFC) | | ||
301 | + DMA_DESC_FOLLOW_WITHOUT_INTERRUPT); | ||
302 | + } | ||
303 | + | ||
304 | + desc[i - 1].nextDesc = (DMA_DESC_END_WITH_INTERRUPT); | ||
305 | + | ||
306 | + dma_sync_single_for_device(up->port.dev, desc_address, up->tx_dma.size, | ||
307 | + DMA_TO_DEVICE); | ||
308 | + | ||
309 | + /* Initiating the DMA transfer. */ | ||
310 | + ioh_set_dma_mode(channel, mode); | ||
311 | + ioh_set_dma_desc(channel, (struct ioh_dma_desc *)((desc_address & | ||
312 | + 0xFFFFFFFC) | DMA_DESC_FOLLOW_WITHOUT_INTERRUPT),\ | ||
313 | + (((struct ioh_dma_desc *)desc_address) + (total_desc - 1))); | ||
314 | + ioh_dma_set_callback(channel, ioh_dma_tx_callback, (u32)up); | ||
315 | + ioh_enable_dma(channel); | ||
316 | + | ||
317 | +#ifdef DEBUG | ||
318 | + printk(KERN_DEBUG"Function set_scatter_gather_dma_mode invoked.\n"); | ||
319 | +#endif | ||
320 | +} | ||
321 | + | ||
322 | +/* Function for DMA settings for ONE SHOT mode. */ | ||
323 | +void set_one_shot_dma_mode(struct uart_8250_port *up, unsigned count) | ||
324 | +{ | ||
325 | + u32 in_address; | ||
326 | + u32 out_address; | ||
327 | + u8 value; | ||
328 | + int channel = up->tx_dma.channel; | ||
329 | + struct ioh_dma_mode_param mode = { | ||
330 | + .TransferDirection = IOH_DMA_DIR_OUT_TO_IN, | ||
331 | + .DMASizeType = IOH_DMA_SIZE_TYPE_8BIT, | ||
332 | + .DMATransferMode = DMA_ONE_SHOT_MODE | ||
333 | + }; | ||
334 | + | ||
335 | + /* Disable Receive hardware interrupt.*/ | ||
336 | + value = (u8)serial_in(up, UART_IER); | ||
337 | + serial_out(up, UART_IER, (value & 0xFD)); | ||
338 | + up->ier = serial_in(up, UART_IER); | ||
339 | + | ||
340 | + /* Mapping the DMA buffer for transfer. */ | ||
341 | + out_address = dma_map_single(up->port.dev, (void *)up->buffer, | ||
342 | + PAGE_SIZE, DMA_TO_DEVICE); | ||
343 | + in_address = up->port.mapbase + (map_8250_in_reg(up, UART_TX)); | ||
344 | + up->buffer_phy = out_address; | ||
345 | + up->tx_dma.phy_addr = 0; | ||
346 | + | ||
347 | + /* Initiating the DMA transfer. */ | ||
348 | + ioh_set_dma_mode(channel, mode); | ||
349 | + ioh_set_dma_addr(channel, in_address, out_address); | ||
350 | + ioh_set_dma_count(channel, count); | ||
351 | + ioh_dma_set_callback(channel, ioh_dma_tx_callback, (u32)up); | ||
352 | + ioh_enable_dma(channel); | ||
353 | + | ||
354 | +#ifdef DEBUG | ||
355 | + printk(KERN_DEBUG"Function set_one_shot_dma_mode invoked.\n"); | ||
356 | +#endif | ||
357 | +} | ||
358 | + | ||
359 | +/* Function for pushing the received characters to tty buffer. */ | ||
360 | +/* At high baud rates tty buffer does not get emptied sufficiently fast | ||
361 | + and hence multiple retries are required to push the data into the buffer */ | ||
362 | + | ||
363 | +static int push_rx(struct tty_struct *tty, const unsigned char *buf, int size) | ||
364 | +{ | ||
365 | + u32 sz, i, j; | ||
366 | + u32 loop; | ||
367 | + u32 pushed; | ||
368 | + | ||
369 | + for (pushed = 0, i = 0, loop = 1; (pushed < size) && loop; | ||
370 | + pushed += sz, i++) { | ||
371 | + sz = tty_insert_flip_string(tty, &buf[pushed], size - pushed); | ||
372 | + | ||
373 | + for (j = 0; (j < 100000) && (sz == 0); j++) { | ||
374 | + tty_flip_buffer_push(tty); | ||
375 | + sz = tty_insert_flip_string(tty, &buf[pushed], | ||
376 | + size - pushed); | ||
377 | + } | ||
378 | + | ||
379 | + if (sz == 0) | ||
380 | + loop = 0; | ||
381 | + | ||
382 | + } | ||
383 | + | ||
384 | + tty_flip_buffer_push(tty); | ||
385 | + | ||
386 | +#ifdef DEBUG | ||
387 | + printk(KERN_DEBUG"push_rx -> %d characters pushed. Remained " \ | ||
388 | + "%d characters.\n", pushed, size - pushed); | ||
389 | + printk(KERN_DEBUG"Function push_rx return %u.\n", pushed); | ||
390 | +#endif | ||
391 | + | ||
392 | + return pushed; | ||
393 | +} | ||
394 | + | ||
395 | +/* The DMA reception callback function. */ | ||
396 | +void ioh_dma_rx_callback(int status, unsigned long data) | ||
397 | +{ | ||
398 | + struct uart_8250_port *up = (struct uart_8250_port *)data; | ||
399 | + unsigned fifo_size; | ||
400 | + unsigned long flags; | ||
401 | + u8 value; | ||
402 | + | ||
403 | + spin_lock_irqsave(&up->port.lock, flags); | ||
404 | + | ||
405 | + /* Normal end. */ | ||
406 | + if (status == IOH_DMA_END) { | ||
407 | + /* Preparing the DMA buffer to be accessed by the CPU*/ | ||
408 | + dma_sync_single_for_cpu(up->port.dev, up->rx_dma.phy_addr, | ||
409 | + up->rx_dma.size, DMA_FROM_DEVICE); | ||
410 | + | ||
411 | +#ifdef DEBUG | ||
412 | + printk(KERN_DEBUG"ioh_dma_rx_callback -> DMA END interrupt\ | ||
413 | + obtained for reception.\n"); | ||
414 | +#endif | ||
415 | + fifo_size = up->rx_fifo_size; | ||
416 | +/* push_rx(up->port.info->port.tty, (char *)up->rx_dma.buf, | ||
417 | + fifo_size);*/ | ||
418 | + push_rx(up->port.state->port.tty, (char *)up->rx_dma.buf, | ||
419 | + fifo_size); /*for 2.6.33-rc3 */ | ||
420 | + | ||
421 | + } else if (status == IOH_DMA_ABORT) { /* DMA abort. */ | ||
422 | + printk(KERN_ERR"ioh_dma_rx_callback -> DMA ABORT interrupt\ | ||
423 | + obtained for reception.\n"); | ||
424 | + } | ||
425 | + | ||
426 | + /* Unmapping the buffer from DMA accesible area. */ | ||
427 | + dma_unmap_single(up->port.dev, up->rx_dma.phy_addr, up->rx_dma.size, | ||
428 | + DMA_FROM_DEVICE); | ||
429 | + | ||
430 | + /*Enable hardware interrupt.*/ | ||
431 | + value = (u8)serial_in(up, UART_IER); | ||
432 | + serial_out(up, UART_IER, (value | 0x01)); | ||
433 | + up->ier = serial_in(up, UART_IER); | ||
434 | + up->dma_progress = 0; | ||
435 | + | ||
436 | + spin_unlock_irqrestore(&up->port.lock, flags); | ||
437 | + | ||
438 | +#ifdef DEBUG | ||
439 | + printk(KERN_DEBUG"ioh_dma_rx_callback -> Function ioh_dma_rx_callback\ | ||
440 | + is invoked.\n"); | ||
441 | +#endif | ||
442 | +} | ||
443 | + | ||
444 | +/* For initiating the DMA operation.*/ | ||
445 | +void handle_dma_operation(struct uart_8250_port *up) | ||
446 | +{ | ||
447 | + u8 value; | ||
448 | + int channel = up->rx_dma.channel; | ||
449 | + | ||
450 | + /* Disable Receive hardware interrupt.*/ | ||
451 | + value = (u8)serial_in(up, UART_IER); | ||
452 | + serial_out(up, UART_IER, (value & 0xFE)); | ||
453 | + up->ier = serial_in(up, UART_IER); | ||
454 | + | ||
455 | + /* Enabling the DMA transfer. */ | ||
456 | + ioh_enable_dma(channel); | ||
457 | + up->dma_progress = 1; | ||
458 | + | ||
459 | +#ifdef DEBUG | ||
460 | + printk(KERN_DEBUG"handle_dma_operation -> DMA settings for reception\ | ||
461 | + completed.\n"); | ||
462 | + printk(KERN_DEBUG"Function handle_dma_operation invoked.\n"); | ||
463 | +#endif | ||
464 | +} | ||
465 | +#endif /*for 2.6.33-rc3 */ | ||
466 | + | ||
467 | /* Uart divisor latch read */ | ||
468 | static inline int _serial_dl_read(struct uart_8250_port *up) | ||
469 | { | ||
470 | @@ -725,7 +1117,8 @@ | ||
471 | result = !(mode & UART_RSA_MSR_FIFO); | ||
472 | |||
473 | if (!result) { | ||
474 | - serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); | ||
475 | + serial_outp(up, UART_RSA_MSR, | ||
476 | + mode & ~UART_RSA_MSR_FIFO); | ||
477 | mode = serial_inp(up, UART_RSA_MSR); | ||
478 | result = !(mode & UART_RSA_MSR_FIFO); | ||
479 | } | ||
480 | @@ -1040,6 +1433,18 @@ | ||
481 | return; | ||
482 | } | ||
483 | |||
484 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
485 | + if ((up->port.flags & UPF_IOH_UART) != 0) { | ||
486 | + if ((up->port.flags & UPF_IOH_UART_64_FIFO) != 0) | ||
487 | + /* IOH 2 Line 64 FIFO UART */ | ||
488 | + up->port.type = PORT_IOH_64FIFO; | ||
489 | + else | ||
490 | + /* IOH 8 Line 256 FIFO UART */ | ||
491 | + up->port.type = PORT_IOH_256FIFO; | ||
492 | + | ||
493 | + } | ||
494 | +#endif | ||
495 | + | ||
496 | /* | ||
497 | * Try writing and reading the UART_IER_UUE bit (b6). | ||
498 | * If it works, this is probably one of the Xscale platform's | ||
499 | @@ -1093,7 +1498,7 @@ | ||
500 | return; | ||
501 | |||
502 | DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ", | ||
503 | - serial_index(&up->port), up->port.iobase, up->port.membase); | ||
504 | + serial_index(&up->port), up->port.iobase, up->port.membase); | ||
505 | |||
506 | /* | ||
507 | * We really do need global IRQs disabled here - we're going to | ||
508 | @@ -1196,7 +1601,34 @@ | ||
509 | up->port.type = PORT_16550; | ||
510 | break; | ||
511 | case 3: | ||
512 | - autoconfig_16550a(up); | ||
513 | +#ifdef ENABLE_SERIAL_8250_PCH | ||
514 | + if ((up->port.type != PORT_IOH_256FIFO) && | ||
515 | + (up->port.type != PORT_IOH_64FIFO)) { | ||
516 | +#endif | ||
517 | + | ||
518 | +#ifdef DEBUG | ||
519 | + printk(KERN_DEBUG | ||
520 | + "IOH UART LOG:function autoconfig->autoconfig_16550a\ | ||
521 | + invoked " | ||
522 | + "for port %d\n", up->port.type); | ||
523 | +#endif | ||
524 | + autoconfig_16550a(up); | ||
525 | + | ||
526 | +#ifdef ENABLE_SERIAL_8250_PCH | ||
527 | + } | ||
528 | +#endif | ||
529 | + | ||
530 | +#ifdef ENABLE_SERIAL_8250_PCH | ||
531 | + else { | ||
532 | + | ||
533 | +#ifdef DEBUG | ||
534 | + printk(KERN_DEBUG | ||
535 | + "IOH UART LOG:function autoconfig->autoconfig_16550a\ | ||
536 | + not " | ||
537 | + "invoked for IOH UART port %d\n", up->port.type); | ||
538 | +#endif | ||
539 | + } | ||
540 | +#endif | ||
541 | break; | ||
542 | } | ||
543 | |||
544 | @@ -1224,18 +1656,40 @@ | ||
545 | #endif | ||
546 | |||
547 | serial_outp(up, UART_LCR, save_lcr); | ||
548 | +#ifdef ENABLE_SERIAL_8250_PCH | ||
549 | + if ((up->port.type != PORT_IOH_256FIFO) && | ||
550 | + (up->port.type != PORT_IOH_64FIFO)) { | ||
551 | + /* autoconfig is not done for ioh uarts. | ||
552 | + hence do not report any kernel warning */ | ||
553 | +#endif | ||
554 | |||
555 | - if (up->capabilities != uart_config[up->port.type].flags) { | ||
556 | - printk(KERN_WARNING | ||
557 | - "ttyS%d: detected caps %08x should be %08x\n", | ||
558 | - serial_index(&up->port), up->capabilities, | ||
559 | - uart_config[up->port.type].flags); | ||
560 | + if (up->capabilities != uart_config[up->port.type].flags) { | ||
561 | + printk(KERN_WARNING "ttyS%d: detected\ | ||
562 | + caps %08x should be %08x\n", | ||
563 | + up->port.line, up->capabilities, | ||
564 | + uart_config[up->port.type].flags); | ||
565 | + } | ||
566 | + | ||
567 | +#ifdef ENABLE_SERIAL_8250_PCH | ||
568 | } | ||
569 | +#endif | ||
570 | |||
571 | up->port.fifosize = uart_config[up->port.type].fifo_size; | ||
572 | up->capabilities = uart_config[up->port.type].flags; | ||
573 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | ||
574 | |||
575 | +#ifdef DEBUG | ||
576 | + printk(KERN_DEBUG | ||
577 | + "IOH UART LOG:autoconfig: up->port.type = %d, up->port.fifosize =%d," | ||
578 | + "up->capabilities = %x, up->tx_loadsz = %d\n", up->port.type, | ||
579 | + up->port.fifosize, up->capabilities, up->tx_loadsz); | ||
580 | + | ||
581 | + printk(KERN_DEBUG | ||
582 | + "IOH UART LOG:autoconfig: port.name = %s, port.fcr = %x\n", | ||
583 | + uart_config[up->port.type].name, uart_config[up->port.type].fcr); | ||
584 | + | ||
585 | +#endif | ||
586 | + | ||
587 | if (up->port.type == PORT_UNKNOWN) | ||
588 | goto out; | ||
589 | |||
590 | @@ -1461,7 +1915,11 @@ | ||
591 | static void transmit_chars(struct uart_8250_port *up) | ||
592 | { | ||
593 | struct circ_buf *xmit = &up->port.state->xmit; | ||
594 | - int count; | ||
595 | + int count = 0; | ||
596 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
597 | + unsigned limit = 0; | ||
598 | + unsigned size = 0; | ||
599 | +#endif | ||
600 | |||
601 | if (up->port.x_char) { | ||
602 | serial_outp(up, UART_TX, up->port.x_char); | ||
603 | @@ -1478,15 +1936,53 @@ | ||
604 | return; | ||
605 | } | ||
606 | |||
607 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
608 | + if (((up->port.flags & UPF_IOH_UART) != 0)) { | ||
609 | + size = uart_circ_chars_pending(xmit); | ||
610 | + | ||
611 | + if (size > PAGE_SIZE) | ||
612 | + size = PAGE_SIZE; | ||
613 | + | ||
614 | + count = size; | ||
615 | + } | ||
616 | + | ||
617 | + else | ||
618 | +#endif | ||
619 | count = up->tx_loadsz; | ||
620 | do { | ||
621 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
622 | + if ((((up->port.flags & UPF_IOH_UART) != 0)) && (size > 0)) { | ||
623 | + ((char *)(up->buffer))[limit] = xmit->buf[xmit->tail]; | ||
624 | + limit++; | ||
625 | + | ||
626 | + } else | ||
627 | +#endif | ||
628 | serial_out(up, UART_TX, xmit->buf[xmit->tail]); | ||
629 | + | ||
630 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
631 | up->port.icount.tx++; | ||
632 | if (uart_circ_empty(xmit)) | ||
633 | break; | ||
634 | } while (--count > 0); | ||
635 | |||
636 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
637 | + if (limit > 0) { | ||
638 | + if (limit > up->tx_loadsz) { | ||
639 | + set_scatter_gather_dma_mode(up, limit); | ||
640 | +#ifdef DEBUG | ||
641 | + printk(KERN_DEBUG"transmit_chars -> Function\ | ||
642 | + set_scatter_gather_dma_mode invoked.\n"); | ||
643 | +#endif | ||
644 | + } else { | ||
645 | + set_one_shot_dma_mode(up, limit); | ||
646 | +#ifdef DEBUG | ||
647 | + printk(KERN_DEBUG"transmit_chars -> Function\ | ||
648 | + set_one_shot_dma_mode invoked.\n"); | ||
649 | +#endif | ||
650 | + } | ||
651 | + } | ||
652 | +#endif | ||
653 | + | ||
654 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
655 | uart_write_wakeup(&up->port); | ||
656 | |||
657 | @@ -1494,6 +1990,10 @@ | ||
658 | |||
659 | if (uart_circ_empty(xmit)) | ||
660 | __stop_tx(up); | ||
661 | + | ||
662 | +#ifdef DEBUG | ||
663 | + printk(KERN_DEBUG"Function transmit_chars invoked.\n"); | ||
664 | +#endif | ||
665 | } | ||
666 | |||
667 | static unsigned int check_modem_status(struct uart_8250_port *up) | ||
668 | @@ -1509,9 +2009,11 @@ | ||
669 | if (status & UART_MSR_DDSR) | ||
670 | up->port.icount.dsr++; | ||
671 | if (status & UART_MSR_DDCD) | ||
672 | - uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); | ||
673 | + uart_handle_dcd_change(&up->port, | ||
674 | + status & UART_MSR_DCD); | ||
675 | if (status & UART_MSR_DCTS) | ||
676 | - uart_handle_cts_change(&up->port, status & UART_MSR_CTS); | ||
677 | + uart_handle_cts_change(&up->port, | ||
678 | + status & UART_MSR_CTS); | ||
679 | |||
680 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | ||
681 | } | ||
682 | @@ -1533,13 +2035,36 @@ | ||
683 | |||
684 | DEBUG_INTR("status = %x...", status); | ||
685 | |||
686 | - if (status & (UART_LSR_DR | UART_LSR_BI)) | ||
687 | - receive_chars(up, &status); | ||
688 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
689 | + if ((up->dma_flag) && (up->dma_enabled)) { | ||
690 | + /* If reception has to be done through DMA. */ | ||
691 | +#ifdef DEBUG | ||
692 | + printk(KERN_DEBUG"serial8250_handle_port ->\ | ||
693 | + Proceeding to handle reception " \ | ||
694 | + "interrupt through DMA operation.\n"); | ||
695 | +#endif | ||
696 | + handle_dma_operation(up); | ||
697 | + } else { | ||
698 | +#endif | ||
699 | + | ||
700 | + if ((status & (UART_LSR_DR | UART_LSR_BI)) | ||
701 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
702 | + && (!up->dma_progress) | ||
703 | +#endif | ||
704 | + ) | ||
705 | + receive_chars(up, &status); | ||
706 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
707 | + } | ||
708 | +#endif | ||
709 | check_modem_status(up); | ||
710 | if (status & UART_LSR_THRE) | ||
711 | transmit_chars(up); | ||
712 | |||
713 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
714 | + | ||
715 | +#ifdef DEBUG | ||
716 | + printk(KERN_DEBUG"serial8250_handle_port invoked.\n"); | ||
717 | +#endif | ||
718 | } | ||
719 | |||
720 | /* | ||
721 | @@ -1575,6 +2100,26 @@ | ||
722 | |||
723 | iir = serial_in(up, UART_IIR); | ||
724 | if (!(iir & UART_IIR_NO_INT)) { | ||
725 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
726 | + /* Determing whether the receive FIFO is full. */ | ||
727 | + if ((iir & UART_IIR_RDI) && !(iir & 0x8) && | ||
728 | + ((up->port.flags & UPF_IOH_UART) != 0)) { | ||
729 | + | ||
730 | + up->dma_flag = 1; | ||
731 | + | ||
732 | +#ifdef DEBUG | ||
733 | + printk(KERN_DEBUG"serial8250_interrupt ->\ | ||
734 | + DMA Mode enabled for reception.\n"); | ||
735 | +#endif | ||
736 | + } else { | ||
737 | + up->dma_flag = 0; | ||
738 | +#ifdef DEBUG | ||
739 | + printk(KERN_DEBUG"serial8250_interrupt ->\ | ||
740 | + DMA Mode disabled for reception.\n"); | ||
741 | +#endif | ||
742 | + } | ||
743 | +#endif | ||
744 | + | ||
745 | serial8250_handle_port(up); | ||
746 | |||
747 | handled = 1; | ||
748 | @@ -1946,6 +2491,167 @@ | ||
749 | unsigned char lsr, iir; | ||
750 | int retval; | ||
751 | |||
752 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
753 | + /* Initialising the device for DMA support. */ | ||
754 | + int dma_flag = 0; | ||
755 | + up->dma_progress = 0; | ||
756 | + up->dma_enabled = 0; | ||
757 | + | ||
758 | + if ((up->port.flags & UPF_IOH_UART) != 0) { | ||
759 | + struct pci_dev pdev; | ||
760 | + | ||
761 | +/* switch((up->port.flags & 0xE000000))*/ | ||
762 | + switch ((up->port.flags & (UPF_IOH_UART | UPF_IOH_UART_BIT0 | | ||
763 | + UPF_IOH_UART_BIT1))) { | ||
764 | + case UPF_IOH_UART0: | ||
765 | +#ifdef DEBUG | ||
766 | + printk(KERN_DEBUG"serial8250_startup ->\ | ||
767 | + UART0 detected.\n"); | ||
768 | +#endif | ||
769 | + pdev.device = PCI_DEVICE_ID_IOH_UART0; | ||
770 | + up->port.mctrl |= TIOCM_RTS; | ||
771 | + break; | ||
772 | + | ||
773 | + case UPF_IOH_UART1: | ||
774 | +#ifdef DEBUG | ||
775 | + printk(KERN_DEBUG"serial8250_startup ->\ | ||
776 | + UART1 detected.\n"); | ||
777 | +#endif | ||
778 | + pdev.device = PCI_DEVICE_ID_IOH_UART1; | ||
779 | + break; | ||
780 | + | ||
781 | + case UPF_IOH_UART2: | ||
782 | +#ifdef DEBUG | ||
783 | + printk(KERN_DEBUG"serial8250_startup ->\ | ||
784 | + UART2 detected.\n"); | ||
785 | +#endif | ||
786 | + pdev.device = PCI_DEVICE_ID_IOH_UART2; | ||
787 | + break; | ||
788 | + | ||
789 | + case UPF_IOH_UART3: | ||
790 | +#ifdef DEBUG | ||
791 | + printk(KERN_DEBUG"serial8250_startup ->\ | ||
792 | + UART3 detected.\n"); | ||
793 | +#endif | ||
794 | + pdev.device = PCI_DEVICE_ID_IOH_UART3; | ||
795 | + break; | ||
796 | + | ||
797 | + default: | ||
798 | + break; | ||
799 | + } | ||
800 | + | ||
801 | + /* Allocating space for DMA buffer. */ | ||
802 | + up->rx_dma.buf = (u32)__get_free_page(GFP_KERNEL|GFP_DMA); | ||
803 | + if (!(up->rx_dma.buf)) { | ||
804 | + printk(KERN_ERR"serial8250_startup -> DMA buffer\ | ||
805 | + allocation " \ | ||
806 | + "failed for Rx DMA buffer.\n"); | ||
807 | + return -ENOMEM; | ||
808 | + } | ||
809 | + | ||
810 | + /* For transmission process. */ | ||
811 | + up->tx_dma.buf = (u32)__get_free_page(GFP_KERNEL|GFP_DMA); | ||
812 | + if (!(up->tx_dma.buf)) { | ||
813 | + free_page(up->rx_dma.buf); | ||
814 | + printk(KERN_ERR"serial8250_startup -> DMA buffer\ | ||
815 | + allocation " \ | ||
816 | + "failed for TX DMA buffer.\n"); | ||
817 | + return -ENOMEM; | ||
818 | + } | ||
819 | + | ||
820 | + /* For copying of transmit data. */ | ||
821 | + up->buffer = (u32)__get_free_page(GFP_KERNEL|GFP_DMA); | ||
822 | + if (!(up->buffer)) { | ||
823 | + free_page(up->rx_dma.buf); | ||
824 | + free_page(up->tx_dma.buf); | ||
825 | + printk(KERN_ERR"serial8250_startup -> DMA buffer\ | ||
826 | + allocation " \ | ||
827 | + "failed for Buffer.\n"); | ||
828 | + return -ENOMEM; | ||
829 | + } | ||
830 | + | ||
831 | + up->rx_dma.size = PAGE_SIZE; | ||
832 | + up->tx_dma.size = PAGE_SIZE; | ||
833 | + | ||
834 | + /* Requesting for DMA channel for reception. */ | ||
835 | + up->rx_dma.channel = ioh_request_dma(&pdev, | ||
836 | + IOH_DMA_RX_DATA_REQ0); | ||
837 | + if (up->rx_dma.channel < 0) { | ||
838 | + free_page(up->rx_dma.buf); | ||
839 | + free_page(up->tx_dma.buf); | ||
840 | + free_page(up->buffer); | ||
841 | + up->rx_dma.buf = 0; | ||
842 | + up->tx_dma.buf = 0; | ||
843 | + up->buffer = 0; | ||
844 | + | ||
845 | + printk(KERN_ERR"serial8250_startup -> DMA channel\ | ||
846 | + allocation for " \ | ||
847 | + "reception failed.\n"); | ||
848 | + return -EIO; | ||
849 | + } | ||
850 | + | ||
851 | + /* Requesting DMA channel for transmission. */ | ||
852 | + up->tx_dma.channel = ioh_request_dma(&pdev, | ||
853 | + IOH_DMA_TX_DATA_REQ0); | ||
854 | + if (up->tx_dma.channel < 0) { | ||
855 | + free_page(up->rx_dma.buf); | ||
856 | + free_page(up->tx_dma.buf); | ||
857 | + free_page(up->buffer); | ||
858 | + up->rx_dma.buf = 0; | ||
859 | + up->tx_dma.buf = 0; | ||
860 | + up->buffer = 0; | ||
861 | + ioh_free_dma(up->rx_dma.channel); | ||
862 | + | ||
863 | + printk(KERN_ERR"serial8250_startup -> DMA channel\ | ||
864 | + allocation for " \ | ||
865 | + "transmission failed.\n"); | ||
866 | + return -EIO; | ||
867 | + } | ||
868 | + | ||
869 | + /* Performing DMA settings for reception. */ | ||
870 | + { | ||
871 | + u32 in_address; | ||
872 | + u32 out_address; | ||
873 | + u32 size; | ||
874 | + int channel = up->rx_dma.channel; | ||
875 | + struct ioh_dma_mode_param mode = { | ||
876 | + .TransferDirection = IOH_DMA_DIR_IN_TO_OUT, | ||
877 | + .DMASizeType = IOH_DMA_SIZE_TYPE_8BIT, | ||
878 | + .DMATransferMode = DMA_ONE_SHOT_MODE | ||
879 | + }; | ||
880 | + | ||
881 | + /* Mapping the DMA buffer to DMA accessible area and | ||
882 | + obtaining its base address. */ | ||
883 | + out_address = dma_map_single(up->port.dev, | ||
884 | + (void *)up->rx_dma.buf, | ||
885 | + up->rx_dma.size, | ||
886 | + DMA_FROM_DEVICE); | ||
887 | + in_address = up->port.mapbase + | ||
888 | + (map_8250_in_reg(up, UART_RX)); | ||
889 | + size = up->rx_fifo_size; | ||
890 | + up->rx_dma.phy_addr = out_address; | ||
891 | + | ||
892 | + /* Setting the DMA settings. */ | ||
893 | + (void)ioh_set_dma_mode(channel, mode); | ||
894 | + (void)ioh_set_dma_addr(channel, in_address, | ||
895 | + out_address); | ||
896 | + (void)ioh_set_dma_count(channel, size); | ||
897 | + (void)ioh_dma_set_callback(channel, ioh_dma_rx_callback, | ||
898 | + (u32)up); | ||
899 | + } | ||
900 | + | ||
901 | + dma_flag = 1; | ||
902 | + | ||
903 | +#ifdef DEBUG | ||
904 | + printk(KERN_DEBUG"serial8250_startup -> Buffer Allocation\ | ||
905 | + successful and DMA " \ | ||
906 | + "channels obtained are Reception: %d\ | ||
907 | + Transmission: %d.\n", \ | ||
908 | + up->rx_dma.channel, up->tx_dma.channel); | ||
909 | +#endif | ||
910 | + } | ||
911 | +#endif | ||
912 | + | ||
913 | up->capabilities = uart_config[up->port.type].flags; | ||
914 | up->mcr = 0; | ||
915 | |||
916 | @@ -1996,6 +2702,21 @@ | ||
917 | (serial_inp(up, UART_LSR) == 0xff)) { | ||
918 | printk(KERN_INFO "ttyS%d: LSR safety check engaged!\n", | ||
919 | serial_index(&up->port)); | ||
920 | + | ||
921 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
922 | + /* Releasing the DMA resources on failure.*/ | ||
923 | + if (dma_flag == 1) { | ||
924 | + ioh_free_dma(up->rx_dma.channel); | ||
925 | + ioh_free_dma(up->tx_dma.channel); | ||
926 | + free_page(up->rx_dma.buf); | ||
927 | + free_page(up->tx_dma.buf); | ||
928 | + free_page(up->buffer); | ||
929 | + up->rx_dma.buf = 0; | ||
930 | + up->tx_dma.buf = 0; | ||
931 | + up->buffer = 0; | ||
932 | + } | ||
933 | +#endif | ||
934 | + | ||
935 | return -ENODEV; | ||
936 | } | ||
937 | |||
938 | @@ -2008,9 +2729,11 @@ | ||
939 | serial_outp(up, UART_LCR, 0xbf); | ||
940 | |||
941 | fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); | ||
942 | - serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); | ||
943 | + serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | | ||
944 | + UART_FCTR_RX); | ||
945 | serial_outp(up, UART_TRG, UART_TRG_96); | ||
946 | - serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX); | ||
947 | + serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | | ||
948 | + UART_FCTR_TX); | ||
949 | serial_outp(up, UART_TRG, UART_TRG_96); | ||
950 | |||
951 | serial_outp(up, UART_LCR, 0); | ||
952 | @@ -2076,8 +2799,22 @@ | ||
953 | mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout)); | ||
954 | } else { | ||
955 | retval = serial_link_irq_chain(up); | ||
956 | - if (retval) | ||
957 | + if (retval) { | ||
958 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
959 | + /* Releasing the DMA resources on failure.*/ | ||
960 | + if (dma_flag == 1) { | ||
961 | + ioh_free_dma(up->rx_dma.channel); | ||
962 | + ioh_free_dma(up->tx_dma.channel); | ||
963 | + free_page(up->rx_dma.buf); | ||
964 | + free_page(up->tx_dma.buf); | ||
965 | + free_page(up->buffer); | ||
966 | + up->rx_dma.buf = 0; | ||
967 | + up->tx_dma.buf = 0; | ||
968 | + up->buffer = 0; | ||
969 | + } | ||
970 | + #endif | ||
971 | return retval; | ||
972 | + } | ||
973 | } | ||
974 | |||
975 | /* | ||
976 | @@ -2124,7 +2861,8 @@ | ||
977 | if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { | ||
978 | if (!(up->bugs & UART_BUG_TXEN)) { | ||
979 | up->bugs |= UART_BUG_TXEN; | ||
980 | - pr_debug("ttyS%d - enabling bad tx status workarounds\n", | ||
981 | + pr_debug("ttyS%d - enabling bad tx status\ | ||
982 | + workarounds\n", | ||
983 | serial_index(port)); | ||
984 | } | ||
985 | } else { | ||
986 | @@ -2172,6 +2910,31 @@ | ||
987 | struct uart_8250_port *up = (struct uart_8250_port *)port; | ||
988 | unsigned long flags; | ||
989 | |||
990 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
991 | + /* Releasing the DMA resources on exit.*/ | ||
992 | + if ((up->port.flags & UPF_IOH_UART) != 0) { | ||
993 | + if (up->rx_dma.channel >= 0) | ||
994 | + ioh_free_dma(up->rx_dma.channel); | ||
995 | + if (up->tx_dma.channel >= 0) | ||
996 | + ioh_free_dma(up->tx_dma.channel); | ||
997 | + | ||
998 | + if (up->rx_dma.buf) | ||
999 | + free_page(up->rx_dma.buf); | ||
1000 | + if (up->tx_dma.buf) | ||
1001 | + free_page(up->tx_dma.buf); | ||
1002 | + if (up->buffer) | ||
1003 | + free_page(up->buffer); | ||
1004 | + | ||
1005 | + up->rx_dma.buf = 0; | ||
1006 | + up->tx_dma.buf = 0; | ||
1007 | + up->buffer = 0; | ||
1008 | + | ||
1009 | +#ifdef DEBUG | ||
1010 | + printk(KERN_DEBUG"serial8250_shutdown -> DMA buffers and\ | ||
1011 | + channels released.\n"); | ||
1012 | +#endif | ||
1013 | + } | ||
1014 | +#endif | ||
1015 | /* | ||
1016 | * Disable interrupts from this port | ||
1017 | */ | ||
1018 | @@ -2214,7 +2977,8 @@ | ||
1019 | serial_unlink_irq_chain(up); | ||
1020 | } | ||
1021 | |||
1022 | -static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) | ||
1023 | +static unsigned int serial8250_get_divisor(struct uart_port *port, | ||
1024 | + unsigned int baud) | ||
1025 | { | ||
1026 | unsigned int quot; | ||
1027 | |||
1028 | @@ -2242,6 +3006,7 @@ | ||
1029 | unsigned char cval, fcr = 0; | ||
1030 | unsigned long flags; | ||
1031 | unsigned int baud, quot; | ||
1032 | + unsigned int bdrate; | ||
1033 | |||
1034 | switch (termios->c_cflag & CSIZE) { | ||
1035 | case CS5: | ||
1036 | @@ -2278,6 +3043,11 @@ | ||
1037 | port->uartclk / 16); | ||
1038 | quot = serial8250_get_divisor(port, baud); | ||
1039 | |||
1040 | +#ifdef DEBUG | ||
1041 | + printk(KERN_DEBUG "IOH UART LOG:max_baud: %d\n,baud :%d\n quot:%d\n" | ||
1042 | + , max_baud, baud, quot); | ||
1043 | +#endif | ||
1044 | + | ||
1045 | /* | ||
1046 | * Oxford Semi 952 rev B workaround | ||
1047 | */ | ||
1048 | @@ -2285,12 +3055,37 @@ | ||
1049 | quot++; | ||
1050 | |||
1051 | if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) { | ||
1052 | - if (baud < 2400) | ||
1053 | + if (baud < 2400) { | ||
1054 | fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; | ||
1055 | - else | ||
1056 | - fcr = uart_config[up->port.type].fcr; | ||
1057 | + | ||
1058 | +#ifdef ENABLE_SERIAL_8250_PCH | ||
1059 | + if ((up->port.flags & UPF_IOH_UART) != 0) | ||
1060 | + /*This enables 256 byte FIFO | ||
1061 | + for UART 0.*/ | ||
1062 | + fcr |= UART_FCR7_64BYTE; | ||
1063 | + | ||
1064 | +#endif | ||
1065 | + } else | ||
1066 | + fcr = uart_config[up->port.type].fcr; | ||
1067 | } | ||
1068 | |||
1069 | +#if defined(ENABLE_SERIAL_8250_PCH) && defined(ENABLE_PCH_DMA_FEATURE) | ||
1070 | + /* Deciding whether to use DMA feature or not.*/ | ||
1071 | + if ((baud >= 38400) && ((up->port.flags & UPF_IOH_UART) != 0)) | ||
1072 | + up->dma_enabled = 1; | ||
1073 | + else | ||
1074 | + up->dma_enabled = 0; | ||
1075 | + | ||
1076 | + | ||
1077 | + get_rx_fifo_size(up, fcr); | ||
1078 | + | ||
1079 | +#ifdef DEBUG | ||
1080 | + printk(KERN_DEBUG"serial8250_set_termios -> The Rx fifo size is: %u\n", | ||
1081 | + up->rx_fifo_size); | ||
1082 | +#endif | ||
1083 | + | ||
1084 | +#endif | ||
1085 | + | ||
1086 | /* | ||
1087 | * MCR-based auto flow control. When AFE is enabled, RTS will be | ||
1088 | * deasserted when the receive FIFO contains more characters than | ||
1089 | @@ -2409,8 +3204,22 @@ | ||
1090 | serial8250_set_mctrl(&up->port, up->port.mctrl); | ||
1091 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1092 | /* Don't rewrite B0 */ | ||
1093 | - if (tty_termios_baud_rate(termios)) | ||
1094 | + | ||
1095 | + bdrate = tty_termios_baud_rate(termios); | ||
1096 | + | ||
1097 | +#ifdef DEBUG | ||
1098 | + printk(KERN_DEBUG "tty_termios_baud_rate value:%d\n", bdrate); | ||
1099 | +#endif | ||
1100 | + | ||
1101 | + if (bdrate) { | ||
1102 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
1103 | + | ||
1104 | +#ifdef DEBUG | ||
1105 | + printk(KERN_DEBUG "termios->c_ispeed:%d\n,\ | ||
1106 | + termios->c_ospeed:%d\n " | ||
1107 | + , termios->c_ispeed, termios->c_ospeed); | ||
1108 | +#endif | ||
1109 | + } | ||
1110 | } | ||
1111 | |||
1112 | static void | ||
1113 | @@ -2580,18 +3389,24 @@ | ||
1114 | if (ret < 0) | ||
1115 | probeflags &= ~PROBE_RSA; | ||
1116 | |||
1117 | + | ||
1118 | if (up->port.iotype != up->cur_iotype) | ||
1119 | set_io_from_upio(port); | ||
1120 | |||
1121 | + | ||
1122 | if (flags & UART_CONFIG_TYPE) | ||
1123 | autoconfig(up, probeflags); | ||
1124 | + | ||
1125 | if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) | ||
1126 | autoconfig_irq(up); | ||
1127 | |||
1128 | + | ||
1129 | if (up->port.type != PORT_RSA && probeflags & PROBE_RSA) | ||
1130 | serial8250_release_rsa_resource(up); | ||
1131 | + | ||
1132 | if (up->port.type == PORT_UNKNOWN) | ||
1133 | serial8250_release_std_resource(up); | ||
1134 | + | ||
1135 | } | ||
1136 | |||
1137 | static int | ||
1138 | @@ -2686,6 +3501,7 @@ | ||
1139 | up->port.regshift = old_serial_port[i].iomem_reg_shift; | ||
1140 | set_io_from_upio(&up->port); | ||
1141 | up->port.irqflags |= irqflag; | ||
1142 | + | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | @@ -2967,7 +3783,8 @@ | ||
1147 | port.irqflags |= irqflag; | ||
1148 | ret = serial8250_register_port(&port); | ||
1149 | if (ret < 0) { | ||
1150 | - dev_err(&dev->dev, "unable to register port at index %d " | ||
1151 | + dev_err(&dev->dev, "unable to register port at\ | ||
1152 | + index %d " | ||
1153 | "(IO%lx MEM%llx IRQ%d): %d\n", i, | ||
1154 | p->iobase, (unsigned long long)p->mapbase, | ||
1155 | p->irq, ret); | ||
1156 | @@ -3044,7 +3861,8 @@ | ||
1157 | */ | ||
1158 | static DEFINE_MUTEX(serial_mutex); | ||
1159 | |||
1160 | -static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) | ||
1161 | +static | ||
1162 | +struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) | ||
1163 | { | ||
1164 | int i; | ||
1165 | |||
1166 | @@ -3251,7 +4069,8 @@ | ||
1167 | " (unsafe)"); | ||
1168 | |||
1169 | module_param(nr_uarts, uint, 0644); | ||
1170 | -MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | ||
1171 | +MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. \ | ||
1172 | + (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); | ||
1173 | |||
1174 | module_param(skip_txen_test, uint, 0644); | ||
1175 | MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time"); | ||
1176 | diff -urN linux-2.6.33.1/drivers/serial/8250_pch.h topcliff-2.6.33.1/drivers/serial/8250_pch.h | ||
1177 | --- linux-2.6.33.1/drivers/serial/8250_pch.h 1970-01-01 09:00:00.000000000 +0900 | ||
1178 | +++ topcliff-2.6.33.1/drivers/serial/8250_pch.h 2010-03-23 10:34:44.000000000 +0900 | ||
1179 | @@ -0,0 +1,57 @@ | ||
1180 | +/*! | ||
1181 | + * @file 8250_pch.h | ||
1182 | + * @brief Provides the macro definitions used by all files. | ||
1183 | + * @version 1.0.0.0 | ||
1184 | + * @section | ||
1185 | + * This program is free software; you can redistribute it and/or modify | ||
1186 | + * it under the terms of the GNU General Public License as published by | ||
1187 | + * the Free Software Foundation; version 2 of the License. | ||
1188 | + * | ||
1189 | + * This program is distributed in the hope that it will be useful, | ||
1190 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1191 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1192 | + * GNU General Public License for more details. | ||
1193 | + * | ||
1194 | + * You should have received a copy of the GNU General Public License | ||
1195 | + * along with this program; if not, write to the Free Software | ||
1196 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
1197 | + */ | ||
1198 | + | ||
1199 | +/* | ||
1200 | + * History: | ||
1201 | + * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. | ||
1202 | + * All rights reserved. | ||
1203 | + * | ||
1204 | + * created: | ||
1205 | + * OKISEMI 03/16/2010 | ||
1206 | + * | ||
1207 | + */ | ||
1208 | + | ||
1209 | +#ifndef __IOH_8250_PCH_H__ | ||
1210 | +#define __IOH_8250_PCH_H__ | ||
1211 | + | ||
1212 | +#define PORT_IOH_256FIFO 128 /* IOH UART with 256 byte FIFO */ | ||
1213 | +#define PORT_IOH_64FIFO 129 /* IOH UART with 64 byte FIFO */ | ||
1214 | + | ||
1215 | +/* flags for IOH port detection */ | ||
1216 | +/* The below fields are used to identify the IOH UART port 0 to 3 */ | ||
1217 | +#define UPF_IOH_UART_BIT0 ((__force upf_t) (1 << 17)) | ||
1218 | +#define UPF_IOH_UART_BIT1 ((__force upf_t) (1 << 18)) | ||
1219 | + | ||
1220 | +#define UPF_IOH_UART ((__force upf_t) (1 << 19)) | ||
1221 | +#define UPF_IOH_UART0 ((UPF_IOH_UART) | (0)) | ||
1222 | +#define UPF_IOH_UART1 ((UPF_IOH_UART) | ((__force upf_t) (UPF_IOH_UART_BIT0))) | ||
1223 | +#define UPF_IOH_UART2 ((UPF_IOH_UART) | ((__force upf_t) (UPF_IOH_UART_BIT1))) | ||
1224 | +#define UPF_IOH_UART3 ((UPF_IOH_UART) | ((__force upf_t) (UPF_IOH_UART_BIT0 |\ | ||
1225 | + UPF_IOH_UART_BIT1))) | ||
1226 | +#define UPF_IOH_UART_64_FIFO ((__force upf_t) (UPF_IOH_UART3)) | ||
1227 | + | ||
1228 | +#define UART_FCR7_256BYTE 0x20 /* Go into 256 byte FIFO mode (IOH UART) */ | ||
1229 | + | ||
1230 | +/* Intel IOH GE UART PCI device IDs */ | ||
1231 | +#define PCI_DEVICE_ID_IOH_UART0 (0x8811) | ||
1232 | +#define PCI_DEVICE_ID_IOH_UART1 (0x8812) | ||
1233 | +#define PCI_DEVICE_ID_IOH_UART2 (0x8813) | ||
1234 | +#define PCI_DEVICE_ID_IOH_UART3 (0x8814) | ||
1235 | + | ||
1236 | +#endif | ||
1237 | diff -urN linux-2.6.33.1/drivers/serial/8250_pci.c topcliff-2.6.33.1/drivers/serial/8250_pci.c | ||
1238 | --- linux-2.6.33.1/drivers/serial/8250_pci.c 2010-03-16 01:09:39.000000000 +0900 | ||
1239 | +++ topcliff-2.6.33.1/drivers/serial/8250_pci.c 2010-03-23 10:34:44.000000000 +0900 | ||
1240 | @@ -14,6 +14,7 @@ | ||
1241 | #include <linux/module.h> | ||
1242 | #include <linux/init.h> | ||
1243 | #include <linux/pci.h> | ||
1244 | +#include <linux/pci_ids.h> | ||
1245 | #include <linux/string.h> | ||
1246 | #include <linux/kernel.h> | ||
1247 | #include <linux/slab.h> | ||
1248 | @@ -27,7 +28,7 @@ | ||
1249 | #include <asm/io.h> | ||
1250 | |||
1251 | #include "8250.h" | ||
1252 | - | ||
1253 | +#include "8250_pch.h" | ||
1254 | #undef SERIAL_DEBUG_PCI | ||
1255 | |||
1256 | /* | ||
1257 | @@ -726,6 +727,87 @@ | ||
1258 | #define NI8430_PORTCON 0x0f | ||
1259 | #define NI8430_PORTCON_TXVR_ENABLE (1 << 3) | ||
1260 | |||
1261 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1262 | + | ||
1263 | +static int | ||
1264 | +pci_ioh_init(struct pci_dev *dev) | ||
1265 | +{ | ||
1266 | + int retval = 0; | ||
1267 | + | ||
1268 | +#ifdef DEBUG | ||
1269 | + printk(KERN_DEBUG "IOH UART LOG:function pci_ioh_init invoked \n"); | ||
1270 | + | ||
1271 | + printk(KERN_DEBUG "IOH UART LOG:function pci_ioh_init->pci_enable_wake invoked \n"); | ||
1272 | +#endif | ||
1273 | + | ||
1274 | + /* disable Wake on UART */ | ||
1275 | + pci_enable_wake(dev, PCI_D3hot, 0); | ||
1276 | + | ||
1277 | +#ifdef DEBUG | ||
1278 | + printk(KERN_DEBUG "IOH UART LOG:function pci_ioh_init return = %d\n", | ||
1279 | + retval); | ||
1280 | +#endif | ||
1281 | + | ||
1282 | + return retval; | ||
1283 | +} | ||
1284 | + | ||
1285 | +static int | ||
1286 | +pci_ioh_setup(struct serial_private *priv, const struct pciserial_board *board, | ||
1287 | + struct uart_port *port, int idx) | ||
1288 | +{ | ||
1289 | + int retval = 1 ; | ||
1290 | + unsigned int bar = 0; | ||
1291 | + unsigned int offset = 0; | ||
1292 | + | ||
1293 | + if (idx == 0) { | ||
1294 | + /* IOH UART has only 1 channel per device */ | ||
1295 | + switch (priv->dev->device) { | ||
1296 | + case PCI_DEVICE_ID_IOH_UART0: | ||
1297 | + port->flags |= UPF_IOH_UART0; | ||
1298 | + break; | ||
1299 | + | ||
1300 | + case PCI_DEVICE_ID_IOH_UART1: | ||
1301 | + port->flags |= UPF_IOH_UART1; | ||
1302 | + break; | ||
1303 | + | ||
1304 | + case PCI_DEVICE_ID_IOH_UART2: | ||
1305 | + port->flags |= UPF_IOH_UART2; | ||
1306 | + break; | ||
1307 | + | ||
1308 | + case PCI_DEVICE_ID_IOH_UART3: | ||
1309 | + port->flags |= UPF_IOH_UART3; | ||
1310 | + break; | ||
1311 | + | ||
1312 | + default: | ||
1313 | + break; | ||
1314 | + } | ||
1315 | + | ||
1316 | + retval = setup_port(priv, port, bar, offset, board->reg_shift); | ||
1317 | + | ||
1318 | + #ifdef ENABLE_PCH_DMA_FEATURE | ||
1319 | + /* Obtaing the Memory Map base for DMA operations. */ | ||
1320 | + port->mapbase = pci_resource_start(priv->dev, 1); | ||
1321 | + #ifdef DEBUG | ||
1322 | + printk(KERN_DEBUG"pci_ioh_setup -> The Map Base has been obtained.\n"); | ||
1323 | + #endif | ||
1324 | + #endif | ||
1325 | + } | ||
1326 | + | ||
1327 | + | ||
1328 | +#ifdef DEBUG | ||
1329 | + printk(KERN_DEBUG "pci_ioh_setup -> Function pci_ioh_setup invoked \n"); | ||
1330 | + printk(KERN_DEBUG "pci_ioh_setup -> board.base_baud = %d, flags = %d,\ | ||
1331 | + num_ports = %d,reg_shift = %d\n", | ||
1332 | + board->base_baud, board->flags, | ||
1333 | + board->num_ports, board->reg_shift); | ||
1334 | + printk(KERN_DEBUG "pci_ioh_setup -> port->flags =%x\n", port->flags); | ||
1335 | + printk(KERN_DEBUG "Function pci_ioh_setup return = %d\n", retval); | ||
1336 | + | ||
1337 | +#endif | ||
1338 | + return retval; | ||
1339 | +} | ||
1340 | +#endif | ||
1341 | + | ||
1342 | static int | ||
1343 | pci_ni8430_setup(struct serial_private *priv, | ||
1344 | const struct pciserial_board *board, | ||
1345 | @@ -918,7 +1000,8 @@ | ||
1346 | (dev->device & 0xF000) != 0xC000) | ||
1347 | return 0; | ||
1348 | |||
1349 | - p = pci_iomap(dev, 0, 5); | ||
1350 | + /*p = pci_iomap(dev, 0, 5);*/ | ||
1351 | + p = pci_iomap(dev, 1, 5); | ||
1352 | if (p == NULL) | ||
1353 | return -ENOMEM; | ||
1354 | |||
1355 | @@ -1393,6 +1476,43 @@ | ||
1356 | .setup = pci_default_setup, | ||
1357 | }, | ||
1358 | /* | ||
1359 | + * IOH UART | ||
1360 | + */ | ||
1361 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1362 | + { | ||
1363 | + .vendor = PCI_VENDOR_ID_INTEL, | ||
1364 | + .device = PCI_DEVICE_ID_IOH_UART0, | ||
1365 | + .subvendor = PCI_ANY_ID, | ||
1366 | + .subdevice = PCI_ANY_ID, | ||
1367 | + .init = pci_ioh_init, | ||
1368 | + .setup = pci_ioh_setup, | ||
1369 | + }, | ||
1370 | + { | ||
1371 | + .vendor = PCI_VENDOR_ID_INTEL, | ||
1372 | + .device = PCI_DEVICE_ID_IOH_UART1, | ||
1373 | + .subvendor = PCI_ANY_ID, | ||
1374 | + .subdevice = PCI_ANY_ID, | ||
1375 | + .init = pci_ioh_init, | ||
1376 | + .setup = pci_ioh_setup, | ||
1377 | + }, | ||
1378 | + { | ||
1379 | + .vendor = PCI_VENDOR_ID_INTEL, | ||
1380 | + .device = PCI_DEVICE_ID_IOH_UART2, | ||
1381 | + .subvendor = PCI_ANY_ID, | ||
1382 | + .subdevice = PCI_ANY_ID, | ||
1383 | + .init = pci_ioh_init, | ||
1384 | + .setup = pci_ioh_setup, | ||
1385 | + }, | ||
1386 | + { | ||
1387 | + .vendor = PCI_VENDOR_ID_INTEL, | ||
1388 | + .device = PCI_DEVICE_ID_IOH_UART3, | ||
1389 | + .subvendor = PCI_ANY_ID, | ||
1390 | + .subdevice = PCI_ANY_ID, | ||
1391 | + .init = pci_ioh_init, | ||
1392 | + .setup = pci_ioh_setup, | ||
1393 | + }, | ||
1394 | +#endif | ||
1395 | + /* | ||
1396 | * Default "match everything" terminator entry | ||
1397 | */ | ||
1398 | { | ||
1399 | @@ -1571,6 +1691,10 @@ | ||
1400 | pbn_ADDIDATA_PCIe_2_3906250, | ||
1401 | pbn_ADDIDATA_PCIe_4_3906250, | ||
1402 | pbn_ADDIDATA_PCIe_8_3906250, | ||
1403 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1404 | + pbn_ioh_uart_8L_256FIFO, /* ioh 8 Line UART with 256 byte FIFO */ | ||
1405 | + pbn_ioh_uart_2L_64FIFO /* ioh 2 Line UART with 64 byte FIFO */ | ||
1406 | +#endif | ||
1407 | }; | ||
1408 | |||
1409 | /* | ||
1410 | @@ -2228,6 +2352,27 @@ | ||
1411 | .uart_offset = 0x200, | ||
1412 | .first_offset = 0x1000, | ||
1413 | }, | ||
1414 | + | ||
1415 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1416 | + | ||
1417 | + /* | ||
1418 | + * IOH UART | ||
1419 | + */ | ||
1420 | + [pbn_ioh_uart_8L_256FIFO] = { | ||
1421 | + .flags = FL_BASE0, | ||
1422 | + .num_ports = 1, | ||
1423 | + .base_baud = 115200, /* OKISEMI For LSI */ | ||
1424 | + .reg_shift = 0, | ||
1425 | + }, | ||
1426 | + | ||
1427 | + [pbn_ioh_uart_2L_64FIFO] = { | ||
1428 | + .flags = FL_BASE0, | ||
1429 | + .num_ports = 1, | ||
1430 | + .base_baud = 115200, /* OKISEMI For LSI*/ | ||
1431 | + .reg_shift = 0, | ||
1432 | + }, | ||
1433 | +#endif | ||
1434 | + | ||
1435 | }; | ||
1436 | |||
1437 | static const struct pci_device_id softmodem_blacklist[] = { | ||
1438 | @@ -2473,8 +2618,20 @@ | ||
1439 | return -EINVAL; | ||
1440 | } | ||
1441 | |||
1442 | +#ifdef DEBUG | ||
1443 | + printk(KERN_DEBUG "IOH UART LOG:function pciserial_init_one ent->vendor" | ||
1444 | + " = %x\n, ent->device = %x, ent->driver_data = %ld\n ", | ||
1445 | + ent->vendor, ent->device, ent->driver_data); | ||
1446 | +#endif | ||
1447 | + | ||
1448 | board = &pci_boards[ent->driver_data]; | ||
1449 | |||
1450 | +#ifdef DEBUG | ||
1451 | + printk(KERN_DEBUG "IOH UART LOG:function pciserial_init_one board->" | ||
1452 | + "base_baud = %u\n, board->flags = %d, board->num_ports = %d\n " | ||
1453 | + , board->base_baud, board->flags, board->num_ports); | ||
1454 | +#endif | ||
1455 | + | ||
1456 | rc = pci_enable_device(dev); | ||
1457 | if (rc) | ||
1458 | return rc; | ||
1459 | @@ -2540,6 +2697,17 @@ | ||
1460 | if (priv) | ||
1461 | pciserial_suspend_ports(priv); | ||
1462 | |||
1463 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1464 | + | ||
1465 | +#ifdef DEBUG | ||
1466 | + printk(KERN_DEBUG "IOH UART LOG:pciserial_suspend_one->pci_enable_wake" | ||
1467 | + "invoked \n"); | ||
1468 | +#endif | ||
1469 | + | ||
1470 | + | ||
1471 | + pci_enable_wake(dev, PCI_D3hot, 1); | ||
1472 | +#endif | ||
1473 | + | ||
1474 | pci_save_state(dev); | ||
1475 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
1476 | return 0; | ||
1477 | @@ -2561,6 +2729,17 @@ | ||
1478 | /* FIXME: We cannot simply error out here */ | ||
1479 | if (err) | ||
1480 | printk(KERN_ERR "pciserial: Unable to re-enable ports, trying to continue.\n"); | ||
1481 | + | ||
1482 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1483 | + | ||
1484 | +#ifdef DEBUG | ||
1485 | + printk(KERN_DEBUG "IOH UART LOG:pciserial_resume_one->pci_enable_wake" | ||
1486 | + "invoked \n"); | ||
1487 | +#endif | ||
1488 | + | ||
1489 | + pci_enable_wake(dev, PCI_D3hot, 0); | ||
1490 | +#endif | ||
1491 | + | ||
1492 | pciserial_resume_ports(priv); | ||
1493 | } | ||
1494 | return 0; | ||
1495 | @@ -3649,6 +3828,48 @@ | ||
1496 | 0, 0, pbn_b0_1_115200 }, | ||
1497 | |||
1498 | /* | ||
1499 | + * IOH UART | ||
1500 | + */ | ||
1501 | +#if defined(ENABLE_SERIAL_8250_PCH) | ||
1502 | + | ||
1503 | + { PCI_VENDOR_ID_INTEL, | ||
1504 | + /*device id for ioh uart with 8 i/o lines and 256 byte fifo. */ | ||
1505 | + PCI_DEVICE_ID_IOH_UART0, | ||
1506 | + PCI_ANY_ID, | ||
1507 | + PCI_ANY_ID, | ||
1508 | + 0, | ||
1509 | + 0, | ||
1510 | + pbn_ioh_uart_8L_256FIFO }, | ||
1511 | + | ||
1512 | + { PCI_VENDOR_ID_INTEL, | ||
1513 | + /*device id for ioh uart with 2 i/o lines and 256 byte fifo. */ | ||
1514 | + PCI_DEVICE_ID_IOH_UART1, | ||
1515 | + PCI_ANY_ID, | ||
1516 | + PCI_ANY_ID, | ||
1517 | + 0, | ||
1518 | + 0, | ||
1519 | + pbn_ioh_uart_2L_64FIFO }, | ||
1520 | + | ||
1521 | + { PCI_VENDOR_ID_INTEL, | ||
1522 | + /*device id for ioh uart with 8 i/o lines and 64 byte fifo. */ | ||
1523 | + PCI_DEVICE_ID_IOH_UART2, | ||
1524 | + PCI_ANY_ID, | ||
1525 | + PCI_ANY_ID, | ||
1526 | + 0, | ||
1527 | + 0, | ||
1528 | + pbn_ioh_uart_2L_64FIFO }, | ||
1529 | + | ||
1530 | + { PCI_VENDOR_ID_INTEL, | ||
1531 | + /*device id for ioh uart with 2 i/o lines and 64 byte fifo. */ | ||
1532 | + PCI_DEVICE_ID_IOH_UART3, | ||
1533 | + PCI_ANY_ID, | ||
1534 | + PCI_ANY_ID, | ||
1535 | + 0, | ||
1536 | + 0, | ||
1537 | + pbn_ioh_uart_2L_64FIFO }, | ||
1538 | +#endif | ||
1539 | + | ||
1540 | + /* | ||
1541 | * These entries match devices with class COMMUNICATION_SERIAL, | ||
1542 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | ||
1543 | */ | ||
1544 | diff -urN linux-2.6.33.1/drivers/serial/Kconfig topcliff-2.6.33.1/drivers/serial/Kconfig | ||
1545 | --- linux-2.6.33.1/drivers/serial/Kconfig 2010-03-16 01:09:39.000000000 +0900 | ||
1546 | +++ topcliff-2.6.33.1/drivers/serial/Kconfig 2010-03-23 10:34:44.000000000 +0900 | ||
1547 | @@ -89,6 +89,21 @@ | ||
1548 | disable this feature if you only need legacy serial support. | ||
1549 | Saves about 9K. | ||
1550 | |||
1551 | +config SERIAL_8250_PCH | ||
1552 | + tristate "PCH PCI serial device support" | ||
1553 | + depends on SERIAL_8250 && PCI && SERIAL_8250_PCI | ||
1554 | + default SERIAL_8250_PCI | ||
1555 | + help | ||
1556 | + This makes the PCH PCI serial driver to support high speed PCH serial ports. | ||
1557 | + | ||
1558 | +config SERIAL_8250_PCH_DMA | ||
1559 | + bool "Enable DMA mode of PCH PCI serial device" | ||
1560 | + depends on SERIAL_8250_PCH | ||
1561 | + select PCH_UART_DMA | ||
1562 | + default y | ||
1563 | + help | ||
1564 | + This makes the PCH PCI serial driver with DMA mode. | ||
1565 | + | ||
1566 | config SERIAL_8250_PNP | ||
1567 | tristate "8250/16550 PNP device support" if EMBEDDED | ||
1568 | depends on SERIAL_8250 && PNP | ||
1569 | diff -urN linux-2.6.33.1/drivers/serial/Makefile topcliff-2.6.33.1/drivers/serial/Makefile | ||
1570 | --- linux-2.6.33.1/drivers/serial/Makefile 2010-03-16 01:09:39.000000000 +0900 | ||
1571 | +++ topcliff-2.6.33.1/drivers/serial/Makefile 2010-03-23 10:34:44.000000000 +0900 | ||
1572 | @@ -1,6 +1,17 @@ | ||
1573 | # | ||
1574 | # Makefile for the kernel serial device drivers. | ||
1575 | # | ||
1576 | +# | ||
1577 | +#This is needed to enable ioh dma# | ||
1578 | +#EXTRA_CFLAGS +=-DENABLE_IOH_DMA_FEATURE | ||
1579 | +ifdef CONFIG_SERIAL_8250_PCH | ||
1580 | +EXTRA_CFLAGS +=-DENABLE_SERIAL_8250_PCH | ||
1581 | +endif | ||
1582 | + | ||
1583 | +ifdef CONFIG_PCH_UART_DMA | ||
1584 | +EXTRA_CFLAGS +=-DENABLE_PCH_DMA_FEATURE | ||
1585 | +EXTRA_CFLAGS +=-Idrivers/dma/pch_dma/ | ||
1586 | +endif | ||
1587 | |||
1588 | obj-$(CONFIG_SERIAL_CORE) += serial_core.o | ||
1589 | obj-$(CONFIG_SERIAL_21285) += 21285.o | ||