cyclades: tiocm cleanup
[linux-2.6-block.git] / drivers / char / cyclades.c
CommitLineData
1da177e4
LT
1#undef BLOCKMOVE
2#define Z_WAKE
3#undef Z_EXT_CHARS_IN_BUFFER
1da177e4
LT
4
5/*
6 * linux/drivers/char/cyclades.c
7 *
8 * This file contains the driver for the Cyclades async multiport
9 * serial boards.
10 *
11 * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
12 * Modified and maintained by Marcio Saito <marcio@cyclades.com>.
1da177e4 13 *
ebdb5135 14 * Copyright (C) 2007-2009 Jiri Slaby <jirislaby@gmail.com>
1da177e4
LT
15 *
16 * Much of the design and some of the code came from serial.c
17 * which was copyright (C) 1991, 1992 Linus Torvalds. It was
18 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
19 * and then fixed as suggested by Michael K. Johnson 12/12/92.
c8e1693a 20 * Converted to pci probing and cleaned up by Jiri Slaby.
1da177e4 21 *
1da177e4
LT
22 */
23
ebdb5135 24#define CY_VERSION "2.6"
096dcfce 25
1da177e4
LT
26/* If you need to install more boards than NR_CARDS, change the constant
27 in the definition below. No other change is necessary to support up to
28 eight boards. Beyond that you'll have to extend cy_isa_addresses. */
29
02f1175c 30#define NR_CARDS 4
1da177e4
LT
31
32/*
33 If the total number of ports is larger than NR_PORTS, change this
34 constant in the definition below. No other change is necessary to
35 support more boards/ports. */
36
02f1175c 37#define NR_PORTS 256
1da177e4 38
1da177e4
LT
39#define ZO_V1 0
40#define ZO_V2 1
41#define ZE_V1 2
42
43#define SERIAL_PARANOIA_CHECK
44#undef CY_DEBUG_OPEN
45#undef CY_DEBUG_THROTTLE
46#undef CY_DEBUG_OTHER
47#undef CY_DEBUG_IO
48#undef CY_DEBUG_COUNT
49#undef CY_DEBUG_DTR
50#undef CY_DEBUG_WAIT_UNTIL_SENT
51#undef CY_DEBUG_INTERRUPTS
52#undef CY_16Y_HACK
53#undef CY_ENABLE_MONITORING
54#undef CY_PCI_DEBUG
55
1da177e4 56/*
15ed6cc0 57 * Include section
1da177e4 58 */
1da177e4
LT
59#include <linux/module.h>
60#include <linux/errno.h>
61#include <linux/signal.h>
62#include <linux/sched.h>
63#include <linux/timer.h>
64#include <linux/interrupt.h>
65#include <linux/tty.h>
33f0f88f 66#include <linux/tty_flip.h>
1da177e4 67#include <linux/serial.h>
405f5571 68#include <linux/smp_lock.h>
1da177e4
LT
69#include <linux/major.h>
70#include <linux/string.h>
71#include <linux/fcntl.h>
72#include <linux/ptrace.h>
73#include <linux/cyclades.h>
74#include <linux/mm.h>
75#include <linux/ioport.h>
76#include <linux/init.h>
77#include <linux/delay.h>
78#include <linux/spinlock.h>
79#include <linux/bitops.h>
054f5b0a 80#include <linux/firmware.h>
9f56fad7 81#include <linux/device.h>
1da177e4 82
15ed6cc0 83#include <linux/io.h>
15ed6cc0 84#include <linux/uaccess.h>
1da177e4 85
1da177e4
LT
86#include <linux/kernel.h>
87#include <linux/pci.h>
88
89#include <linux/stat.h>
90#include <linux/proc_fs.h>
444697d6 91#include <linux/seq_file.h>
1da177e4 92
02f1175c
JS
93static void cy_throttle(struct tty_struct *tty);
94static void cy_send_xchar(struct tty_struct *tty, char ch);
1da177e4 95
1da177e4
LT
96#ifndef SERIAL_XMIT_SIZE
97#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096))
98#endif
1da177e4
LT
99
100#define STD_COM_FLAGS (0)
101
054f5b0a
JS
102/* firmware stuff */
103#define ZL_MAX_BLOCKS 16
104#define DRIVER_VERSION 0x02010203
105#define RAM_SIZE 0x80000
106
054f5b0a
JS
107enum zblock_type {
108 ZBLOCK_PRG = 0,
109 ZBLOCK_FPGA = 1
110};
111
112struct zfile_header {
113 char name[64];
114 char date[32];
115 char aux[32];
116 u32 n_config;
117 u32 config_offset;
118 u32 n_blocks;
119 u32 block_offset;
120 u32 reserved[9];
121} __attribute__ ((packed));
122
123struct zfile_config {
124 char name[64];
125 u32 mailbox;
126 u32 function;
127 u32 n_blocks;
128 u32 block_list[ZL_MAX_BLOCKS];
129} __attribute__ ((packed));
130
131struct zfile_block {
132 u32 type;
133 u32 file_offset;
134 u32 ram_offset;
135 u32 size;
136} __attribute__ ((packed));
137
1da177e4
LT
138static struct tty_driver *cy_serial_driver;
139
140#ifdef CONFIG_ISA
141/* This is the address lookup table. The driver will probe for
142 Cyclom-Y/ISA boards at all addresses in here. If you want the
143 driver to probe addresses at a different address, add it to
144 this table. If the driver is probing some other board and
145 causing problems, remove the offending address from this table.
1da177e4
LT
146*/
147
148static unsigned int cy_isa_addresses[] = {
02f1175c
JS
149 0xD0000,
150 0xD2000,
151 0xD4000,
152 0xD6000,
153 0xD8000,
154 0xDA000,
155 0xDC000,
156 0xDE000,
157 0, 0, 0, 0, 0, 0, 0, 0
1da177e4 158};
02f1175c 159
fe971071 160#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
1da177e4
LT
161
162#ifdef MODULE
3046d50e
JS
163static long maddr[NR_CARDS];
164static int irq[NR_CARDS];
1da177e4
LT
165
166module_param_array(maddr, long, NULL, 0);
167module_param_array(irq, int, NULL, 0);
168#endif
169
02f1175c 170#endif /* CONFIG_ISA */
1da177e4
LT
171
172/* This is the per-card data structure containing address, irq, number of
173 channels, etc. This driver supports a maximum of NR_CARDS cards.
174*/
175static struct cyclades_card cy_card[NR_CARDS];
176
02f1175c 177static int cy_next_channel; /* next minor available */
1da177e4 178
1da177e4
LT
179/*
180 * This is used to look up the divisor speeds and the timeouts
181 * We're normally limited to 15 distinct baud rates. The extra
77451e53 182 * are accessed via settings in info->port.flags.
1da177e4
LT
183 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
184 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
185 * HI VHI
186 * 20
187 */
ebdb5135 188static const int baud_table[] = {
02f1175c
JS
189 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
190 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
191 230400, 0
192};
193
ebdb5135 194static const char baud_co_25[] = { /* 25 MHz clock option table */
02f1175c
JS
195 /* value => 00 01 02 03 04 */
196 /* divide by 8 32 128 512 2048 */
197 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
198 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
199};
200
ebdb5135 201static const char baud_bpr_25[] = { /* 25 MHz baud rate period table */
02f1175c
JS
202 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
203 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
204};
205
ebdb5135 206static const char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */
02f1175c
JS
207 /* value => 00 01 02 03 04 */
208 /* divide by 8 32 128 512 2048 */
209 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
210 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00
212};
213
ebdb5135 214static const char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */
02f1175c
JS
215 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
216 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
217 0x21
218};
219
ebdb5135 220static const char baud_cor3[] = { /* receive threshold */
02f1175c
JS
221 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
222 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
223 0x07
224};
1da177e4
LT
225
226/*
227 * The Cyclades driver implements HW flow control as any serial driver.
15ed6cc0
AC
228 * The cyclades_port structure member rflow and the vector rflow_thr
229 * allows us to take advantage of a special feature in the CD1400 to avoid
230 * data loss even when the system interrupt latency is too high. These flags
231 * are to be used only with very special applications. Setting these flags
232 * requires the use of a special cable (DTR and RTS reversed). In the new
233 * CD1400-based boards (rev. 6.00 or later), there is no need for special
1da177e4
LT
234 * cables.
235 */
236
ebdb5135 237static const char rflow_thr[] = { /* rflow threshold */
02f1175c
JS
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
240 0x0a
241};
1da177e4
LT
242
243/* The Cyclom-Ye has placed the sequential chips in non-sequential
244 * address order. This look-up table overcomes that problem.
245 */
f0eefdc3 246static const unsigned int cy_chip_offset[] = { 0x0000,
02f1175c
JS
247 0x0400,
248 0x0800,
249 0x0C00,
250 0x0200,
251 0x0600,
252 0x0A00,
253 0x0E00
254};
1da177e4
LT
255
256/* PCI related definitions */
257
1da177e4 258#ifdef CONFIG_PCI
ebdb5135 259static const struct pci_device_id cy_pci_dev_id[] = {
15ed6cc0
AC
260 /* PCI < 1Mb */
261 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) },
262 /* PCI > 1Mb */
263 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) },
264 /* 4Y PCI < 1Mb */
265 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) },
266 /* 4Y PCI > 1Mb */
267 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) },
268 /* 8Y PCI < 1Mb */
269 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) },
270 /* 8Y PCI > 1Mb */
271 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) },
272 /* Z PCI < 1Mb */
273 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) },
274 /* Z PCI > 1Mb */
275 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) },
893de2df 276 { } /* end of table */
02f1175c 277};
893de2df 278MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
1da177e4
LT
279#endif
280
281static void cy_start(struct tty_struct *);
d13549f8 282static void cy_set_line_char(struct cyclades_port *, struct tty_struct *);
1a86b5e3 283static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
1da177e4
LT
284#ifdef CONFIG_ISA
285static unsigned detect_isa_irq(void __iomem *);
02f1175c 286#endif /* CONFIG_ISA */
1da177e4 287
1da177e4
LT
288#ifndef CONFIG_CYZ_INTR
289static void cyz_poll(unsigned long);
290
291/* The Cyclades-Z polling cycle is defined by this variable */
292static long cyz_polling_cycle = CZ_DEF_POLL;
293
8d06afab 294static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
1da177e4 295
02f1175c 296#else /* CONFIG_CYZ_INTR */
1da177e4
LT
297static void cyz_rx_restart(unsigned long);
298static struct timer_list cyz_rx_full_timer[NR_PORTS];
02f1175c 299#endif /* CONFIG_CYZ_INTR */
1da177e4 300
2693f485
JS
301static inline bool cy_is_Z(struct cyclades_card *card)
302{
303 return card->num_chips == (unsigned int)-1;
304}
305
306static inline bool __cyz_fpga_loaded(struct RUNTIME_9060 __iomem *ctl_addr)
307{
308 return readl(&ctl_addr->init_ctrl) & (1 << 17);
309}
310
311static inline bool cyz_fpga_loaded(struct cyclades_card *card)
312{
313 return __cyz_fpga_loaded(card->ctl_addr.p9060);
314}
315
316static inline bool cyz_is_loaded(struct cyclades_card *card)
317{
318 struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS;
319
320 return (card->hw_ver == ZO_V1 || cyz_fpga_loaded(card)) &&
321 readl(&fw_id->signature) == ZFIRM_ID;
322}
323
02f1175c 324static inline int serial_paranoia_check(struct cyclades_port *info,
ebdb5135 325 const char *name, const char *routine)
1da177e4
LT
326{
327#ifdef SERIAL_PARANOIA_CHECK
02f1175c 328 if (!info) {
21719191
JS
329 printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) "
330 "in %s\n", name, routine);
02f1175c
JS
331 return 1;
332 }
333
02f1175c 334 if (info->magic != CYCLADES_MAGIC) {
21719191
JS
335 printk(KERN_WARNING "cyc Warning: bad magic number for serial "
336 "struct (%s) in %s\n", name, routine);
02f1175c
JS
337 return 1;
338 }
1da177e4 339#endif
02f1175c 340 return 0;
ebdb5135 341}
1da177e4 342
1da177e4
LT
343/***********************************************************/
344/********* Start of block of Cyclom-Y specific code ********/
345
346/* This routine waits up to 1000 micro-seconds for the previous
347 command to the Cirrus chip to complete and then issues the
348 new command. An error is returned if the previous command
349 didn't finish within the time limit.
350
351 This function is only called from inside spinlock-protected code.
352 */
15ed6cc0 353static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
1da177e4 354{
ad39c300 355 unsigned int i;
1da177e4 356
02f1175c
JS
357 /* Check to see that the previous command has completed */
358 for (i = 0; i < 100; i++) {
15ed6cc0 359 if (readb(base_addr + (CyCCR << index)) == 0)
02f1175c 360 break;
02f1175c 361 udelay(10L);
1da177e4 362 }
02f1175c
JS
363 /* if the CCR never cleared, the previous command
364 didn't finish within the "reasonable time" */
365 if (i == 100)
096dcfce 366 return -1;
1da177e4 367
02f1175c
JS
368 /* Issue the new command */
369 cy_writeb(base_addr + (CyCCR << index), cmd);
1da177e4 370
096dcfce 371 return 0;
02f1175c 372} /* cyy_issue_cmd */
1da177e4
LT
373
374#ifdef CONFIG_ISA
375/* ISA interrupt detection code */
15ed6cc0 376static unsigned detect_isa_irq(void __iomem *address)
1da177e4 377{
02f1175c
JS
378 int irq;
379 unsigned long irqs, flags;
380 int save_xir, save_car;
381 int index = 0; /* IRQ probing is only for ISA */
382
383 /* forget possible initially masked and pending IRQ */
384 irq = probe_irq_off(probe_irq_on());
385
386 /* Clear interrupts on the board first */
387 cy_writeb(address + (Cy_ClrIntr << index), 0);
388 /* Cy_ClrIntr is 0x1800 */
389
390 irqs = probe_irq_on();
391 /* Wait ... */
f6e208c1 392 msleep(5);
02f1175c
JS
393
394 /* Enable the Tx interrupts on the CD1400 */
395 local_irq_save(flags);
396 cy_writeb(address + (CyCAR << index), 0);
397 cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
398
399 cy_writeb(address + (CyCAR << index), 0);
400 cy_writeb(address + (CySRER << index),
db05c3b1 401 readb(address + (CySRER << index)) | CyTxRdy);
02f1175c
JS
402 local_irq_restore(flags);
403
404 /* Wait ... */
f6e208c1 405 msleep(5);
02f1175c
JS
406
407 /* Check which interrupt is in use */
408 irq = probe_irq_off(irqs);
409
410 /* Clean up */
db05c3b1
JS
411 save_xir = (u_char) readb(address + (CyTIR << index));
412 save_car = readb(address + (CyCAR << index));
02f1175c
JS
413 cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
414 cy_writeb(address + (CySRER << index),
db05c3b1 415 readb(address + (CySRER << index)) & ~CyTxRdy);
02f1175c
JS
416 cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
417 cy_writeb(address + (CyCAR << index), (save_car));
418 cy_writeb(address + (Cy_ClrIntr << index), 0);
419 /* Cy_ClrIntr is 0x1800 */
420
421 return (irq > 0) ? irq : 0;
1da177e4 422}
02f1175c 423#endif /* CONFIG_ISA */
1da177e4 424
ce97a097
JS
425static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
426 void __iomem *base_addr)
e941027f
JS
427{
428 struct cyclades_port *info;
429 struct tty_struct *tty;
65f76a82
JS
430 int len, index = cinfo->bus_index;
431 u8 save_xir, channel, save_car, data, char_count;
e941027f 432
e941027f 433#ifdef CY_DEBUG_INTERRUPTS
ce97a097 434 printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
e941027f 435#endif
ce97a097 436 /* determine the channel & change to that context */
65f76a82
JS
437 save_xir = readb(base_addr + (CyRIR << index));
438 channel = save_xir & CyIRChannel;
ce97a097
JS
439 info = &cinfo->ports[channel + chip * 4];
440 save_car = readb(base_addr + (CyCAR << index));
441 cy_writeb(base_addr + (CyCAR << index), save_xir);
442
d13549f8 443 tty = tty_port_tty_get(&info->port);
ce97a097 444 /* if there is nowhere to put the data, discard it */
d13549f8 445 if (tty == NULL) {
65f76a82
JS
446 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
447 CyIVRRxEx) { /* exception */
ce97a097
JS
448 data = readb(base_addr + (CyRDSR << index));
449 } else { /* normal character reception */
450 char_count = readb(base_addr + (CyRDCR << index));
451 while (char_count--)
db05c3b1 452 data = readb(base_addr + (CyRDSR << index));
ce97a097
JS
453 }
454 goto end;
455 }
456 /* there is an open port for this data */
65f76a82
JS
457 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
458 CyIVRRxEx) { /* exception */
ce97a097
JS
459 data = readb(base_addr + (CyRDSR << index));
460
461 /* For statistics only */
462 if (data & CyBREAK)
463 info->icount.brk++;
464 else if (data & CyFRAME)
465 info->icount.frame++;
466 else if (data & CyPARITY)
467 info->icount.parity++;
468 else if (data & CyOVERRUN)
469 info->icount.overrun++;
470
471 if (data & info->ignore_status_mask) {
472 info->icount.rx++;
d13549f8 473 tty_kref_put(tty);
ce97a097
JS
474 return;
475 }
476 if (tty_buffer_request_room(tty, 1)) {
477 if (data & info->read_status_mask) {
478 if (data & CyBREAK) {
479 tty_insert_flip_char(tty,
480 readb(base_addr + (CyRDSR <<
481 index)), TTY_BREAK);
482 info->icount.rx++;
77451e53 483 if (info->port.flags & ASYNC_SAK)
ce97a097
JS
484 do_SAK(tty);
485 } else if (data & CyFRAME) {
15ed6cc0 486 tty_insert_flip_char(tty,
ce97a097
JS
487 readb(base_addr + (CyRDSR <<
488 index)), TTY_FRAME);
489 info->icount.rx++;
490 info->idle_stats.frame_errs++;
491 } else if (data & CyPARITY) {
492 /* Pieces of seven... */
493 tty_insert_flip_char(tty,
494 readb(base_addr + (CyRDSR <<
495 index)), TTY_PARITY);
496 info->icount.rx++;
497 info->idle_stats.parity_errs++;
498 } else if (data & CyOVERRUN) {
499 tty_insert_flip_char(tty, 0,
500 TTY_OVERRUN);
501 info->icount.rx++;
502 /* If the flip buffer itself is
503 overflowing, we still lose
504 the next incoming character.
505 */
506 tty_insert_flip_char(tty,
507 readb(base_addr + (CyRDSR <<
508 index)), TTY_FRAME);
02f1175c 509 info->icount.rx++;
02f1175c 510 info->idle_stats.overruns++;
ce97a097
JS
511 /* These two conditions may imply */
512 /* a normal read should be done. */
513 /* } else if(data & CyTIMEOUT) { */
514 /* } else if(data & CySPECHAR) { */
515 } else {
516 tty_insert_flip_char(tty, 0,
517 TTY_NORMAL);
518 info->icount.rx++;
02f1175c 519 }
ce97a097
JS
520 } else {
521 tty_insert_flip_char(tty, 0, TTY_NORMAL);
522 info->icount.rx++;
523 }
524 } else {
525 /* there was a software buffer overrun and nothing
526 * could be done about it!!! */
527 info->icount.buf_overrun++;
528 info->idle_stats.overruns++;
529 }
530 } else { /* normal character reception */
531 /* load # chars available from the chip */
532 char_count = readb(base_addr + (CyRDCR << index));
e941027f
JS
533
534#ifdef CY_ENABLE_MONITORING
ce97a097
JS
535 ++info->mon.int_count;
536 info->mon.char_count += char_count;
537 if (char_count > info->mon.char_max)
538 info->mon.char_max = char_count;
539 info->mon.char_last = char_count;
e941027f 540#endif
ce97a097
JS
541 len = tty_buffer_request_room(tty, char_count);
542 while (len--) {
543 data = readb(base_addr + (CyRDSR << index));
544 tty_insert_flip_char(tty, data, TTY_NORMAL);
545 info->idle_stats.recv_bytes++;
546 info->icount.rx++;
e941027f 547#ifdef CY_16Y_HACK
ce97a097 548 udelay(10L);
e941027f 549#endif
e941027f 550 }
ce97a097 551 info->idle_stats.recv_idle = jiffies;
e941027f 552 }
ce97a097 553 tty_schedule_flip(tty);
d13549f8 554 tty_kref_put(tty);
ce97a097
JS
555end:
556 /* end of service */
557 cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
558 cy_writeb(base_addr + (CyCAR << index), save_car);
ce97a097 559}
e941027f 560
65f76a82 561static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
ce97a097
JS
562 void __iomem *base_addr)
563{
564 struct cyclades_port *info;
d13549f8 565 struct tty_struct *tty;
65f76a82
JS
566 int char_count, index = cinfo->bus_index;
567 u8 save_xir, channel, save_car, outch;
ce97a097
JS
568
569 /* Since we only get here when the transmit buffer
570 is empty, we know we can always stuff a dozen
571 characters. */
e941027f 572#ifdef CY_DEBUG_INTERRUPTS
ce97a097 573 printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
e941027f
JS
574#endif
575
ce97a097 576 /* determine the channel & change to that context */
65f76a82
JS
577 save_xir = readb(base_addr + (CyTIR << index));
578 channel = save_xir & CyIRChannel;
ce97a097
JS
579 save_car = readb(base_addr + (CyCAR << index));
580 cy_writeb(base_addr + (CyCAR << index), save_xir);
581
582 /* validate the port# (as configured and open) */
583 if (channel + chip * 4 >= cinfo->nports) {
584 cy_writeb(base_addr + (CySRER << index),
585 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
586 goto end;
587 }
588 info = &cinfo->ports[channel + chip * 4];
d13549f8
JS
589 tty = tty_port_tty_get(&info->port);
590 if (tty == NULL) {
ce97a097
JS
591 cy_writeb(base_addr + (CySRER << index),
592 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
593 goto end;
594 }
02f1175c 595
ce97a097
JS
596 /* load the on-chip space for outbound data */
597 char_count = info->xmit_fifo_size;
02f1175c 598
ce97a097
JS
599 if (info->x_char) { /* send special char */
600 outch = info->x_char;
601 cy_writeb(base_addr + (CyTDR << index), outch);
602 char_count--;
603 info->icount.tx++;
604 info->x_char = 0;
605 }
02f1175c 606
ce97a097
JS
607 if (info->breakon || info->breakoff) {
608 if (info->breakon) {
609 cy_writeb(base_addr + (CyTDR << index), 0);
610 cy_writeb(base_addr + (CyTDR << index), 0x81);
611 info->breakon = 0;
612 char_count -= 2;
e941027f 613 }
ce97a097
JS
614 if (info->breakoff) {
615 cy_writeb(base_addr + (CyTDR << index), 0);
616 cy_writeb(base_addr + (CyTDR << index), 0x83);
617 info->breakoff = 0;
618 char_count -= 2;
e941027f 619 }
ce97a097 620 }
02f1175c 621
ce97a097
JS
622 while (char_count-- > 0) {
623 if (!info->xmit_cnt) {
624 if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
625 cy_writeb(base_addr + (CySRER << index),
626 readb(base_addr + (CySRER << index)) &
02f1175c 627 ~CyTxMpty);
ce97a097
JS
628 } else {
629 cy_writeb(base_addr + (CySRER << index),
630 (readb(base_addr + (CySRER << index)) &
02f1175c 631 ~CyTxRdy) | CyTxMpty);
02f1175c 632 }
ce97a097
JS
633 goto done;
634 }
77451e53 635 if (info->port.xmit_buf == NULL) {
ce97a097
JS
636 cy_writeb(base_addr + (CySRER << index),
637 readb(base_addr + (CySRER << index)) &
02f1175c 638 ~CyTxRdy);
ce97a097
JS
639 goto done;
640 }
d13549f8 641 if (tty->stopped || tty->hw_stopped) {
ce97a097
JS
642 cy_writeb(base_addr + (CySRER << index),
643 readb(base_addr + (CySRER << index)) &
02f1175c 644 ~CyTxRdy);
ce97a097
JS
645 goto done;
646 }
647 /* Because the Embedded Transmit Commands have been enabled,
648 * we must check to see if the escape character, NULL, is being
649 * sent. If it is, we must ensure that there is room for it to
650 * be doubled in the output stream. Therefore we no longer
651 * advance the pointer when the character is fetched, but
652 * rather wait until after the check for a NULL output
653 * character. This is necessary because there may not be room
654 * for the two chars needed to send a NULL.)
655 */
77451e53 656 outch = info->port.xmit_buf[info->xmit_tail];
ce97a097
JS
657 if (outch) {
658 info->xmit_cnt--;
659 info->xmit_tail = (info->xmit_tail + 1) &
660 (SERIAL_XMIT_SIZE - 1);
661 cy_writeb(base_addr + (CyTDR << index), outch);
662 info->icount.tx++;
663 } else {
664 if (char_count > 1) {
02f1175c
JS
665 info->xmit_cnt--;
666 info->xmit_tail = (info->xmit_tail + 1) &
ce97a097 667 (SERIAL_XMIT_SIZE - 1);
02f1175c 668 cy_writeb(base_addr + (CyTDR << index), outch);
ce97a097 669 cy_writeb(base_addr + (CyTDR << index), 0);
02f1175c 670 info->icount.tx++;
ce97a097 671 char_count--;
02f1175c 672 }
e941027f 673 }
e941027f
JS
674 }
675
ce97a097 676done:
d13549f8
JS
677 tty_wakeup(tty);
678 tty_kref_put(tty);
ce97a097
JS
679end:
680 /* end of service */
681 cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
682 cy_writeb(base_addr + (CyCAR << index), save_car);
ce97a097 683}
02f1175c 684
ce97a097
JS
685static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
686 void __iomem *base_addr)
687{
688 struct cyclades_port *info;
d13549f8 689 struct tty_struct *tty;
65f76a82
JS
690 int index = cinfo->bus_index;
691 u8 save_xir, channel, save_car, mdm_change, mdm_status;
ce97a097
JS
692
693 /* determine the channel & change to that context */
65f76a82
JS
694 save_xir = readb(base_addr + (CyMIR << index));
695 channel = save_xir & CyIRChannel;
ce97a097
JS
696 info = &cinfo->ports[channel + chip * 4];
697 save_car = readb(base_addr + (CyCAR << index));
698 cy_writeb(base_addr + (CyCAR << index), save_xir);
699
700 mdm_change = readb(base_addr + (CyMISR << index));
701 mdm_status = readb(base_addr + (CyMSVR1 << index));
702
d13549f8
JS
703 tty = tty_port_tty_get(&info->port);
704 if (!tty)
ce97a097
JS
705 goto end;
706
707 if (mdm_change & CyANY_DELTA) {
708 /* For statistics only */
709 if (mdm_change & CyDCD)
710 info->icount.dcd++;
711 if (mdm_change & CyCTS)
712 info->icount.cts++;
713 if (mdm_change & CyDSR)
714 info->icount.dsr++;
715 if (mdm_change & CyRI)
716 info->icount.rng++;
717
718 wake_up_interruptible(&info->delta_msr_wait);
719 }
720
77451e53 721 if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
174e6fe0
JS
722 if (mdm_status & CyDCD)
723 wake_up_interruptible(&info->port.open_wait);
724 else
d13549f8 725 tty_hangup(tty);
ce97a097 726 }
77451e53 727 if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
d13549f8 728 if (tty->hw_stopped) {
ce97a097
JS
729 if (mdm_status & CyCTS) {
730 /* cy_start isn't used
731 because... !!! */
d13549f8 732 tty->hw_stopped = 0;
ce97a097
JS
733 cy_writeb(base_addr + (CySRER << index),
734 readb(base_addr + (CySRER << index)) |
735 CyTxRdy);
d13549f8 736 tty_wakeup(tty);
02f1175c 737 }
ce97a097
JS
738 } else {
739 if (!(mdm_status & CyCTS)) {
740 /* cy_stop isn't used
741 because ... !!! */
d13549f8 742 tty->hw_stopped = 1;
ce97a097
JS
743 cy_writeb(base_addr + (CySRER << index),
744 readb(base_addr + (CySRER << index)) &
745 ~CyTxRdy);
02f1175c 746 }
e941027f 747 }
e941027f 748 }
ce97a097
JS
749/* if (mdm_change & CyDSR) {
750 }
751 if (mdm_change & CyRI) {
752 }*/
d13549f8 753 tty_kref_put(tty);
ce97a097
JS
754end:
755 /* end of service */
756 cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
757 cy_writeb(base_addr + (CyCAR << index), save_car);
e941027f
JS
758}
759
1da177e4
LT
760/* The real interrupt service routine is called
761 whenever the card wants its hand held--chars
762 received, out buffer empty, modem change, etc.
763 */
02f1175c 764static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1da177e4 765{
02f1175c 766 int status;
f7429034 767 struct cyclades_card *cinfo = dev_id;
02f1175c 768 void __iomem *base_addr, *card_base_addr;
65f76a82 769 unsigned int chip, too_many, had_work;
02f1175c 770 int index;
02f1175c 771
f7429034 772 if (unlikely(cinfo == NULL)) {
1da177e4 773#ifdef CY_DEBUG_INTERRUPTS
15ed6cc0
AC
774 printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",
775 irq);
1da177e4 776#endif
02f1175c
JS
777 return IRQ_NONE; /* spurious interrupt */
778 }
779
780 card_base_addr = cinfo->base_addr;
781 index = cinfo->bus_index;
782
f1e83c6c
JS
783 /* card was not initialized yet (e.g. DEBUG_SHIRQ) */
784 if (unlikely(card_base_addr == NULL))
785 return IRQ_HANDLED;
786
02f1175c
JS
787 /* This loop checks all chips in the card. Make a note whenever
788 _any_ chip had some work to do, as this is considered an
789 indication that there will be more to do. Only when no chip
790 has any work does this outermost loop exit.
791 */
792 do {
793 had_work = 0;
794 for (chip = 0; chip < cinfo->num_chips; chip++) {
795 base_addr = cinfo->base_addr +
796 (cy_chip_offset[chip] << index);
797 too_many = 0;
db05c3b1 798 while ((status = readb(base_addr +
02f1175c
JS
799 (CySVRR << index))) != 0x00) {
800 had_work++;
801 /* The purpose of the following test is to ensure that
802 no chip can monopolize the driver. This forces the
803 chips to be checked in a round-robin fashion (after
804 draining each of a bunch (1000) of characters).
805 */
ce97a097 806 if (1000 < too_many++)
02f1175c 807 break;
1c0a387c 808 spin_lock(&cinfo->card_lock);
ce97a097
JS
809 if (status & CySRReceive) /* rx intr */
810 cyy_chip_rx(cinfo, chip, base_addr);
811 if (status & CySRTransmit) /* tx intr */
812 cyy_chip_tx(cinfo, chip, base_addr);
813 if (status & CySRModem) /* modem intr */
814 cyy_chip_modem(cinfo, chip, base_addr);
1c0a387c 815 spin_unlock(&cinfo->card_lock);
02f1175c
JS
816 }
817 }
818 } while (had_work);
819
820 /* clear interrupts */
821 spin_lock(&cinfo->card_lock);
822 cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0);
823 /* Cy_ClrIntr is 0x1800 */
824 spin_unlock(&cinfo->card_lock);
825 return IRQ_HANDLED;
826} /* cyy_interrupt */
1da177e4 827
4d768200
JS
828static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set,
829 unsigned int clear)
830{
831 struct cyclades_card *card = info->card;
832 void __iomem *base_addr;
833 int chip, channel, index;
0d348729 834 u32 rts, dtr, msvrr, msvrd;
4d768200
JS
835
836 channel = info->line - card->first_line;
837 chip = channel >> 2;
838 channel &= 0x03;
839 index = card->bus_index;
840 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
841
0d348729
JS
842 if (info->rtsdtr_inv) {
843 msvrr = CyMSVR2;
844 msvrd = CyMSVR1;
845 rts = CyDTR;
846 dtr = CyRTS;
847 } else {
848 msvrr = CyMSVR1;
849 msvrd = CyMSVR2;
850 rts = CyRTS;
851 dtr = CyDTR;
852 }
4d768200 853 if (set & TIOCM_RTS) {
0d348729
JS
854 cy_writeb(base_addr + (CyCAR << index), (u8)channel);
855 cy_writeb(base_addr + (msvrr << index), rts);
4d768200
JS
856 }
857 if (clear & TIOCM_RTS) {
0d348729
JS
858 cy_writeb(base_addr + (CyCAR << index), (u8)channel);
859 cy_writeb(base_addr + (msvrr << index), ~rts);
4d768200
JS
860 }
861 if (set & TIOCM_DTR) {
0d348729
JS
862 cy_writeb(base_addr + (CyCAR << index), (u8)channel);
863 cy_writeb(base_addr + (msvrd << index), dtr);
4d768200
JS
864#ifdef CY_DEBUG_DTR
865 printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
866 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
867 readb(base_addr + (CyMSVR1 << index)),
868 readb(base_addr + (CyMSVR2 << index)));
869#endif
870 }
871 if (clear & TIOCM_DTR) {
0d348729
JS
872 cy_writeb(base_addr + (CyCAR << index), (u8)channel);
873 cy_writeb(base_addr + (msvrd << index), ~dtr);
4d768200
JS
874#ifdef CY_DEBUG_DTR
875 printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
876 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
877 readb(base_addr + (CyMSVR1 << index)),
878 readb(base_addr + (CyMSVR2 << index)));
879#endif
880 }
881}
882
1da177e4
LT
883/***********************************************************/
884/********* End of block of Cyclom-Y specific code **********/
15ed6cc0 885/******** Start of block of Cyclades-Z specific code *******/
1da177e4
LT
886/***********************************************************/
887
888static int
02f1175c 889cyz_fetch_msg(struct cyclades_card *cinfo,
15ed6cc0 890 __u32 *channel, __u8 *cmd, __u32 *param)
1da177e4 891{
f0eefdc3 892 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
02f1175c
JS
893 unsigned long loc_doorbell;
894
97e87f8e 895 loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell);
02f1175c
JS
896 if (loc_doorbell) {
897 *cmd = (char)(0xff & loc_doorbell);
db05c3b1
JS
898 *channel = readl(&board_ctrl->fwcmd_channel);
899 *param = (__u32) readl(&board_ctrl->fwcmd_param);
97e87f8e 900 cy_writel(&cinfo->ctl_addr.p9060->loc_doorbell, 0xffffffff);
02f1175c
JS
901 return 1;
902 }
903 return 0;
904} /* cyz_fetch_msg */
1da177e4
LT
905
906static int
02f1175c 907cyz_issue_cmd(struct cyclades_card *cinfo,
1a86b5e3 908 __u32 channel, __u8 cmd, __u32 param)
1da177e4 909{
f0eefdc3 910 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1a86b5e3 911 __u32 __iomem *pci_doorbell;
65f76a82 912 unsigned int index;
02f1175c 913
2693f485 914 if (!cyz_is_loaded(cinfo))
096dcfce 915 return -1;
15ed6cc0 916
02f1175c 917 index = 0;
97e87f8e 918 pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell;
db05c3b1 919 while ((readl(pci_doorbell) & 0xff) != 0) {
15ed6cc0 920 if (index++ == 1000)
db05c3b1 921 return (int)(readl(pci_doorbell) & 0xff);
02f1175c
JS
922 udelay(50L);
923 }
924 cy_writel(&board_ctrl->hcmd_channel, channel);
925 cy_writel(&board_ctrl->hcmd_param, param);
926 cy_writel(pci_doorbell, (long)cmd);
927
096dcfce 928 return 0;
02f1175c 929} /* cyz_issue_cmd */
1da177e4 930
f0eefdc3 931static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
1da177e4 932{
f0eefdc3 933 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
875b206b 934 struct cyclades_card *cinfo = info->card;
65f76a82 935 unsigned int char_count;
02f1175c 936 int len;
1da177e4 937#ifdef BLOCKMOVE
ce71b0ff 938 unsigned char *buf;
1da177e4 939#else
02f1175c 940 char data;
1da177e4 941#endif
ad39c300 942 __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
1da177e4 943
db05c3b1
JS
944 rx_get = new_rx_get = readl(&buf_ctrl->rx_get);
945 rx_put = readl(&buf_ctrl->rx_put);
946 rx_bufsize = readl(&buf_ctrl->rx_bufsize);
947 rx_bufaddr = readl(&buf_ctrl->rx_bufaddr);
02f1175c
JS
948 if (rx_put >= rx_get)
949 char_count = rx_put - rx_get;
950 else
951 char_count = rx_put - rx_get + rx_bufsize;
1da177e4 952
02f1175c 953 if (char_count) {
1da177e4 954#ifdef CY_ENABLE_MONITORING
02f1175c
JS
955 info->mon.int_count++;
956 info->mon.char_count += char_count;
957 if (char_count > info->mon.char_max)
958 info->mon.char_max = char_count;
959 info->mon.char_last = char_count;
1da177e4 960#endif
f7429034 961 if (tty == NULL) {
02f1175c
JS
962 /* flush received characters */
963 new_rx_get = (new_rx_get + char_count) &
964 (rx_bufsize - 1);
965 info->rflush_count++;
966 } else {
1da177e4 967#ifdef BLOCKMOVE
02f1175c
JS
968 /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
969 for performance, but because of buffer boundaries, there
970 may be several steps to the operation */
ce71b0ff
JS
971 while (1) {
972 len = tty_prepare_flip_string(tty, &buf,
973 char_count);
974 if (!len)
975 break;
976
977 len = min_t(unsigned int, min(len, char_count),
978 rx_bufsize - new_rx_get);
979
980 memcpy_fromio(buf, cinfo->base_addr +
981 rx_bufaddr + new_rx_get, len);
982
983 new_rx_get = (new_rx_get + len) &
02f1175c 984 (rx_bufsize - 1);
ce71b0ff
JS
985 char_count -= len;
986 info->icount.rx += len;
987 info->idle_stats.recv_bytes += len;
02f1175c 988 }
1da177e4 989#else
02f1175c
JS
990 len = tty_buffer_request_room(tty, char_count);
991 while (len--) {
db05c3b1 992 data = readb(cinfo->base_addr + rx_bufaddr +
02f1175c 993 new_rx_get);
15ed6cc0
AC
994 new_rx_get = (new_rx_get + 1) &
995 (rx_bufsize - 1);
02f1175c
JS
996 tty_insert_flip_char(tty, data, TTY_NORMAL);
997 info->idle_stats.recv_bytes++;
998 info->icount.rx++;
999 }
1da177e4
LT
1000#endif
1001#ifdef CONFIG_CYZ_INTR
02f1175c
JS
1002 /* Recalculate the number of chars in the RX buffer and issue
1003 a cmd in case it's higher than the RX high water mark */
db05c3b1 1004 rx_put = readl(&buf_ctrl->rx_put);
02f1175c
JS
1005 if (rx_put >= rx_get)
1006 char_count = rx_put - rx_get;
1007 else
1008 char_count = rx_put - rx_get + rx_bufsize;
65f76a82 1009 if (char_count >= readl(&buf_ctrl->rx_threshold) &&
ebafeeff
JS
1010 !timer_pending(&cyz_rx_full_timer[
1011 info->line]))
1012 mod_timer(&cyz_rx_full_timer[info->line],
1013 jiffies + 1);
1da177e4 1014#endif
02f1175c
JS
1015 info->idle_stats.recv_idle = jiffies;
1016 tty_schedule_flip(tty);
1017 }
1018 /* Update rx_get */
1019 cy_writel(&buf_ctrl->rx_get, new_rx_get);
1da177e4 1020 }
1da177e4
LT
1021}
1022
f0eefdc3 1023static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
1da177e4 1024{
f0eefdc3 1025 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
875b206b 1026 struct cyclades_card *cinfo = info->card;
65f76a82
JS
1027 u8 data;
1028 unsigned int char_count;
1da177e4 1029#ifdef BLOCKMOVE
02f1175c 1030 int small_count;
1da177e4 1031#endif
ad39c300 1032 __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr;
1da177e4 1033
02f1175c
JS
1034 if (info->xmit_cnt <= 0) /* Nothing to transmit */
1035 return;
1da177e4 1036
db05c3b1
JS
1037 tx_get = readl(&buf_ctrl->tx_get);
1038 tx_put = readl(&buf_ctrl->tx_put);
1039 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
1040 tx_bufaddr = readl(&buf_ctrl->tx_bufaddr);
02f1175c
JS
1041 if (tx_put >= tx_get)
1042 char_count = tx_get - tx_put - 1 + tx_bufsize;
1043 else
1044 char_count = tx_get - tx_put - 1;
1da177e4 1045
02f1175c 1046 if (char_count) {
1da177e4 1047
f7429034 1048 if (tty == NULL)
02f1175c 1049 goto ztxdone;
1da177e4 1050
02f1175c
JS
1051 if (info->x_char) { /* send special char */
1052 data = info->x_char;
1da177e4 1053
02f1175c
JS
1054 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1055 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1056 info->x_char = 0;
1057 char_count--;
1058 info->icount.tx++;
02f1175c 1059 }
1da177e4 1060#ifdef BLOCKMOVE
02f1175c
JS
1061 while (0 < (small_count = min_t(unsigned int,
1062 tx_bufsize - tx_put, min_t(unsigned int,
1063 (SERIAL_XMIT_SIZE - info->xmit_tail),
1064 min_t(unsigned int, info->xmit_cnt,
1065 char_count))))) {
1066
1067 memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr +
1068 tx_put),
77451e53 1069 &info->port.xmit_buf[info->xmit_tail],
02f1175c
JS
1070 small_count);
1071
1072 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1073 char_count -= small_count;
1074 info->icount.tx += small_count;
1075 info->xmit_cnt -= small_count;
1076 info->xmit_tail = (info->xmit_tail + small_count) &
1077 (SERIAL_XMIT_SIZE - 1);
02f1175c 1078 }
1da177e4 1079#else
02f1175c 1080 while (info->xmit_cnt && char_count) {
77451e53 1081 data = info->port.xmit_buf[info->xmit_tail];
02f1175c
JS
1082 info->xmit_cnt--;
1083 info->xmit_tail = (info->xmit_tail + 1) &
1084 (SERIAL_XMIT_SIZE - 1);
1085
1086 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1087 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1088 char_count--;
1089 info->icount.tx++;
02f1175c 1090 }
1da177e4 1091#endif
ebafeeff 1092 tty_wakeup(tty);
7fa57a0c 1093ztxdone:
02f1175c
JS
1094 /* Update tx_put */
1095 cy_writel(&buf_ctrl->tx_put, tx_put);
1da177e4 1096 }
1da177e4
LT
1097}
1098
02f1175c 1099static void cyz_handle_cmd(struct cyclades_card *cinfo)
1da177e4 1100{
f0eefdc3 1101 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
02f1175c
JS
1102 struct tty_struct *tty;
1103 struct cyclades_port *info;
101b8159 1104 __u32 channel, param, fw_ver;
1a86b5e3 1105 __u8 cmd;
02f1175c
JS
1106 int special_count;
1107 int delta_count;
1108
db05c3b1 1109 fw_ver = readl(&board_ctrl->fw_version);
02f1175c
JS
1110
1111 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
1112 special_count = 0;
1113 delta_count = 0;
dd025c0c 1114 info = &cinfo->ports[channel];
d13549f8 1115 tty = tty_port_tty_get(&info->port);
15ed6cc0 1116 if (tty == NULL)
02f1175c 1117 continue;
f7429034 1118
02f1175c
JS
1119 switch (cmd) {
1120 case C_CM_PR_ERROR:
1121 tty_insert_flip_char(tty, 0, TTY_PARITY);
1122 info->icount.rx++;
1123 special_count++;
1124 break;
1125 case C_CM_FR_ERROR:
1126 tty_insert_flip_char(tty, 0, TTY_FRAME);
1127 info->icount.rx++;
1128 special_count++;
1129 break;
1130 case C_CM_RXBRK:
1131 tty_insert_flip_char(tty, 0, TTY_BREAK);
1132 info->icount.rx++;
1133 special_count++;
1134 break;
1135 case C_CM_MDCD:
1136 info->icount.dcd++;
1137 delta_count++;
77451e53 1138 if (info->port.flags & ASYNC_CHECK_CD) {
f0eefdc3
JS
1139 u32 dcd = fw_ver > 241 ? param :
1140 readl(&info->u.cyz.ch_ctrl->rs_status);
174e6fe0 1141 if (dcd & C_RS_DCD)
77451e53 1142 wake_up_interruptible(&info->port.open_wait);
174e6fe0 1143 else
d13549f8 1144 tty_hangup(tty);
02f1175c
JS
1145 }
1146 break;
1147 case C_CM_MCTS:
1148 info->icount.cts++;
1149 delta_count++;
1150 break;
1151 case C_CM_MRI:
1152 info->icount.rng++;
1153 delta_count++;
1154 break;
1155 case C_CM_MDSR:
1156 info->icount.dsr++;
1157 delta_count++;
1158 break;
1da177e4 1159#ifdef Z_WAKE
02f1175c 1160 case C_CM_IOCTLW:
ebafeeff 1161 complete(&info->shutdown_wait);
02f1175c 1162 break;
1da177e4
LT
1163#endif
1164#ifdef CONFIG_CYZ_INTR
02f1175c
JS
1165 case C_CM_RXHIWM:
1166 case C_CM_RXNNDT:
1167 case C_CM_INTBACK2:
1168 /* Reception Interrupt */
1da177e4 1169#ifdef CY_DEBUG_INTERRUPTS
21719191
JS
1170 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1171 "port %ld\n", info->card, channel);
1da177e4 1172#endif
f0eefdc3 1173 cyz_handle_rx(info, tty);
02f1175c
JS
1174 break;
1175 case C_CM_TXBEMPTY:
1176 case C_CM_TXLOWWM:
1177 case C_CM_INTBACK:
1178 /* Transmission Interrupt */
1da177e4 1179#ifdef CY_DEBUG_INTERRUPTS
21719191
JS
1180 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1181 "port %ld\n", info->card, channel);
1da177e4 1182#endif
f0eefdc3 1183 cyz_handle_tx(info, tty);
02f1175c
JS
1184 break;
1185#endif /* CONFIG_CYZ_INTR */
1186 case C_CM_FATAL:
1187 /* should do something with this !!! */
1188 break;
1189 default:
1190 break;
1191 }
1192 if (delta_count)
ebafeeff 1193 wake_up_interruptible(&info->delta_msr_wait);
02f1175c
JS
1194 if (special_count)
1195 tty_schedule_flip(tty);
d13549f8 1196 tty_kref_put(tty);
1da177e4 1197 }
1da177e4
LT
1198}
1199
1200#ifdef CONFIG_CYZ_INTR
02f1175c 1201static irqreturn_t cyz_interrupt(int irq, void *dev_id)
1da177e4 1202{
f7429034 1203 struct cyclades_card *cinfo = dev_id;
1da177e4 1204
2693f485 1205 if (unlikely(!cyz_is_loaded(cinfo))) {
1da177e4 1206#ifdef CY_DEBUG_INTERRUPTS
21719191
JS
1207 printk(KERN_DEBUG "cyz_interrupt: board not yet loaded "
1208 "(IRQ%d).\n", irq);
1da177e4 1209#endif
02f1175c
JS
1210 return IRQ_NONE;
1211 }
1da177e4 1212
02f1175c
JS
1213 /* Handle the interrupts */
1214 cyz_handle_cmd(cinfo);
1da177e4 1215
02f1175c
JS
1216 return IRQ_HANDLED;
1217} /* cyz_interrupt */
1da177e4 1218
02f1175c 1219static void cyz_rx_restart(unsigned long arg)
1da177e4 1220{
02f1175c 1221 struct cyclades_port *info = (struct cyclades_port *)arg;
875b206b 1222 struct cyclades_card *card = info->card;
02f1175c 1223 int retval;
875b206b 1224 __u32 channel = info->line - card->first_line;
02f1175c
JS
1225 unsigned long flags;
1226
9fa1b3b1 1227 spin_lock_irqsave(&card->card_lock, flags);
875b206b 1228 retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L);
02f1175c 1229 if (retval != 0) {
21719191 1230 printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n",
02f1175c
JS
1231 info->line, retval);
1232 }
9fa1b3b1 1233 spin_unlock_irqrestore(&card->card_lock, flags);
1da177e4
LT
1234}
1235
02f1175c 1236#else /* CONFIG_CYZ_INTR */
1da177e4 1237
02f1175c 1238static void cyz_poll(unsigned long arg)
1da177e4 1239{
02f1175c
JS
1240 struct cyclades_card *cinfo;
1241 struct cyclades_port *info;
b7050906 1242 unsigned long expires = jiffies + HZ;
65f76a82 1243 unsigned int port, card;
1da177e4 1244
02f1175c
JS
1245 for (card = 0; card < NR_CARDS; card++) {
1246 cinfo = &cy_card[card];
1247
2693f485 1248 if (!cy_is_Z(cinfo))
02f1175c 1249 continue;
2693f485 1250 if (!cyz_is_loaded(cinfo))
02f1175c
JS
1251 continue;
1252
1da177e4 1253 /* Skip first polling cycle to avoid racing conditions with the FW */
02f1175c 1254 if (!cinfo->intr_enabled) {
02f1175c
JS
1255 cinfo->intr_enabled = 1;
1256 continue;
1257 }
1da177e4 1258
02f1175c 1259 cyz_handle_cmd(cinfo);
1da177e4 1260
02f1175c 1261 for (port = 0; port < cinfo->nports; port++) {
d13549f8
JS
1262 struct tty_struct *tty;
1263
dd025c0c 1264 info = &cinfo->ports[port];
d13549f8
JS
1265 tty = tty_port_tty_get(&info->port);
1266 /* OK to pass NULL to the handle functions below.
1267 They need to drop the data in that case. */
1268
02f1175c 1269 if (!info->throttle)
f0eefdc3
JS
1270 cyz_handle_rx(info, tty);
1271 cyz_handle_tx(info, tty);
d13549f8 1272 tty_kref_put(tty);
02f1175c
JS
1273 }
1274 /* poll every 'cyz_polling_cycle' period */
b7050906 1275 expires = jiffies + cyz_polling_cycle;
1da177e4 1276 }
b7050906 1277 mod_timer(&cyz_timerlist, expires);
02f1175c 1278} /* cyz_poll */
1da177e4 1279
02f1175c 1280#endif /* CONFIG_CYZ_INTR */
1da177e4
LT
1281
1282/********** End of block of Cyclades-Z specific code *********/
1283/***********************************************************/
1284
1da177e4
LT
1285/* This is called whenever a port becomes active;
1286 interrupts are enabled and DTR & RTS are turned on.
1287 */
d13549f8 1288static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
1da177e4 1289{
875b206b 1290 struct cyclades_card *card;
02f1175c
JS
1291 unsigned long flags;
1292 int retval = 0;
1293 void __iomem *base_addr;
cc7fdf49 1294 int channel;
02f1175c 1295 unsigned long page;
1da177e4 1296
02f1175c 1297 card = info->card;
875b206b 1298 channel = info->line - card->first_line;
1da177e4 1299
02f1175c
JS
1300 page = get_zeroed_page(GFP_KERNEL);
1301 if (!page)
1302 return -ENOMEM;
1da177e4 1303
9fa1b3b1 1304 spin_lock_irqsave(&card->card_lock, flags);
1da177e4 1305
cc7fdf49 1306 if (info->port.flags & ASYNC_INITIALIZED)
02f1175c 1307 goto errout;
1da177e4 1308
02f1175c 1309 if (!info->type) {
d13549f8 1310 set_bit(TTY_IO_ERROR, &tty->flags);
02f1175c
JS
1311 goto errout;
1312 }
1da177e4 1313
77451e53 1314 if (info->port.xmit_buf)
02f1175c
JS
1315 free_page(page);
1316 else
77451e53 1317 info->port.xmit_buf = (unsigned char *)page;
1da177e4 1318
9fa1b3b1 1319 spin_unlock_irqrestore(&card->card_lock, flags);
1da177e4 1320
d13549f8 1321 cy_set_line_char(info, tty);
1da177e4 1322
2693f485 1323 if (!cy_is_Z(card)) {
cc7fdf49
JS
1324 int chip = channel >> 2;
1325 int index = card->bus_index;
02f1175c 1326 channel &= 0x03;
875b206b 1327 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4
LT
1328
1329#ifdef CY_DEBUG_OPEN
21719191
JS
1330 printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, "
1331 "base_addr %p\n",
1332 card, chip, channel, base_addr);
1da177e4 1333#endif
9fa1b3b1 1334 spin_lock_irqsave(&card->card_lock, flags);
1da177e4 1335
02f1175c 1336 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
1da177e4 1337
02f1175c
JS
1338 cy_writeb(base_addr + (CyRTPR << index),
1339 (info->default_timeout ? info->default_timeout : 0x02));
1340 /* 10ms rx timeout */
1da177e4 1341
02f1175c
JS
1342 cyy_issue_cmd(base_addr, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR,
1343 index);
1da177e4 1344
4d768200 1345 cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0);
1da177e4 1346
02f1175c 1347 cy_writeb(base_addr + (CySRER << index),
db05c3b1 1348 readb(base_addr + (CySRER << index)) | CyRxData);
02f1175c 1349 } else {
f0eefdc3 1350 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
1da177e4 1351
2693f485 1352 if (!cyz_is_loaded(card))
02f1175c 1353 return -ENODEV;
1da177e4 1354
1da177e4 1355#ifdef CY_DEBUG_OPEN
21719191 1356 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
f0eefdc3 1357 "base_addr %p\n", card, channel, card->base_addr);
1da177e4 1358#endif
9fa1b3b1 1359 spin_lock_irqsave(&card->card_lock, flags);
1da177e4 1360
f0eefdc3 1361 cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE);
1da177e4
LT
1362#ifdef Z_WAKE
1363#ifdef CONFIG_CYZ_INTR
f0eefdc3 1364 cy_writel(&ch_ctrl->intr_enable,
02f1175c
JS
1365 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1366 C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD);
1da177e4 1367#else
f0eefdc3 1368 cy_writel(&ch_ctrl->intr_enable,
02f1175c
JS
1369 C_IN_IOCTLW | C_IN_MDCD);
1370#endif /* CONFIG_CYZ_INTR */
1da177e4
LT
1371#else
1372#ifdef CONFIG_CYZ_INTR
f0eefdc3 1373 cy_writel(&ch_ctrl->intr_enable,
02f1175c
JS
1374 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1375 C_IN_RXNNDT | C_IN_MDCD);
1da177e4 1376#else
f0eefdc3 1377 cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD);
02f1175c
JS
1378#endif /* CONFIG_CYZ_INTR */
1379#endif /* Z_WAKE */
1380
875b206b 1381 retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
02f1175c 1382 if (retval != 0) {
21719191
JS
1383 printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was "
1384 "%x\n", info->line, retval);
02f1175c 1385 }
1da177e4 1386
02f1175c 1387 /* Flush RX buffers before raising DTR and RTS */
875b206b 1388 retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L);
02f1175c 1389 if (retval != 0) {
21719191
JS
1390 printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was "
1391 "%x\n", info->line, retval);
02f1175c 1392 }
1da177e4 1393
02f1175c
JS
1394 /* set timeout !!! */
1395 /* set RTS and DTR !!! */
4d768200 1396 tty_port_raise_dtr_rts(&info->port);
1da177e4 1397
02f1175c 1398 /* enable send, recv, modem !!! */
cc7fdf49 1399 }
02f1175c 1400
cc7fdf49 1401 info->port.flags |= ASYNC_INITIALIZED;
1da177e4 1402
cc7fdf49
JS
1403 clear_bit(TTY_IO_ERROR, &tty->flags);
1404 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1405 info->breakon = info->breakoff = 0;
1406 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
1407 info->idle_stats.in_use =
1408 info->idle_stats.recv_idle =
1409 info->idle_stats.xmit_idle = jiffies;
1410
1411 spin_unlock_irqrestore(&card->card_lock, flags);
1da177e4
LT
1412
1413#ifdef CY_DEBUG_OPEN
21719191 1414 printk(KERN_DEBUG "cyc startup done\n");
1da177e4
LT
1415#endif
1416 return 0;
1417
1418errout:
9fa1b3b1 1419 spin_unlock_irqrestore(&card->card_lock, flags);
cc7fdf49 1420 free_page(page);
1da177e4 1421 return retval;
02f1175c 1422} /* startup */
1da177e4 1423
02f1175c 1424static void start_xmit(struct cyclades_port *info)
1da177e4 1425{
875b206b 1426 struct cyclades_card *card;
02f1175c
JS
1427 unsigned long flags;
1428 void __iomem *base_addr;
875b206b 1429 int chip, channel, index;
1da177e4 1430
02f1175c 1431 card = info->card;
875b206b 1432 channel = info->line - card->first_line;
2693f485 1433 if (!cy_is_Z(card)) {
02f1175c
JS
1434 chip = channel >> 2;
1435 channel &= 0x03;
875b206b
JS
1436 index = card->bus_index;
1437 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 1438
9fa1b3b1 1439 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
1440 cy_writeb(base_addr + (CyCAR << index), channel);
1441 cy_writeb(base_addr + (CySRER << index),
db05c3b1 1442 readb(base_addr + (CySRER << index)) | CyTxRdy);
9fa1b3b1 1443 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 1444 } else {
1da177e4 1445#ifdef CONFIG_CYZ_INTR
02f1175c 1446 int retval;
1da177e4 1447
9fa1b3b1 1448 spin_lock_irqsave(&card->card_lock, flags);
875b206b 1449 retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L);
02f1175c 1450 if (retval != 0) {
21719191
JS
1451 printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was "
1452 "%x\n", info->line, retval);
02f1175c 1453 }
9fa1b3b1 1454 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
1455#else /* CONFIG_CYZ_INTR */
1456 /* Don't have to do anything at this time */
1457#endif /* CONFIG_CYZ_INTR */
1458 }
1459} /* start_xmit */
1da177e4
LT
1460
1461/*
1462 * This routine shuts down a serial port; interrupts are disabled,
1463 * and DTR is dropped if the hangup on close termio flag is on.
1464 */
d13549f8 1465static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
1da177e4 1466{
875b206b 1467 struct cyclades_card *card;
02f1175c
JS
1468 unsigned long flags;
1469 void __iomem *base_addr;
875b206b 1470 int chip, channel, index;
02f1175c 1471
77451e53 1472 if (!(info->port.flags & ASYNC_INITIALIZED))
02f1175c 1473 return;
02f1175c
JS
1474
1475 card = info->card;
875b206b 1476 channel = info->line - card->first_line;
2693f485 1477 if (!cy_is_Z(card)) {
02f1175c
JS
1478 chip = channel >> 2;
1479 channel &= 0x03;
875b206b
JS
1480 index = card->bus_index;
1481 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4
LT
1482
1483#ifdef CY_DEBUG_OPEN
21719191
JS
1484 printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, "
1485 "channel %d, base_addr %p\n",
1486 card, chip, channel, base_addr);
1da177e4
LT
1487#endif
1488
9fa1b3b1 1489 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
1490
1491 /* Clear delta_msr_wait queue to avoid mem leaks. */
1492 wake_up_interruptible(&info->delta_msr_wait);
1da177e4 1493
77451e53 1494 if (info->port.xmit_buf) {
02f1175c 1495 unsigned char *temp;
77451e53
AC
1496 temp = info->port.xmit_buf;
1497 info->port.xmit_buf = NULL;
02f1175c
JS
1498 free_page((unsigned long)temp);
1499 }
4d768200
JS
1500 if (tty->termios->c_cflag & HUPCL)
1501 cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR);
1502
02f1175c
JS
1503 cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
1504 /* it may be appropriate to clear _XMIT at
1505 some later date (after testing)!!! */
1506
d13549f8 1507 set_bit(TTY_IO_ERROR, &tty->flags);
77451e53 1508 info->port.flags &= ~ASYNC_INITIALIZED;
9fa1b3b1 1509 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 1510 } else {
1da177e4 1511#ifdef CY_DEBUG_OPEN
21719191 1512 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
f0eefdc3 1513 "base_addr %p\n", card, channel, card->base_addr);
1da177e4
LT
1514#endif
1515
2693f485 1516 if (!cyz_is_loaded(card))
02f1175c 1517 return;
1da177e4 1518
9fa1b3b1 1519 spin_lock_irqsave(&card->card_lock, flags);
1da177e4 1520
77451e53 1521 if (info->port.xmit_buf) {
02f1175c 1522 unsigned char *temp;
77451e53
AC
1523 temp = info->port.xmit_buf;
1524 info->port.xmit_buf = NULL;
02f1175c 1525 free_page((unsigned long)temp);
1da177e4 1526 }
02f1175c 1527
4d768200
JS
1528 if (tty->termios->c_cflag & HUPCL)
1529 tty_port_lower_dtr_rts(&info->port);
1da177e4 1530
d13549f8 1531 set_bit(TTY_IO_ERROR, &tty->flags);
77451e53 1532 info->port.flags &= ~ASYNC_INITIALIZED;
02f1175c 1533
9fa1b3b1 1534 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 1535 }
1da177e4
LT
1536
1537#ifdef CY_DEBUG_OPEN
21719191 1538 printk(KERN_DEBUG "cyc shutdown done\n");
1da177e4 1539#endif
02f1175c 1540} /* shutdown */
1da177e4
LT
1541
1542/*
1543 * ------------------------------------------------------------
1544 * cy_open() and friends
1545 * ------------------------------------------------------------
1546 */
1547
1da177e4
LT
1548/*
1549 * This routine is called whenever a serial port is opened. It
1550 * performs the serial-specific initialization for the tty structure.
1551 */
02f1175c 1552static int cy_open(struct tty_struct *tty, struct file *filp)
1da177e4 1553{
02f1175c 1554 struct cyclades_port *info;
65f76a82
JS
1555 unsigned int i, line;
1556 int retval;
1da177e4 1557
02f1175c 1558 line = tty->index;
15ed6cc0 1559 if (tty->index < 0 || NR_PORTS <= line)
02f1175c 1560 return -ENODEV;
15ed6cc0 1561
dd025c0c
JS
1562 for (i = 0; i < NR_CARDS; i++)
1563 if (line < cy_card[i].first_line + cy_card[i].nports &&
1564 line >= cy_card[i].first_line)
1565 break;
1566 if (i >= NR_CARDS)
1567 return -ENODEV;
1568 info = &cy_card[i].ports[line - cy_card[i].first_line];
15ed6cc0 1569 if (info->line < 0)
02f1175c 1570 return -ENODEV;
1da177e4 1571
02f1175c
JS
1572 /* If the card's firmware hasn't been loaded,
1573 treat it as absent from the system. This
1574 will make the user pay attention.
1575 */
2693f485 1576 if (cy_is_Z(info->card)) {
875b206b 1577 struct cyclades_card *cinfo = info->card;
02f1175c
JS
1578 struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
1579
2693f485
JS
1580 if (!cyz_is_loaded(cinfo)) {
1581 if (cinfo->hw_ver == ZE_V1 && cyz_fpga_loaded(cinfo) &&
101b8159
JS
1582 readl(&firm_id->signature) ==
1583 ZFIRM_HLT) {
21719191
JS
1584 printk(KERN_ERR "cyc:Cyclades-Z Error: you "
1585 "need an external power supply for "
1586 "this number of ports.\nFirmware "
1587 "halted.\n");
02f1175c 1588 } else {
21719191
JS
1589 printk(KERN_ERR "cyc:Cyclades-Z firmware not "
1590 "yet loaded\n");
02f1175c
JS
1591 }
1592 return -ENODEV;
1593 }
1594#ifdef CONFIG_CYZ_INTR
1595 else {
1596 /* In case this Z board is operating in interrupt mode, its
1597 interrupts should be enabled as soon as the first open
1598 happens to one of its ports. */
1599 if (!cinfo->intr_enabled) {
97e87f8e 1600 u16 intr;
02f1175c 1601
02f1175c 1602 /* Enable interrupts on the PLX chip */
97e87f8e
JS
1603 intr = readw(&cinfo->ctl_addr.p9060->
1604 intr_ctrl_stat) | 0x0900;
1605 cy_writew(&cinfo->ctl_addr.p9060->
1606 intr_ctrl_stat, intr);
02f1175c
JS
1607 /* Enable interrupts on the FW */
1608 retval = cyz_issue_cmd(cinfo, 0,
1609 C_CM_IRQ_ENBL, 0L);
1610 if (retval != 0) {
21719191
JS
1611 printk(KERN_ERR "cyc:IRQ enable retval "
1612 "was %x\n", retval);
02f1175c 1613 }
02f1175c
JS
1614 cinfo->intr_enabled = 1;
1615 }
1da177e4 1616 }
02f1175c
JS
1617#endif /* CONFIG_CYZ_INTR */
1618 /* Make sure this Z port really exists in hardware */
1619 if (info->line > (cinfo->first_line + cinfo->nports - 1))
1620 return -ENODEV;
1da177e4 1621 }
1da177e4 1622#ifdef CY_DEBUG_OTHER
21719191 1623 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
1da177e4 1624#endif
02f1175c 1625 tty->driver_data = info;
15ed6cc0 1626 if (serial_paranoia_check(info, tty->name, "cy_open"))
02f1175c 1627 return -ENODEV;
15ed6cc0 1628
1da177e4 1629#ifdef CY_DEBUG_OPEN
21719191 1630 printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
77451e53 1631 info->port.count);
1da177e4 1632#endif
77451e53 1633 info->port.count++;
1da177e4 1634#ifdef CY_DEBUG_COUNT
21719191 1635 printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
77451e53 1636 current->pid, info->port.count);
1da177e4 1637#endif
1da177e4 1638
02f1175c
JS
1639 /*
1640 * If the port is the middle of closing, bail out now
1641 */
77451e53
AC
1642 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
1643 wait_event_interruptible(info->port.close_wait,
1644 !(info->port.flags & ASYNC_CLOSING));
1645 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
02f1175c 1646 }
1da177e4 1647
02f1175c
JS
1648 /*
1649 * Start up serial port
1650 */
d13549f8 1651 retval = cy_startup(info, tty);
15ed6cc0 1652 if (retval)
02f1175c 1653 return retval;
1da177e4 1654
f0737579 1655 retval = tty_port_block_til_ready(&info->port, tty, filp);
02f1175c 1656 if (retval) {
1da177e4 1657#ifdef CY_DEBUG_OPEN
21719191
JS
1658 printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
1659 "with %d\n", retval);
1da177e4 1660#endif
02f1175c
JS
1661 return retval;
1662 }
1da177e4 1663
02f1175c 1664 info->throttle = 0;
d13549f8 1665 tty_port_tty_set(&info->port, tty);
1da177e4 1666
02f1175c 1667#ifdef CY_DEBUG_OPEN
21719191 1668 printk(KERN_DEBUG "cyc:cy_open done\n");
02f1175c
JS
1669#endif
1670 return 0;
1671} /* cy_open */
1da177e4
LT
1672
1673/*
1674 * cy_wait_until_sent() --- wait until the transmitter is empty
1675 */
02f1175c 1676static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
1da177e4 1677{
875b206b 1678 struct cyclades_card *card;
cab9bdd1 1679 struct cyclades_port *info = tty->driver_data;
02f1175c 1680 void __iomem *base_addr;
875b206b 1681 int chip, channel, index;
02f1175c
JS
1682 unsigned long orig_jiffies;
1683 int char_time;
1684
1685 if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent"))
1686 return;
1687
1688 if (info->xmit_fifo_size == 0)
1689 return; /* Just in case.... */
1da177e4 1690
02f1175c 1691 orig_jiffies = jiffies;
978e595f 1692 lock_kernel();
02f1175c
JS
1693 /*
1694 * Set the check interval to be 1/5 of the estimated time to
1695 * send a single character, and make it at least 1. The check
1696 * interval should also be less than the timeout.
1697 *
1698 * Note: we have to use pretty tight timings here to satisfy
1699 * the NIST-PCTS.
1700 */
1701 char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size;
1702 char_time = char_time / 5;
1703 if (char_time <= 0)
1704 char_time = 1;
1705 if (timeout < 0)
1706 timeout = 0;
1707 if (timeout)
1708 char_time = min(char_time, timeout);
1709 /*
1710 * If the transmitter hasn't cleared in twice the approximate
1711 * amount of time to send the entire FIFO, it probably won't
1712 * ever clear. This assumes the UART isn't doing flow
1713 * control, which is currently the case. Hence, if it ever
1714 * takes longer than info->timeout, this is probably due to a
1715 * UART bug of some kind. So, we clamp the timeout parameter at
1716 * 2*info->timeout.
1717 */
1718 if (!timeout || timeout > 2 * info->timeout)
1719 timeout = 2 * info->timeout;
1da177e4 1720#ifdef CY_DEBUG_WAIT_UNTIL_SENT
21719191
JS
1721 printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...",
1722 timeout, char_time, jiffies);
1da177e4 1723#endif
02f1175c 1724 card = info->card;
875b206b 1725 channel = (info->line) - (card->first_line);
2693f485 1726 if (!cy_is_Z(card)) {
02f1175c
JS
1727 chip = channel >> 2;
1728 channel &= 0x03;
875b206b
JS
1729 index = card->bus_index;
1730 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
db05c3b1 1731 while (readb(base_addr + (CySRER << index)) & CyTxRdy) {
1da177e4 1732#ifdef CY_DEBUG_WAIT_UNTIL_SENT
21719191 1733 printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
1da177e4 1734#endif
02f1175c
JS
1735 if (msleep_interruptible(jiffies_to_msecs(char_time)))
1736 break;
1737 if (timeout && time_after(jiffies, orig_jiffies +
1738 timeout))
1739 break;
1740 }
1da177e4 1741 }
02f1175c
JS
1742 /* Run one more char cycle */
1743 msleep_interruptible(jiffies_to_msecs(char_time * 5));
978e595f 1744 unlock_kernel();
1da177e4 1745#ifdef CY_DEBUG_WAIT_UNTIL_SENT
21719191 1746 printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
1da177e4
LT
1747#endif
1748}
1749
978e595f
AC
1750static void cy_flush_buffer(struct tty_struct *tty)
1751{
1752 struct cyclades_port *info = tty->driver_data;
1753 struct cyclades_card *card;
1754 int channel, retval;
1755 unsigned long flags;
1756
1757#ifdef CY_DEBUG_IO
1758 printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
1759#endif
1760
1761 if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
1762 return;
1763
1764 card = info->card;
1765 channel = info->line - card->first_line;
1766
1767 spin_lock_irqsave(&card->card_lock, flags);
1768 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1769 spin_unlock_irqrestore(&card->card_lock, flags);
1770
2693f485 1771 if (cy_is_Z(card)) { /* If it is a Z card, flush the on-board
978e595f
AC
1772 buffers as well */
1773 spin_lock_irqsave(&card->card_lock, flags);
1774 retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
1775 if (retval != 0) {
1776 printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
1777 "was %x\n", info->line, retval);
1778 }
1779 spin_unlock_irqrestore(&card->card_lock, flags);
1780 }
1781 tty_wakeup(tty);
1782} /* cy_flush_buffer */
1783
1784
1da177e4
LT
1785/*
1786 * This routine is called when a particular tty device is closed.
1787 */
02f1175c 1788static void cy_close(struct tty_struct *tty, struct file *filp)
1da177e4 1789{
cab9bdd1 1790 struct cyclades_port *info = tty->driver_data;
9fa1b3b1 1791 struct cyclades_card *card;
02f1175c 1792 unsigned long flags;
1da177e4 1793
15ed6cc0 1794 if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
02f1175c 1795 return;
1da177e4 1796
9fa1b3b1
JS
1797 card = info->card;
1798
23342262 1799 if (!tty_port_close_start(&info->port, tty, filp))
02f1175c 1800 return;
15ed6cc0 1801
9fa1b3b1 1802 spin_lock_irqsave(&card->card_lock, flags);
02f1175c 1803
2693f485 1804 if (!cy_is_Z(card)) {
9fa1b3b1
JS
1805 int channel = info->line - card->first_line;
1806 int index = card->bus_index;
1807 void __iomem *base_addr = card->base_addr +
02f1175c
JS
1808 (cy_chip_offset[channel >> 2] << index);
1809 /* Stop accepting input */
1810 channel &= 0x03;
1811 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
1812 cy_writeb(base_addr + (CySRER << index),
db05c3b1 1813 readb(base_addr + (CySRER << index)) & ~CyRxData);
77451e53 1814 if (info->port.flags & ASYNC_INITIALIZED) {
15ed6cc0
AC
1815 /* Waiting for on-board buffers to be empty before
1816 closing the port */
9fa1b3b1 1817 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 1818 cy_wait_until_sent(tty, info->timeout);
9fa1b3b1 1819 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
1820 }
1821 } else {
1822#ifdef Z_WAKE
15ed6cc0
AC
1823 /* Waiting for on-board buffers to be empty before closing
1824 the port */
f0eefdc3 1825 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
9fa1b3b1 1826 int channel = info->line - card->first_line;
02f1175c
JS
1827 int retval;
1828
f0eefdc3 1829 if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) {
9fa1b3b1 1830 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
02f1175c 1831 if (retval != 0) {
21719191
JS
1832 printk(KERN_DEBUG "cyc:cy_close retval on "
1833 "ttyC%d was %x\n", info->line, retval);
02f1175c 1834 }
9fa1b3b1 1835 spin_unlock_irqrestore(&card->card_lock, flags);
2c7fea99 1836 wait_for_completion_interruptible(&info->shutdown_wait);
9fa1b3b1 1837 spin_lock_irqsave(&card->card_lock, flags);
02f1175c 1838 }
1da177e4 1839#endif
02f1175c
JS
1840 }
1841
9fa1b3b1 1842 spin_unlock_irqrestore(&card->card_lock, flags);
d13549f8 1843 cy_shutdown(info, tty);
978e595f 1844 cy_flush_buffer(tty);
02f1175c 1845
d13549f8 1846 tty_port_tty_set(&info->port, NULL);
1da177e4 1847
23342262 1848 tty_port_close_end(&info->port, tty);
02f1175c 1849} /* cy_close */
1da177e4
LT
1850
1851/* This routine gets called when tty_write has put something into
1852 * the write_queue. The characters may come from user space or
1853 * kernel space.
1854 *
1855 * This routine will return the number of characters actually
1856 * accepted for writing.
1857 *
1858 * If the port is not already transmitting stuff, start it off by
1859 * enabling interrupts. The interrupt service routine will then
1860 * ensure that the characters are sent.
1861 * If the port is already active, there is no need to kick it.
1862 *
1863 */
02f1175c 1864static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
1da177e4 1865{
cab9bdd1 1866 struct cyclades_port *info = tty->driver_data;
02f1175c
JS
1867 unsigned long flags;
1868 int c, ret = 0;
1da177e4
LT
1869
1870#ifdef CY_DEBUG_IO
21719191 1871 printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line);
1da177e4
LT
1872#endif
1873
15ed6cc0 1874 if (serial_paranoia_check(info, tty->name, "cy_write"))
02f1175c 1875 return 0;
1da177e4 1876
77451e53 1877 if (!info->port.xmit_buf)
02f1175c 1878 return 0;
1da177e4 1879
9fa1b3b1 1880 spin_lock_irqsave(&info->card->card_lock, flags);
02f1175c 1881 while (1) {
1a4e2351
HH
1882 c = min(count, (int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1));
1883 c = min(c, (int)(SERIAL_XMIT_SIZE - info->xmit_head));
02f1175c
JS
1884
1885 if (c <= 0)
1886 break;
1887
77451e53 1888 memcpy(info->port.xmit_buf + info->xmit_head, buf, c);
02f1175c
JS
1889 info->xmit_head = (info->xmit_head + c) &
1890 (SERIAL_XMIT_SIZE - 1);
1891 info->xmit_cnt += c;
1892 buf += c;
1893 count -= c;
1894 ret += c;
1895 }
9fa1b3b1 1896 spin_unlock_irqrestore(&info->card->card_lock, flags);
02f1175c
JS
1897
1898 info->idle_stats.xmit_bytes += ret;
1899 info->idle_stats.xmit_idle = jiffies;
1900
15ed6cc0 1901 if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped)
02f1175c 1902 start_xmit(info);
15ed6cc0 1903
02f1175c
JS
1904 return ret;
1905} /* cy_write */
1da177e4
LT
1906
1907/*
1908 * This routine is called by the kernel to write a single
1909 * character to the tty device. If the kernel uses this routine,
1910 * it must call the flush_chars() routine (if defined) when it is
1911 * done stuffing characters into the driver. If there is no room
1912 * in the queue, the character is ignored.
1913 */
76b25a55 1914static int cy_put_char(struct tty_struct *tty, unsigned char ch)
1da177e4 1915{
cab9bdd1 1916 struct cyclades_port *info = tty->driver_data;
02f1175c 1917 unsigned long flags;
1da177e4
LT
1918
1919#ifdef CY_DEBUG_IO
21719191 1920 printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line);
1da177e4
LT
1921#endif
1922
02f1175c 1923 if (serial_paranoia_check(info, tty->name, "cy_put_char"))
76b25a55 1924 return 0;
1da177e4 1925
77451e53 1926 if (!info->port.xmit_buf)
76b25a55 1927 return 0;
1da177e4 1928
9fa1b3b1 1929 spin_lock_irqsave(&info->card->card_lock, flags);
90cc3018 1930 if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
9fa1b3b1 1931 spin_unlock_irqrestore(&info->card->card_lock, flags);
76b25a55 1932 return 0;
02f1175c 1933 }
1da177e4 1934
77451e53 1935 info->port.xmit_buf[info->xmit_head++] = ch;
02f1175c
JS
1936 info->xmit_head &= SERIAL_XMIT_SIZE - 1;
1937 info->xmit_cnt++;
1da177e4
LT
1938 info->idle_stats.xmit_bytes++;
1939 info->idle_stats.xmit_idle = jiffies;
9fa1b3b1 1940 spin_unlock_irqrestore(&info->card->card_lock, flags);
76b25a55 1941 return 1;
02f1175c 1942} /* cy_put_char */
1da177e4
LT
1943
1944/*
1945 * This routine is called by the kernel after it has written a
15ed6cc0 1946 * series of characters to the tty device using put_char().
1da177e4 1947 */
02f1175c 1948static void cy_flush_chars(struct tty_struct *tty)
1da177e4 1949{
cab9bdd1 1950 struct cyclades_port *info = tty->driver_data;
02f1175c 1951
1da177e4 1952#ifdef CY_DEBUG_IO
21719191 1953 printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line);
1da177e4
LT
1954#endif
1955
02f1175c
JS
1956 if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
1957 return;
1da177e4 1958
02f1175c 1959 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
77451e53 1960 !info->port.xmit_buf)
02f1175c 1961 return;
1da177e4 1962
02f1175c
JS
1963 start_xmit(info);
1964} /* cy_flush_chars */
1da177e4
LT
1965
1966/*
1967 * This routine returns the numbers of characters the tty driver
1968 * will accept for queuing to be written. This number is subject
1969 * to change as output buffers get emptied, or if the output flow
1970 * control is activated.
1971 */
02f1175c 1972static int cy_write_room(struct tty_struct *tty)
1da177e4 1973{
cab9bdd1 1974 struct cyclades_port *info = tty->driver_data;
02f1175c
JS
1975 int ret;
1976
1da177e4 1977#ifdef CY_DEBUG_IO
21719191 1978 printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line);
1da177e4
LT
1979#endif
1980
02f1175c
JS
1981 if (serial_paranoia_check(info, tty->name, "cy_write_room"))
1982 return 0;
1983 ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
1984 if (ret < 0)
1985 ret = 0;
1986 return ret;
1987} /* cy_write_room */
1da177e4 1988
02f1175c 1989static int cy_chars_in_buffer(struct tty_struct *tty)
1da177e4 1990{
cab9bdd1 1991 struct cyclades_port *info = tty->driver_data;
1da177e4 1992
02f1175c
JS
1993 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
1994 return 0;
1995
1da177e4 1996#ifdef Z_EXT_CHARS_IN_BUFFER
f0eefdc3 1997 if (!cy_is_Z(info->card)) {
02f1175c 1998#endif /* Z_EXT_CHARS_IN_BUFFER */
1da177e4 1999#ifdef CY_DEBUG_IO
21719191
JS
2000 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
2001 info->line, info->xmit_cnt);
1da177e4 2002#endif
02f1175c 2003 return info->xmit_cnt;
1da177e4 2004#ifdef Z_EXT_CHARS_IN_BUFFER
02f1175c 2005 } else {
f0eefdc3 2006 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
02f1175c 2007 int char_count;
ad39c300 2008 __u32 tx_put, tx_get, tx_bufsize;
02f1175c 2009
978e595f 2010 lock_kernel();
db05c3b1
JS
2011 tx_get = readl(&buf_ctrl->tx_get);
2012 tx_put = readl(&buf_ctrl->tx_put);
2013 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
02f1175c
JS
2014 if (tx_put >= tx_get)
2015 char_count = tx_put - tx_get;
2016 else
2017 char_count = tx_put - tx_get + tx_bufsize;
1da177e4 2018#ifdef CY_DEBUG_IO
21719191
JS
2019 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
2020 info->line, info->xmit_cnt + char_count);
1da177e4 2021#endif
978e595f 2022 unlock_kernel();
096dcfce 2023 return info->xmit_cnt + char_count;
02f1175c
JS
2024 }
2025#endif /* Z_EXT_CHARS_IN_BUFFER */
2026} /* cy_chars_in_buffer */
1da177e4
LT
2027
2028/*
2029 * ------------------------------------------------------------
2030 * cy_ioctl() and friends
2031 * ------------------------------------------------------------
2032 */
2033
1a86b5e3 2034static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
1da177e4 2035{
02f1175c 2036 int co, co_val, bpr;
1a86b5e3 2037 __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
02f1175c 2038 25000000);
1da177e4 2039
02f1175c
JS
2040 if (baud == 0) {
2041 info->tbpr = info->tco = info->rbpr = info->rco = 0;
2042 return;
2043 }
1da177e4 2044
02f1175c
JS
2045 /* determine which prescaler to use */
2046 for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
2047 if (cy_clock / co_val / baud > 63)
2048 break;
2049 }
1da177e4 2050
02f1175c
JS
2051 bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
2052 if (bpr > 255)
2053 bpr = 255;
1da177e4 2054
02f1175c
JS
2055 info->tbpr = info->rbpr = bpr;
2056 info->tco = info->rco = co;
1da177e4
LT
2057}
2058
2059/*
2060 * This routine finds or computes the various line characteristics.
2061 * It used to be called config_setup
2062 */
d13549f8 2063static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
1da177e4 2064{
875b206b 2065 struct cyclades_card *card;
02f1175c
JS
2066 unsigned long flags;
2067 void __iomem *base_addr;
875b206b 2068 int chip, channel, index;
02f1175c 2069 unsigned cflag, iflag;
02f1175c
JS
2070 int baud, baud_rate = 0;
2071 int i;
2072
d13549f8 2073 if (!tty->termios) /* XXX can this happen at all? */
02f1175c 2074 return;
15ed6cc0
AC
2075
2076 if (info->line == -1)
02f1175c 2077 return;
15ed6cc0 2078
d13549f8
JS
2079 cflag = tty->termios->c_cflag;
2080 iflag = tty->termios->c_iflag;
1da177e4 2081
02f1175c
JS
2082 /*
2083 * Set up the tty->alt_speed kludge
2084 */
d13549f8
JS
2085 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2086 tty->alt_speed = 57600;
2087 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2088 tty->alt_speed = 115200;
2089 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
2090 tty->alt_speed = 230400;
2091 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
2092 tty->alt_speed = 460800;
02f1175c
JS
2093
2094 card = info->card;
875b206b 2095 channel = info->line - card->first_line;
02f1175c 2096
2693f485 2097 if (!cy_is_Z(card)) {
02f1175c 2098
875b206b 2099 index = card->bus_index;
02f1175c
JS
2100
2101 /* baud rate */
d13549f8 2102 baud = tty_get_baud_rate(tty);
77451e53 2103 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
02f1175c
JS
2104 ASYNC_SPD_CUST) {
2105 if (info->custom_divisor)
2106 baud_rate = info->baud / info->custom_divisor;
2107 else
2108 baud_rate = info->baud;
2109 } else if (baud > CD1400_MAX_SPEED) {
2110 baud = CD1400_MAX_SPEED;
2111 }
2112 /* find the baud index */
2113 for (i = 0; i < 20; i++) {
15ed6cc0 2114 if (baud == baud_table[i])
02f1175c 2115 break;
02f1175c 2116 }
15ed6cc0 2117 if (i == 20)
02f1175c 2118 i = 19; /* CD1400_MAX_SPEED */
02f1175c 2119
77451e53 2120 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
02f1175c
JS
2121 ASYNC_SPD_CUST) {
2122 cyy_baud_calc(info, baud_rate);
2123 } else {
2124 if (info->chip_rev >= CD1400_REV_J) {
2125 /* It is a CD1400 rev. J or later */
2126 info->tbpr = baud_bpr_60[i]; /* Tx BPR */
2127 info->tco = baud_co_60[i]; /* Tx CO */
2128 info->rbpr = baud_bpr_60[i]; /* Rx BPR */
2129 info->rco = baud_co_60[i]; /* Rx CO */
2130 } else {
2131 info->tbpr = baud_bpr_25[i]; /* Tx BPR */
2132 info->tco = baud_co_25[i]; /* Tx CO */
2133 info->rbpr = baud_bpr_25[i]; /* Rx BPR */
2134 info->rco = baud_co_25[i]; /* Rx CO */
2135 }
2136 }
2137 if (baud_table[i] == 134) {
2138 /* get it right for 134.5 baud */
2139 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
2140 2;
77451e53 2141 } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
02f1175c
JS
2142 ASYNC_SPD_CUST) {
2143 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2144 baud_rate) + 2;
2145 } else if (baud_table[i]) {
2146 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2147 baud_table[i]) + 2;
2148 /* this needs to be propagated into the card info */
2149 } else {
2150 info->timeout = 0;
2151 }
2152 /* By tradition (is it a standard?) a baud rate of zero
2153 implies the line should be/has been closed. A bit
2154 later in this routine such a test is performed. */
2155
2156 /* byte size and parity */
2157 info->cor5 = 0;
2158 info->cor4 = 0;
2159 /* receive threshold */
2160 info->cor3 = (info->default_threshold ?
2161 info->default_threshold : baud_cor3[i]);
2162 info->cor2 = CyETC;
2163 switch (cflag & CSIZE) {
2164 case CS5:
2165 info->cor1 = Cy_5_BITS;
2166 break;
2167 case CS6:
2168 info->cor1 = Cy_6_BITS;
2169 break;
2170 case CS7:
2171 info->cor1 = Cy_7_BITS;
2172 break;
2173 case CS8:
2174 info->cor1 = Cy_8_BITS;
2175 break;
2176 }
15ed6cc0 2177 if (cflag & CSTOPB)
02f1175c 2178 info->cor1 |= Cy_2_STOP;
15ed6cc0 2179
02f1175c 2180 if (cflag & PARENB) {
15ed6cc0 2181 if (cflag & PARODD)
02f1175c 2182 info->cor1 |= CyPARITY_O;
15ed6cc0 2183 else
02f1175c 2184 info->cor1 |= CyPARITY_E;
15ed6cc0 2185 } else
02f1175c 2186 info->cor1 |= CyPARITY_NONE;
02f1175c
JS
2187
2188 /* CTS flow control flag */
2189 if (cflag & CRTSCTS) {
77451e53 2190 info->port.flags |= ASYNC_CTS_FLOW;
02f1175c
JS
2191 info->cor2 |= CyCtsAE;
2192 } else {
77451e53 2193 info->port.flags &= ~ASYNC_CTS_FLOW;
02f1175c
JS
2194 info->cor2 &= ~CyCtsAE;
2195 }
2196 if (cflag & CLOCAL)
77451e53 2197 info->port.flags &= ~ASYNC_CHECK_CD;
02f1175c 2198 else
77451e53 2199 info->port.flags |= ASYNC_CHECK_CD;
1da177e4
LT
2200
2201 /***********************************************
2202 The hardware option, CyRtsAO, presents RTS when
2203 the chip has characters to send. Since most modems
2204 use RTS as reverse (inbound) flow control, this
2205 option is not used. If inbound flow control is
2206 necessary, DTR can be programmed to provide the
2207 appropriate signals for use with a non-standard
2208 cable. Contact Marcio Saito for details.
2209 ***********************************************/
2210
02f1175c
JS
2211 chip = channel >> 2;
2212 channel &= 0x03;
875b206b 2213 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4 2214
9fa1b3b1 2215 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2216 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
2217
2218 /* tx and rx baud rate */
2219
2220 cy_writeb(base_addr + (CyTCOR << index), info->tco);
2221 cy_writeb(base_addr + (CyTBPR << index), info->tbpr);
2222 cy_writeb(base_addr + (CyRCOR << index), info->rco);
2223 cy_writeb(base_addr + (CyRBPR << index), info->rbpr);
2224
2225 /* set line characteristics according configuration */
2226
d13549f8
JS
2227 cy_writeb(base_addr + (CySCHR1 << index), START_CHAR(tty));
2228 cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(tty));
02f1175c
JS
2229 cy_writeb(base_addr + (CyCOR1 << index), info->cor1);
2230 cy_writeb(base_addr + (CyCOR2 << index), info->cor2);
2231 cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
2232 cy_writeb(base_addr + (CyCOR4 << index), info->cor4);
2233 cy_writeb(base_addr + (CyCOR5 << index), info->cor5);
2234
2235 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
2236 CyCOR3ch, index);
2237
15ed6cc0
AC
2238 /* !!! Is this needed? */
2239 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
02f1175c
JS
2240 cy_writeb(base_addr + (CyRTPR << index),
2241 (info->default_timeout ? info->default_timeout : 0x02));
2242 /* 10ms rx timeout */
2243
d13549f8 2244 if (C_CLOCAL(tty)) {
02f1175c
JS
2245 /* without modem intr */
2246 cy_writeb(base_addr + (CySRER << index),
db05c3b1 2247 readb(base_addr + (CySRER << index)) | CyMdmCh);
02f1175c
JS
2248 /* act on 1->0 modem transitions */
2249 if ((cflag & CRTSCTS) && info->rflow) {
2250 cy_writeb(base_addr + (CyMCOR1 << index),
2251 (CyCTS | rflow_thr[i]));
2252 } else {
2253 cy_writeb(base_addr + (CyMCOR1 << index),
2254 CyCTS);
2255 }
2256 /* act on 0->1 modem transitions */
2257 cy_writeb(base_addr + (CyMCOR2 << index), CyCTS);
1da177e4 2258 } else {
02f1175c
JS
2259 /* without modem intr */
2260 cy_writeb(base_addr + (CySRER << index),
db05c3b1 2261 readb(base_addr +
02f1175c
JS
2262 (CySRER << index)) | CyMdmCh);
2263 /* act on 1->0 modem transitions */
2264 if ((cflag & CRTSCTS) && info->rflow) {
2265 cy_writeb(base_addr + (CyMCOR1 << index),
2266 (CyDSR | CyCTS | CyRI | CyDCD |
2267 rflow_thr[i]));
2268 } else {
2269 cy_writeb(base_addr + (CyMCOR1 << index),
2270 CyDSR | CyCTS | CyRI | CyDCD);
2271 }
2272 /* act on 0->1 modem transitions */
2273 cy_writeb(base_addr + (CyMCOR2 << index),
2274 CyDSR | CyCTS | CyRI | CyDCD);
1da177e4 2275 }
02f1175c 2276
4d768200
JS
2277 if (i == 0) /* baud rate is zero, turn off line */
2278 cyy_change_rts_dtr(info, 0, TIOCM_DTR);
2279 else
2280 cyy_change_rts_dtr(info, TIOCM_DTR, 0);
1da177e4 2281
d13549f8 2282 clear_bit(TTY_IO_ERROR, &tty->flags);
9fa1b3b1 2283 spin_unlock_irqrestore(&card->card_lock, flags);
1da177e4 2284
1da177e4 2285 } else {
f0eefdc3 2286 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
1a86b5e3 2287 __u32 sw_flow;
02f1175c 2288 int retval;
1da177e4 2289
2693f485 2290 if (!cyz_is_loaded(card))
02f1175c 2291 return;
1da177e4 2292
02f1175c 2293 /* baud rate */
d13549f8 2294 baud = tty_get_baud_rate(tty);
77451e53 2295 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
02f1175c
JS
2296 ASYNC_SPD_CUST) {
2297 if (info->custom_divisor)
2298 baud_rate = info->baud / info->custom_divisor;
2299 else
2300 baud_rate = info->baud;
2301 } else if (baud > CYZ_MAX_SPEED) {
2302 baud = CYZ_MAX_SPEED;
2303 }
2304 cy_writel(&ch_ctrl->comm_baud, baud);
2305
2306 if (baud == 134) {
2307 /* get it right for 134.5 baud */
2308 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
2309 2;
77451e53 2310 } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
02f1175c
JS
2311 ASYNC_SPD_CUST) {
2312 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2313 baud_rate) + 2;
2314 } else if (baud) {
2315 info->timeout = (info->xmit_fifo_size * HZ * 15 /
2316 baud) + 2;
2317 /* this needs to be propagated into the card info */
2318 } else {
2319 info->timeout = 0;
2320 }
1da177e4 2321
02f1175c
JS
2322 /* byte size and parity */
2323 switch (cflag & CSIZE) {
2324 case CS5:
2325 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS5);
2326 break;
2327 case CS6:
2328 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS6);
2329 break;
2330 case CS7:
2331 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS7);
2332 break;
2333 case CS8:
2334 cy_writel(&ch_ctrl->comm_data_l, C_DL_CS8);
2335 break;
2336 }
2337 if (cflag & CSTOPB) {
2338 cy_writel(&ch_ctrl->comm_data_l,
db05c3b1 2339 readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
02f1175c
JS
2340 } else {
2341 cy_writel(&ch_ctrl->comm_data_l,
db05c3b1 2342 readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
02f1175c
JS
2343 }
2344 if (cflag & PARENB) {
15ed6cc0 2345 if (cflag & PARODD)
02f1175c 2346 cy_writel(&ch_ctrl->comm_parity, C_PR_ODD);
15ed6cc0 2347 else
02f1175c 2348 cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN);
15ed6cc0 2349 } else
02f1175c 2350 cy_writel(&ch_ctrl->comm_parity, C_PR_NONE);
1da177e4 2351
02f1175c
JS
2352 /* CTS flow control flag */
2353 if (cflag & CRTSCTS) {
2354 cy_writel(&ch_ctrl->hw_flow,
db05c3b1 2355 readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
02f1175c 2356 } else {
db05c3b1
JS
2357 cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) &
2358 ~(C_RS_CTS | C_RS_RTS));
02f1175c
JS
2359 }
2360 /* As the HW flow control is done in firmware, the driver
2361 doesn't need to care about it */
77451e53 2362 info->port.flags &= ~ASYNC_CTS_FLOW;
02f1175c
JS
2363
2364 /* XON/XOFF/XANY flow control flags */
2365 sw_flow = 0;
2366 if (iflag & IXON) {
2367 sw_flow |= C_FL_OXX;
2368 if (iflag & IXANY)
2369 sw_flow |= C_FL_OIXANY;
2370 }
2371 cy_writel(&ch_ctrl->sw_flow, sw_flow);
2372
875b206b 2373 retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
02f1175c 2374 if (retval != 0) {
21719191
JS
2375 printk(KERN_ERR "cyc:set_line_char retval on ttyC%d "
2376 "was %x\n", info->line, retval);
02f1175c
JS
2377 }
2378
2379 /* CD sensitivity */
15ed6cc0 2380 if (cflag & CLOCAL)
77451e53 2381 info->port.flags &= ~ASYNC_CHECK_CD;
15ed6cc0 2382 else
77451e53 2383 info->port.flags |= ASYNC_CHECK_CD;
1da177e4 2384
02f1175c
JS
2385 if (baud == 0) { /* baud rate is zero, turn off line */
2386 cy_writel(&ch_ctrl->rs_control,
db05c3b1 2387 readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
1da177e4 2388#ifdef CY_DEBUG_DTR
21719191 2389 printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n");
1da177e4 2390#endif
02f1175c
JS
2391 } else {
2392 cy_writel(&ch_ctrl->rs_control,
db05c3b1 2393 readl(&ch_ctrl->rs_control) | C_RS_DTR);
1da177e4 2394#ifdef CY_DEBUG_DTR
21719191 2395 printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n");
1da177e4 2396#endif
02f1175c 2397 }
1da177e4 2398
15ed6cc0 2399 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
02f1175c 2400 if (retval != 0) {
21719191
JS
2401 printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d "
2402 "was %x\n", info->line, retval);
02f1175c 2403 }
1da177e4 2404
d13549f8 2405 clear_bit(TTY_IO_ERROR, &tty->flags);
1da177e4 2406 }
02f1175c 2407} /* set_line_char */
1da177e4 2408
6c28181c 2409static int cy_get_serial_info(struct cyclades_port *info,
15ed6cc0 2410 struct serial_struct __user *retinfo)
1da177e4 2411{
875b206b 2412 struct cyclades_card *cinfo = info->card;
6c28181c
JS
2413 struct serial_struct tmp = {
2414 .type = info->type,
2415 .line = info->line,
2416 .port = (info->card - cy_card) * 0x100 + info->line -
2417 cinfo->first_line,
2418 .irq = cinfo->irq,
2419 .flags = info->port.flags,
2420 .close_delay = info->port.close_delay,
2421 .closing_wait = info->port.closing_wait,
2422 .baud_base = info->baud,
2423 .custom_divisor = info->custom_divisor,
2424 .hub6 = 0, /*!!! */
2425 };
02f1175c 2426 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
6c28181c 2427}
1da177e4
LT
2428
2429static int
d13549f8 2430cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
15ed6cc0 2431 struct serial_struct __user *new_info)
1da177e4 2432{
02f1175c 2433 struct serial_struct new_serial;
02f1175c
JS
2434
2435 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2436 return -EFAULT;
02f1175c
JS
2437
2438 if (!capable(CAP_SYS_ADMIN)) {
44b7d1b3 2439 if (new_serial.close_delay != info->port.close_delay ||
02f1175c
JS
2440 new_serial.baud_base != info->baud ||
2441 (new_serial.flags & ASYNC_FLAGS &
2442 ~ASYNC_USR_MASK) !=
77451e53 2443 (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
02f1175c 2444 return -EPERM;
77451e53 2445 info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) |
02f1175c
JS
2446 (new_serial.flags & ASYNC_USR_MASK);
2447 info->baud = new_serial.baud_base;
2448 info->custom_divisor = new_serial.custom_divisor;
2449 goto check_and_exit;
2450 }
2451
2452 /*
2453 * OK, past this point, all the error checking has been done.
2454 * At this point, we start making changes.....
2455 */
2456
2457 info->baud = new_serial.baud_base;
2458 info->custom_divisor = new_serial.custom_divisor;
77451e53 2459 info->port.flags = (info->port.flags & ~ASYNC_FLAGS) |
02f1175c 2460 (new_serial.flags & ASYNC_FLAGS);
44b7d1b3
AC
2461 info->port.close_delay = new_serial.close_delay * HZ / 100;
2462 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
1da177e4
LT
2463
2464check_and_exit:
77451e53 2465 if (info->port.flags & ASYNC_INITIALIZED) {
d13549f8 2466 cy_set_line_char(info, tty);
02f1175c
JS
2467 return 0;
2468 } else {
d13549f8 2469 return cy_startup(info, tty);
02f1175c
JS
2470 }
2471} /* set_serial_info */
1da177e4
LT
2472
2473/*
2474 * get_lsr_info - get line status register info
2475 *
2476 * Purpose: Let user call ioctl() to get info when the UART physically
2477 * is emptied. On bus types like RS485, the transmitter must
2478 * release the bus after transmitting. This must be done when
2479 * the transmit shift register is empty, not be done when the
2480 * transmit holding register is empty. This functionality
2481 * allows an RS485 driver to be written in user space.
2482 */
15ed6cc0 2483static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
1da177e4 2484{
875b206b
JS
2485 struct cyclades_card *card;
2486 int chip, channel, index;
02f1175c
JS
2487 unsigned char status;
2488 unsigned int result;
2489 unsigned long flags;
2490 void __iomem *base_addr;
1da177e4 2491
02f1175c 2492 card = info->card;
875b206b 2493 channel = (info->line) - (card->first_line);
2693f485 2494 if (!cy_is_Z(card)) {
02f1175c
JS
2495 chip = channel >> 2;
2496 channel &= 0x03;
875b206b
JS
2497 index = card->bus_index;
2498 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 2499
9fa1b3b1 2500 spin_lock_irqsave(&card->card_lock, flags);
db05c3b1 2501 status = readb(base_addr + (CySRER << index)) &
02f1175c 2502 (CyTxRdy | CyTxMpty);
9fa1b3b1 2503 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2504 result = (status ? 0 : TIOCSER_TEMT);
2505 } else {
2506 /* Not supported yet */
2507 return -EINVAL;
2508 }
2509 return put_user(result, (unsigned long __user *)value);
1da177e4
LT
2510}
2511
02f1175c 2512static int cy_tiocmget(struct tty_struct *tty, struct file *file)
1da177e4 2513{
cab9bdd1 2514 struct cyclades_port *info = tty->driver_data;
875b206b 2515 struct cyclades_card *card;
02f1175c 2516 void __iomem *base_addr;
0d348729 2517 int result, channel;
02f1175c 2518
bf9d8929 2519 if (serial_paranoia_check(info, tty->name, __func__))
02f1175c 2520 return -ENODEV;
1da177e4 2521
02f1175c 2522 card = info->card;
875b206b 2523 channel = info->line - card->first_line;
0d348729
JS
2524
2525 lock_kernel();
2693f485 2526 if (!cy_is_Z(card)) {
0d348729
JS
2527 unsigned long flags;
2528 unsigned char status;
2529 int chip = channel >> 2;
2530 int index = card->bus_index;
2531
02f1175c 2532 channel &= 0x03;
875b206b 2533 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4 2534
9fa1b3b1 2535 spin_lock_irqsave(&card->card_lock, flags);
0d348729 2536 cy_writeb(base_addr + (CyCAR << index), (u8)channel);
db05c3b1
JS
2537 status = readb(base_addr + (CyMSVR1 << index));
2538 status |= readb(base_addr + (CyMSVR2 << index));
9fa1b3b1 2539 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2540
2541 if (info->rtsdtr_inv) {
2542 result = ((status & CyRTS) ? TIOCM_DTR : 0) |
2543 ((status & CyDTR) ? TIOCM_RTS : 0);
2544 } else {
2545 result = ((status & CyRTS) ? TIOCM_RTS : 0) |
2546 ((status & CyDTR) ? TIOCM_DTR : 0);
2547 }
2548 result |= ((status & CyDCD) ? TIOCM_CAR : 0) |
2549 ((status & CyRI) ? TIOCM_RNG : 0) |
2550 ((status & CyDSR) ? TIOCM_DSR : 0) |
2551 ((status & CyCTS) ? TIOCM_CTS : 0);
1da177e4 2552 } else {
0d348729
JS
2553 u32 lstatus;
2554
2555 if (!cyz_is_loaded(card)) {
2556 result = -ENODEV;
2557 goto end;
02f1175c 2558 }
1da177e4 2559
0d348729
JS
2560 lstatus = readl(&info->u.cyz.ch_ctrl->rs_status);
2561 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
2562 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
2563 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
2564 ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
2565 ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
2566 ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
02f1175c 2567 }
0d348729 2568end:
7b130c0e 2569 unlock_kernel();
02f1175c
JS
2570 return result;
2571} /* cy_tiomget */
1da177e4
LT
2572
2573static int
2574cy_tiocmset(struct tty_struct *tty, struct file *file,
02f1175c 2575 unsigned int set, unsigned int clear)
1da177e4 2576{
cab9bdd1 2577 struct cyclades_port *info = tty->driver_data;
875b206b 2578 struct cyclades_card *card;
02f1175c 2579 unsigned long flags;
02f1175c 2580
bf9d8929 2581 if (serial_paranoia_check(info, tty->name, __func__))
02f1175c
JS
2582 return -ENODEV;
2583
2584 card = info->card;
2693f485 2585 if (!cy_is_Z(card)) {
4d768200
JS
2586 spin_lock_irqsave(&card->card_lock, flags);
2587 cyy_change_rts_dtr(info, set, clear);
2588 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2589 } else {
0d348729
JS
2590 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2591 int retval, channel = info->line - card->first_line;
2592 u32 rs;
2593
2594 if (!cyz_is_loaded(card))
2595 return -ENODEV;
2596
2597 spin_lock_irqsave(&card->card_lock, flags);
2598 rs = readl(&ch_ctrl->rs_control);
2599 if (set & TIOCM_RTS)
2600 rs |= C_RS_RTS;
2601 if (clear & TIOCM_RTS)
2602 rs &= ~C_RS_RTS;
2603 if (set & TIOCM_DTR) {
2604 rs |= C_RS_DTR;
1da177e4 2605#ifdef CY_DEBUG_DTR
0d348729 2606 printk(KERN_DEBUG "cyc:set_modem_info raising Z DTR\n");
1da177e4 2607#endif
0d348729
JS
2608 }
2609 if (clear & TIOCM_DTR) {
2610 rs &= ~C_RS_DTR;
1da177e4 2611#ifdef CY_DEBUG_DTR
0d348729
JS
2612 printk(KERN_DEBUG "cyc:set_modem_info clearing "
2613 "Z DTR\n");
1da177e4 2614#endif
02f1175c 2615 }
0d348729 2616 cy_writel(&ch_ctrl->rs_control, rs);
9fa1b3b1 2617 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
0d348729 2618 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2619 if (retval != 0) {
21719191
JS
2620 printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
2621 "was %x\n", info->line, retval);
02f1175c 2622 }
1da177e4 2623 }
02f1175c 2624 return 0;
0d348729 2625}
1da177e4
LT
2626
2627/*
2628 * cy_break() --- routine which turns the break handling on or off
2629 */
9e98966c 2630static int cy_break(struct tty_struct *tty, int break_state)
1da177e4 2631{
cab9bdd1 2632 struct cyclades_port *info = tty->driver_data;
9fa1b3b1 2633 struct cyclades_card *card;
02f1175c 2634 unsigned long flags;
9e98966c 2635 int retval = 0;
1da177e4 2636
02f1175c 2637 if (serial_paranoia_check(info, tty->name, "cy_break"))
9e98966c 2638 return -EINVAL;
1da177e4 2639
9fa1b3b1
JS
2640 card = info->card;
2641
2642 spin_lock_irqsave(&card->card_lock, flags);
2693f485 2643 if (!cy_is_Z(card)) {
02f1175c
JS
2644 /* Let the transmit ISR take care of this (since it
2645 requires stuffing characters into the output stream).
2646 */
2647 if (break_state == -1) {
2648 if (!info->breakon) {
2649 info->breakon = 1;
2650 if (!info->xmit_cnt) {
9fa1b3b1 2651 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2652 start_xmit(info);
9fa1b3b1 2653 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2654 }
2655 }
2656 } else {
2657 if (!info->breakoff) {
2658 info->breakoff = 1;
2659 if (!info->xmit_cnt) {
9fa1b3b1 2660 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2661 start_xmit(info);
9fa1b3b1 2662 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2663 }
2664 }
1da177e4 2665 }
1da177e4 2666 } else {
02f1175c 2667 if (break_state == -1) {
9fa1b3b1
JS
2668 retval = cyz_issue_cmd(card,
2669 info->line - card->first_line,
02f1175c
JS
2670 C_CM_SET_BREAK, 0L);
2671 if (retval != 0) {
21719191
JS
2672 printk(KERN_ERR "cyc:cy_break (set) retval on "
2673 "ttyC%d was %x\n", info->line, retval);
02f1175c
JS
2674 }
2675 } else {
9fa1b3b1
JS
2676 retval = cyz_issue_cmd(card,
2677 info->line - card->first_line,
02f1175c
JS
2678 C_CM_CLR_BREAK, 0L);
2679 if (retval != 0) {
21719191
JS
2680 printk(KERN_DEBUG "cyc:cy_break (clr) retval "
2681 "on ttyC%d was %x\n", info->line,
2682 retval);
02f1175c 2683 }
1da177e4 2684 }
1da177e4 2685 }
9fa1b3b1 2686 spin_unlock_irqrestore(&card->card_lock, flags);
9e98966c 2687 return retval;
02f1175c 2688} /* cy_break */
1da177e4 2689
02f1175c 2690static int set_threshold(struct cyclades_port *info, unsigned long value)
1da177e4 2691{
875b206b 2692 struct cyclades_card *card;
02f1175c 2693 void __iomem *base_addr;
875b206b 2694 int channel, chip, index;
02f1175c 2695 unsigned long flags;
1da177e4 2696
02f1175c 2697 card = info->card;
875b206b 2698 channel = info->line - card->first_line;
2693f485 2699 if (!cy_is_Z(card)) {
02f1175c
JS
2700 chip = channel >> 2;
2701 channel &= 0x03;
875b206b 2702 index = card->bus_index;
02f1175c 2703 base_addr =
875b206b 2704 card->base_addr + (cy_chip_offset[chip] << index);
02f1175c
JS
2705
2706 info->cor3 &= ~CyREC_FIFO;
2707 info->cor3 |= value & CyREC_FIFO;
1da177e4 2708
9fa1b3b1 2709 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2710 cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
2711 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
9fa1b3b1 2712 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2713 }
2714 return 0;
2715} /* set_threshold */
1da177e4 2716
15ed6cc0
AC
2717static int get_threshold(struct cyclades_port *info,
2718 unsigned long __user *value)
1da177e4 2719{
875b206b 2720 struct cyclades_card *card;
02f1175c 2721 void __iomem *base_addr;
875b206b 2722 int channel, chip, index;
02f1175c 2723 unsigned long tmp;
1da177e4 2724
02f1175c 2725 card = info->card;
875b206b 2726 channel = info->line - card->first_line;
2693f485 2727 if (!cy_is_Z(card)) {
02f1175c
JS
2728 chip = channel >> 2;
2729 channel &= 0x03;
875b206b
JS
2730 index = card->bus_index;
2731 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 2732
db05c3b1 2733 tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
02f1175c 2734 return put_user(tmp, value);
02f1175c 2735 }
f7429034 2736 return 0;
02f1175c 2737} /* get_threshold */
1da177e4 2738
02f1175c 2739static int set_timeout(struct cyclades_port *info, unsigned long value)
1da177e4 2740{
875b206b 2741 struct cyclades_card *card;
02f1175c 2742 void __iomem *base_addr;
875b206b 2743 int channel, chip, index;
02f1175c 2744 unsigned long flags;
1da177e4 2745
02f1175c 2746 card = info->card;
875b206b 2747 channel = info->line - card->first_line;
2693f485 2748 if (!cy_is_Z(card)) {
02f1175c
JS
2749 chip = channel >> 2;
2750 channel &= 0x03;
875b206b
JS
2751 index = card->bus_index;
2752 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4 2753
9fa1b3b1 2754 spin_lock_irqsave(&card->card_lock, flags);
02f1175c 2755 cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
9fa1b3b1 2756 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2757 }
2758 return 0;
2759} /* set_timeout */
1da177e4 2760
15ed6cc0
AC
2761static int get_timeout(struct cyclades_port *info,
2762 unsigned long __user *value)
1da177e4 2763{
875b206b 2764 struct cyclades_card *card;
02f1175c 2765 void __iomem *base_addr;
875b206b 2766 int channel, chip, index;
02f1175c 2767 unsigned long tmp;
1da177e4 2768
02f1175c 2769 card = info->card;
875b206b 2770 channel = info->line - card->first_line;
2693f485 2771 if (!cy_is_Z(card)) {
02f1175c
JS
2772 chip = channel >> 2;
2773 channel &= 0x03;
875b206b
JS
2774 index = card->bus_index;
2775 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 2776
db05c3b1 2777 tmp = readb(base_addr + (CyRTPR << index));
02f1175c 2778 return put_user(tmp, value);
02f1175c 2779 }
f7429034 2780 return 0;
02f1175c 2781} /* get_timeout */
1da177e4 2782
6c28181c
JS
2783static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg,
2784 struct cyclades_icount *cprev)
1da177e4 2785{
6c28181c
JS
2786 struct cyclades_icount cnow;
2787 unsigned long flags;
2788 int ret;
1da177e4 2789
6c28181c
JS
2790 spin_lock_irqsave(&info->card->card_lock, flags);
2791 cnow = info->icount; /* atomic copy */
2792 spin_unlock_irqrestore(&info->card->card_lock, flags);
2793
2794 ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
2795 ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
2796 ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
2797 ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts));
2798
2799 *cprev = cnow;
2800
2801 return ret;
2802}
1da177e4
LT
2803
2804/*
2805 * This routine allows the tty driver to implement device-
2806 * specific ioctl's. If the ioctl number passed in cmd is
2807 * not recognized by the driver, it should return ENOIOCTLCMD.
2808 */
2809static int
02f1175c
JS
2810cy_ioctl(struct tty_struct *tty, struct file *file,
2811 unsigned int cmd, unsigned long arg)
1da177e4 2812{
cab9bdd1 2813 struct cyclades_port *info = tty->driver_data;
6c28181c 2814 struct cyclades_icount cnow; /* kernel counter temps */
02f1175c
JS
2815 int ret_val = 0;
2816 unsigned long flags;
2817 void __user *argp = (void __user *)arg;
2818
2819 if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
2820 return -ENODEV;
1da177e4
LT
2821
2822#ifdef CY_DEBUG_OTHER
21719191
JS
2823 printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
2824 info->line, cmd, arg);
1da177e4 2825#endif
7b130c0e 2826 lock_kernel();
1da177e4 2827
02f1175c
JS
2828 switch (cmd) {
2829 case CYGETMON:
6c28181c
JS
2830 if (copy_to_user(argp, &info->mon, sizeof(info->mon))) {
2831 ret_val = -EFAULT;
2832 break;
2833 }
2834 memset(&info->mon, 0, sizeof(info->mon));
02f1175c
JS
2835 break;
2836 case CYGETTHRESH:
2837 ret_val = get_threshold(info, argp);
2838 break;
2839 case CYSETTHRESH:
2840 ret_val = set_threshold(info, arg);
2841 break;
2842 case CYGETDEFTHRESH:
6c28181c
JS
2843 ret_val = put_user(info->default_threshold,
2844 (unsigned long __user *)argp);
02f1175c
JS
2845 break;
2846 case CYSETDEFTHRESH:
6c28181c 2847 info->default_threshold = arg & 0x0f;
02f1175c
JS
2848 break;
2849 case CYGETTIMEOUT:
2850 ret_val = get_timeout(info, argp);
2851 break;
2852 case CYSETTIMEOUT:
2853 ret_val = set_timeout(info, arg);
2854 break;
2855 case CYGETDEFTIMEOUT:
6c28181c
JS
2856 ret_val = put_user(info->default_timeout,
2857 (unsigned long __user *)argp);
02f1175c
JS
2858 break;
2859 case CYSETDEFTIMEOUT:
6c28181c 2860 info->default_timeout = arg & 0xff;
02f1175c 2861 break;
1da177e4 2862 case CYSETRFLOW:
02f1175c 2863 info->rflow = (int)arg;
02f1175c 2864 break;
1da177e4 2865 case CYGETRFLOW:
02f1175c
JS
2866 ret_val = info->rflow;
2867 break;
1da177e4 2868 case CYSETRTSDTR_INV:
02f1175c 2869 info->rtsdtr_inv = (int)arg;
02f1175c 2870 break;
1da177e4 2871 case CYGETRTSDTR_INV:
02f1175c
JS
2872 ret_val = info->rtsdtr_inv;
2873 break;
1da177e4 2874 case CYGETCD1400VER:
02f1175c
JS
2875 ret_val = info->chip_rev;
2876 break;
1da177e4
LT
2877#ifndef CONFIG_CYZ_INTR
2878 case CYZSETPOLLCYCLE:
02f1175c 2879 cyz_polling_cycle = (arg * HZ) / 1000;
02f1175c 2880 break;
1da177e4 2881 case CYZGETPOLLCYCLE:
02f1175c
JS
2882 ret_val = (cyz_polling_cycle * 1000) / HZ;
2883 break;
2884#endif /* CONFIG_CYZ_INTR */
1da177e4 2885 case CYSETWAIT:
44b7d1b3 2886 info->port.closing_wait = (unsigned short)arg * HZ / 100;
02f1175c 2887 break;
1da177e4 2888 case CYGETWAIT:
44b7d1b3 2889 ret_val = info->port.closing_wait / (HZ / 100);
02f1175c
JS
2890 break;
2891 case TIOCGSERIAL:
6c28181c 2892 ret_val = cy_get_serial_info(info, argp);
02f1175c
JS
2893 break;
2894 case TIOCSSERIAL:
d13549f8 2895 ret_val = cy_set_serial_info(info, tty, argp);
02f1175c
JS
2896 break;
2897 case TIOCSERGETLSR: /* Get line status register */
2898 ret_val = get_lsr_info(info, argp);
2899 break;
2900 /*
2901 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
2902 * - mask passed in arg for lines of interest
2903 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
2904 * Caller should use TIOCGICOUNT to see which one it was
2905 */
1da177e4 2906 case TIOCMIWAIT:
9fa1b3b1 2907 spin_lock_irqsave(&info->card->card_lock, flags);
02f1175c 2908 /* note the counters on entry */
2c7fea99 2909 cnow = info->icount;
9fa1b3b1 2910 spin_unlock_irqrestore(&info->card->card_lock, flags);
6c28181c
JS
2911 ret_val = wait_event_interruptible(info->delta_msr_wait,
2912 cy_cflags_changed(info, arg, &cnow));
2c7fea99 2913 break;
1da177e4 2914
02f1175c
JS
2915 /*
2916 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2917 * Return: write counters to the user passed counter struct
2918 * NB: both 1->0 and 0->1 transitions are counted except for
2919 * RI where only 0->1 is counted.
2920 */
6c28181c
JS
2921 case TIOCGICOUNT: {
2922 struct serial_icounter_struct sic = { };
2923
9fa1b3b1 2924 spin_lock_irqsave(&info->card->card_lock, flags);
02f1175c 2925 cnow = info->icount;
9fa1b3b1 2926 spin_unlock_irqrestore(&info->card->card_lock, flags);
6c28181c
JS
2927
2928 sic.cts = cnow.cts;
2929 sic.dsr = cnow.dsr;
2930 sic.rng = cnow.rng;
2931 sic.dcd = cnow.dcd;
2932 sic.rx = cnow.rx;
2933 sic.tx = cnow.tx;
2934 sic.frame = cnow.frame;
2935 sic.overrun = cnow.overrun;
2936 sic.parity = cnow.parity;
2937 sic.brk = cnow.brk;
2938 sic.buf_overrun = cnow.buf_overrun;
2939
2940 if (copy_to_user(argp, &sic, sizeof(sic)))
2941 ret_val = -EFAULT;
02f1175c 2942 break;
6c28181c 2943 }
02f1175c
JS
2944 default:
2945 ret_val = -ENOIOCTLCMD;
2946 }
7b130c0e 2947 unlock_kernel();
1da177e4
LT
2948
2949#ifdef CY_DEBUG_OTHER
21719191 2950 printk(KERN_DEBUG "cyc:cy_ioctl done\n");
1da177e4 2951#endif
02f1175c
JS
2952 return ret_val;
2953} /* cy_ioctl */
1da177e4
LT
2954
2955/*
2956 * This routine allows the tty driver to be notified when
2957 * device's termios settings have changed. Note that a
2958 * well-designed tty driver should be prepared to accept the case
2959 * where old == NULL, and try to do something rational.
2960 */
02f1175c 2961static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1da177e4 2962{
cab9bdd1 2963 struct cyclades_port *info = tty->driver_data;
1da177e4
LT
2964
2965#ifdef CY_DEBUG_OTHER
21719191 2966 printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
1da177e4
LT
2967#endif
2968
d13549f8 2969 cy_set_line_char(info, tty);
02f1175c
JS
2970
2971 if ((old_termios->c_cflag & CRTSCTS) &&
2972 !(tty->termios->c_cflag & CRTSCTS)) {
2973 tty->hw_stopped = 0;
2974 cy_start(tty);
2975 }
1da177e4 2976#if 0
02f1175c
JS
2977 /*
2978 * No need to wake up processes in open wait, since they
2979 * sample the CLOCAL flag once, and don't recheck it.
2980 * XXX It's not clear whether the current behavior is correct
2981 * or not. Hence, this may change.....
2982 */
2983 if (!(old_termios->c_cflag & CLOCAL) &&
2984 (tty->termios->c_cflag & CLOCAL))
77451e53 2985 wake_up_interruptible(&info->port.open_wait);
1da177e4 2986#endif
02f1175c 2987} /* cy_set_termios */
1da177e4
LT
2988
2989/* This function is used to send a high-priority XON/XOFF character to
2990 the device.
2991*/
02f1175c 2992static void cy_send_xchar(struct tty_struct *tty, char ch)
1da177e4 2993{
cab9bdd1 2994 struct cyclades_port *info = tty->driver_data;
875b206b
JS
2995 struct cyclades_card *card;
2996 int channel;
1da177e4 2997
02f1175c 2998 if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
1da177e4
LT
2999 return;
3000
02f1175c 3001 info->x_char = ch;
1da177e4
LT
3002
3003 if (ch)
02f1175c 3004 cy_start(tty);
1da177e4
LT
3005
3006 card = info->card;
875b206b 3007 channel = info->line - card->first_line;
1da177e4 3008
2693f485 3009 if (cy_is_Z(card)) {
02f1175c 3010 if (ch == STOP_CHAR(tty))
875b206b 3011 cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
02f1175c 3012 else if (ch == START_CHAR(tty))
875b206b 3013 cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L);
1da177e4
LT
3014 }
3015}
3016
3017/* This routine is called by the upper-layer tty layer to signal
3018 that incoming characters should be throttled because the input
3019 buffers are close to full.
3020 */
02f1175c 3021static void cy_throttle(struct tty_struct *tty)
1da177e4 3022{
cab9bdd1 3023 struct cyclades_port *info = tty->driver_data;
875b206b 3024 struct cyclades_card *card;
02f1175c 3025 unsigned long flags;
1da177e4
LT
3026
3027#ifdef CY_DEBUG_THROTTLE
02f1175c 3028 char buf[64];
1da177e4 3029
21719191 3030 printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf),
02f1175c 3031 tty->ldisc.chars_in_buffer(tty), info->line);
1da177e4
LT
3032#endif
3033
15ed6cc0 3034 if (serial_paranoia_check(info, tty->name, "cy_throttle"))
02f1175c 3035 return;
02f1175c
JS
3036
3037 card = info->card;
3038
3039 if (I_IXOFF(tty)) {
2693f485 3040 if (!cy_is_Z(card))
02f1175c
JS
3041 cy_send_xchar(tty, STOP_CHAR(tty));
3042 else
3043 info->throttle = 1;
3044 }
1da177e4 3045
02f1175c 3046 if (tty->termios->c_cflag & CRTSCTS) {
2693f485 3047 if (!cy_is_Z(card)) {
9fa1b3b1 3048 spin_lock_irqsave(&card->card_lock, flags);
4d768200 3049 cyy_change_rts_dtr(info, 0, TIOCM_RTS);
9fa1b3b1 3050 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
3051 } else {
3052 info->throttle = 1;
3053 }
3054 }
02f1175c 3055} /* cy_throttle */
1da177e4
LT
3056
3057/*
3058 * This routine notifies the tty driver that it should signal
3059 * that characters can now be sent to the tty without fear of
3060 * overrunning the input buffers of the line disciplines.
3061 */
02f1175c 3062static void cy_unthrottle(struct tty_struct *tty)
1da177e4 3063{
cab9bdd1 3064 struct cyclades_port *info = tty->driver_data;
875b206b 3065 struct cyclades_card *card;
02f1175c 3066 unsigned long flags;
1da177e4
LT
3067
3068#ifdef CY_DEBUG_THROTTLE
02f1175c
JS
3069 char buf[64];
3070
21719191 3071 printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
15ed6cc0 3072 tty_name(tty, buf), tty_chars_in_buffer(tty), info->line);
1da177e4
LT
3073#endif
3074
15ed6cc0 3075 if (serial_paranoia_check(info, tty->name, "cy_unthrottle"))
02f1175c 3076 return;
1da177e4 3077
02f1175c
JS
3078 if (I_IXOFF(tty)) {
3079 if (info->x_char)
3080 info->x_char = 0;
3081 else
3082 cy_send_xchar(tty, START_CHAR(tty));
1da177e4 3083 }
1da177e4 3084
02f1175c
JS
3085 if (tty->termios->c_cflag & CRTSCTS) {
3086 card = info->card;
2693f485 3087 if (!cy_is_Z(card)) {
9fa1b3b1 3088 spin_lock_irqsave(&card->card_lock, flags);
4d768200 3089 cyy_change_rts_dtr(info, TIOCM_RTS, 0);
9fa1b3b1 3090 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
3091 } else {
3092 info->throttle = 0;
3093 }
3094 }
02f1175c 3095} /* cy_unthrottle */
1da177e4
LT
3096
3097/* cy_start and cy_stop provide software output flow control as a
3098 function of XON/XOFF, software CTS, and other such stuff.
3099*/
02f1175c 3100static void cy_stop(struct tty_struct *tty)
1da177e4 3101{
02f1175c 3102 struct cyclades_card *cinfo;
cab9bdd1 3103 struct cyclades_port *info = tty->driver_data;
02f1175c
JS
3104 void __iomem *base_addr;
3105 int chip, channel, index;
3106 unsigned long flags;
1da177e4
LT
3107
3108#ifdef CY_DEBUG_OTHER
21719191 3109 printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line);
1da177e4
LT
3110#endif
3111
02f1175c
JS
3112 if (serial_paranoia_check(info, tty->name, "cy_stop"))
3113 return;
1da177e4 3114
875b206b 3115 cinfo = info->card;
02f1175c 3116 channel = info->line - cinfo->first_line;
2693f485 3117 if (!cy_is_Z(cinfo)) {
02f1175c
JS
3118 index = cinfo->bus_index;
3119 chip = channel >> 2;
3120 channel &= 0x03;
9fa1b3b1 3121 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
1da177e4 3122
9fa1b3b1 3123 spin_lock_irqsave(&cinfo->card_lock, flags);
02f1175c
JS
3124 cy_writeb(base_addr + (CyCAR << index),
3125 (u_char)(channel & 0x0003)); /* index channel */
3126 cy_writeb(base_addr + (CySRER << index),
db05c3b1 3127 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
9fa1b3b1 3128 spin_unlock_irqrestore(&cinfo->card_lock, flags);
02f1175c 3129 }
02f1175c 3130} /* cy_stop */
1da177e4 3131
02f1175c 3132static void cy_start(struct tty_struct *tty)
1da177e4 3133{
02f1175c 3134 struct cyclades_card *cinfo;
cab9bdd1 3135 struct cyclades_port *info = tty->driver_data;
02f1175c
JS
3136 void __iomem *base_addr;
3137 int chip, channel, index;
3138 unsigned long flags;
1da177e4
LT
3139
3140#ifdef CY_DEBUG_OTHER
21719191 3141 printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line);
1da177e4
LT
3142#endif
3143
02f1175c
JS
3144 if (serial_paranoia_check(info, tty->name, "cy_start"))
3145 return;
1da177e4 3146
875b206b 3147 cinfo = info->card;
02f1175c
JS
3148 channel = info->line - cinfo->first_line;
3149 index = cinfo->bus_index;
2693f485 3150 if (!cy_is_Z(cinfo)) {
02f1175c
JS
3151 chip = channel >> 2;
3152 channel &= 0x03;
9fa1b3b1 3153 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
1da177e4 3154
9fa1b3b1 3155 spin_lock_irqsave(&cinfo->card_lock, flags);
15ed6cc0
AC
3156 cy_writeb(base_addr + (CyCAR << index),
3157 (u_char) (channel & 0x0003)); /* index channel */
02f1175c 3158 cy_writeb(base_addr + (CySRER << index),
db05c3b1 3159 readb(base_addr + (CySRER << index)) | CyTxRdy);
9fa1b3b1 3160 spin_unlock_irqrestore(&cinfo->card_lock, flags);
02f1175c 3161 }
02f1175c 3162} /* cy_start */
1da177e4 3163
1da177e4
LT
3164/*
3165 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
3166 */
02f1175c 3167static void cy_hangup(struct tty_struct *tty)
1da177e4 3168{
cab9bdd1 3169 struct cyclades_port *info = tty->driver_data;
02f1175c 3170
1da177e4 3171#ifdef CY_DEBUG_OTHER
21719191 3172 printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line);
1da177e4
LT
3173#endif
3174
02f1175c
JS
3175 if (serial_paranoia_check(info, tty->name, "cy_hangup"))
3176 return;
1da177e4 3177
02f1175c 3178 cy_flush_buffer(tty);
d13549f8 3179 cy_shutdown(info, tty);
174e6fe0 3180 tty_port_hangup(&info->port);
02f1175c 3181} /* cy_hangup */
1da177e4 3182
f0737579
JS
3183static int cyy_carrier_raised(struct tty_port *port)
3184{
3185 struct cyclades_port *info = container_of(port, struct cyclades_port,
3186 port);
3187 struct cyclades_card *cinfo = info->card;
3188 void __iomem *base = cinfo->base_addr;
3189 unsigned long flags;
3190 int channel = info->line - cinfo->first_line;
3191 int chip = channel >> 2, index = cinfo->bus_index;
3192 u32 cd;
3193
3194 channel &= 0x03;
3195 base += cy_chip_offset[chip] << index;
3196
3197 spin_lock_irqsave(&cinfo->card_lock, flags);
3198 cy_writeb(base + (CyCAR << index), (u8)channel);
3199 cd = readb(base + (CyMSVR1 << index)) & CyDCD;
3200 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3201
3202 return cd;
3203}
3204
3205static void cyy_dtr_rts(struct tty_port *port, int raise)
3206{
3207 struct cyclades_port *info = container_of(port, struct cyclades_port,
3208 port);
3209 struct cyclades_card *cinfo = info->card;
f0737579 3210 unsigned long flags;
f0737579
JS
3211
3212 spin_lock_irqsave(&cinfo->card_lock, flags);
4d768200
JS
3213 cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0,
3214 raise ? 0 : TIOCM_RTS | TIOCM_DTR);
f0737579
JS
3215 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3216}
3217
3218static int cyz_carrier_raised(struct tty_port *port)
3219{
3220 struct cyclades_port *info = container_of(port, struct cyclades_port,
3221 port);
f0737579 3222
f0eefdc3 3223 return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD;
f0737579
JS
3224}
3225
3226static void cyz_dtr_rts(struct tty_port *port, int raise)
3227{
3228 struct cyclades_port *info = container_of(port, struct cyclades_port,
3229 port);
3230 struct cyclades_card *cinfo = info->card;
f0eefdc3 3231 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
f0737579
JS
3232 int ret, channel = info->line - cinfo->first_line;
3233 u32 rs;
3234
f0eefdc3 3235 rs = readl(&ch_ctrl->rs_control);
f0737579
JS
3236 if (raise)
3237 rs |= C_RS_RTS | C_RS_DTR;
3238 else
3239 rs &= ~(C_RS_RTS | C_RS_DTR);
f0eefdc3 3240 cy_writel(&ch_ctrl->rs_control, rs);
f0737579
JS
3241 ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L);
3242 if (ret != 0)
3243 printk(KERN_ERR "%s: retval on ttyC%d was %x\n",
3244 __func__, info->line, ret);
3245#ifdef CY_DEBUG_DTR
3246 printk(KERN_DEBUG "%s: raising Z DTR\n", __func__);
3247#endif
3248}
3249
3250static const struct tty_port_operations cyy_port_ops = {
3251 .carrier_raised = cyy_carrier_raised,
3252 .dtr_rts = cyy_dtr_rts,
3253};
3254
3255static const struct tty_port_operations cyz_port_ops = {
3256 .carrier_raised = cyz_carrier_raised,
3257 .dtr_rts = cyz_dtr_rts,
3258};
3259
1da177e4
LT
3260/*
3261 * ---------------------------------------------------------------------
3262 * cy_init() and friends
3263 *
3264 * cy_init() is called at boot-time to initialize the serial driver.
3265 * ---------------------------------------------------------------------
3266 */
3267
dd025c0c 3268static int __devinit cy_init_card(struct cyclades_card *cinfo)
0809e267
JS
3269{
3270 struct cyclades_port *info;
f0eefdc3 3271 unsigned int channel, port;
0809e267 3272
3046d50e 3273 spin_lock_init(&cinfo->card_lock);
963118ee 3274 cinfo->intr_enabled = 0;
3046d50e 3275
963118ee
JS
3276 cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports),
3277 GFP_KERNEL);
dd025c0c
JS
3278 if (cinfo->ports == NULL) {
3279 printk(KERN_ERR "Cyclades: cannot allocate ports\n");
3280 return -ENOMEM;
3281 }
3282
f0eefdc3
JS
3283 for (channel = 0, port = cinfo->first_line; channel < cinfo->nports;
3284 channel++, port++) {
3285 info = &cinfo->ports[channel];
44b7d1b3 3286 tty_port_init(&info->port);
3046d50e 3287 info->magic = CYCLADES_MAGIC;
875b206b 3288 info->card = cinfo;
3046d50e 3289 info->line = port;
3046d50e 3290
44b7d1b3
AC
3291 info->port.closing_wait = CLOSING_WAIT_DELAY;
3292 info->port.close_delay = 5 * HZ / 10;
77451e53 3293 info->port.flags = STD_COM_FLAGS;
2c7fea99 3294 init_completion(&info->shutdown_wait);
3046d50e
JS
3295 init_waitqueue_head(&info->delta_msr_wait);
3296
2693f485 3297 if (cy_is_Z(cinfo)) {
f0eefdc3
JS
3298 struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS;
3299 struct ZFW_CTRL *zfw_ctrl;
3300
f0737579 3301 info->port.ops = &cyz_port_ops;
0809e267 3302 info->type = PORT_STARTECH;
f0eefdc3
JS
3303
3304 zfw_ctrl = cinfo->base_addr +
3305 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3306 info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel];
3307 info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3308
101b8159 3309 if (cinfo->hw_ver == ZO_V1)
0809e267
JS
3310 info->xmit_fifo_size = CYZ_FIFO_SIZE;
3311 else
3046d50e 3312 info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
0809e267 3313#ifdef CONFIG_CYZ_INTR
3991428d
JS
3314 setup_timer(&cyz_rx_full_timer[port],
3315 cyz_rx_restart, (unsigned long)info);
0809e267 3316#endif
3046d50e 3317 } else {
f0eefdc3 3318 unsigned short chip_number;
963118ee 3319 int index = cinfo->bus_index;
f0eefdc3 3320
f0737579 3321 info->port.ops = &cyy_port_ops;
0809e267 3322 info->type = PORT_CIRRUS;
0809e267 3323 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
3046d50e 3324 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
0809e267
JS
3325 info->cor2 = CyETC;
3326 info->cor3 = 0x08; /* _very_ small rcv threshold */
3046d50e 3327
f0eefdc3 3328 chip_number = channel / CyPORTS_PER_CHIP;
15ed6cc0
AC
3329 info->chip_rev = readb(cinfo->base_addr +
3330 (cy_chip_offset[chip_number] << index) +
3331 (CyGFRCR << index));
3332
3333 if (info->chip_rev >= CD1400_REV_J) {
0809e267
JS
3334 /* It is a CD1400 rev. J or later */
3335 info->tbpr = baud_bpr_60[13]; /* Tx BPR */
3336 info->tco = baud_co_60[13]; /* Tx CO */
3337 info->rbpr = baud_bpr_60[13]; /* Rx BPR */
3338 info->rco = baud_co_60[13]; /* Rx CO */
0809e267
JS
3339 info->rtsdtr_inv = 1;
3340 } else {
3341 info->tbpr = baud_bpr_25[13]; /* Tx BPR */
3342 info->tco = baud_co_25[13]; /* Tx CO */
3343 info->rbpr = baud_bpr_25[13]; /* Rx BPR */
3344 info->rco = baud_co_25[13]; /* Rx CO */
0809e267
JS
3345 info->rtsdtr_inv = 0;
3346 }
3046d50e
JS
3347 info->read_status_mask = CyTIMEOUT | CySPECHAR |
3348 CyBREAK | CyPARITY | CyFRAME | CyOVERRUN;
0809e267 3349 }
3046d50e 3350
0809e267 3351 }
3046d50e
JS
3352
3353#ifndef CONFIG_CYZ_INTR
2693f485 3354 if (cy_is_Z(cinfo) && !timer_pending(&cyz_timerlist)) {
3046d50e
JS
3355 mod_timer(&cyz_timerlist, jiffies + 1);
3356#ifdef CY_PCI_DEBUG
3357 printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
3358#endif
3359 }
3360#endif
dd025c0c 3361 return 0;
0809e267
JS
3362}
3363
1da177e4
LT
3364/* initialize chips on Cyclom-Y card -- return number of valid
3365 chips (which is number of ports/4) */
31b4f0a1
JS
3366static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
3367 int index)
1da177e4 3368{
02f1175c
JS
3369 unsigned int chip_number;
3370 void __iomem *base_addr;
3371
3372 cy_writeb(true_base_addr + (Cy_HwReset << index), 0);
3373 /* Cy_HwReset is 0x1400 */
3374 cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0);
3375 /* Cy_ClrIntr is 0x1800 */
3376 udelay(500L);
3377
15ed6cc0
AC
3378 for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD;
3379 chip_number++) {
02f1175c
JS
3380 base_addr =
3381 true_base_addr + (cy_chip_offset[chip_number] << index);
3382 mdelay(1);
db05c3b1 3383 if (readb(base_addr + (CyCCR << index)) != 0x00) {
02f1175c
JS
3384 /*************
3385 printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
3386 chip_number, (unsigned long)base_addr);
3387 *************/
3388 return chip_number;
3389 }
3390
3391 cy_writeb(base_addr + (CyGFRCR << index), 0);
3392 udelay(10L);
3393
3394 /* The Cyclom-16Y does not decode address bit 9 and therefore
3395 cannot distinguish between references to chip 0 and a non-
3396 existent chip 4. If the preceding clearing of the supposed
3397 chip 4 GFRCR register appears at chip 0, there is no chip 4
3398 and this must be a Cyclom-16Y, not a Cyclom-32Ye.
3399 */
db05c3b1 3400 if (chip_number == 4 && readb(true_base_addr +
02f1175c
JS
3401 (cy_chip_offset[0] << index) +
3402 (CyGFRCR << index)) == 0) {
3403 return chip_number;
3404 }
3405
3406 cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
3407 mdelay(1);
3408
db05c3b1 3409 if (readb(base_addr + (CyGFRCR << index)) == 0x00) {
02f1175c
JS
3410 /*
3411 printk(" chip #%d at %#6lx is not responding ",
3412 chip_number, (unsigned long)base_addr);
3413 printk("(GFRCR stayed 0)\n",
3414 */
3415 return chip_number;
3416 }
db05c3b1 3417 if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) !=
02f1175c
JS
3418 0x40) {
3419 /*
3420 printk(" chip #%d at %#6lx is not valid (GFRCR == "
3421 "%#2x)\n",
3422 chip_number, (unsigned long)base_addr,
3423 base_addr[CyGFRCR<<index]);
3424 */
3425 return chip_number;
3426 }
3427 cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
db05c3b1 3428 if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
02f1175c
JS
3429 /* It is a CD1400 rev. J or later */
3430 /* Impossible to reach 5ms with this chip.
3431 Changed to 2ms instead (f = 500 Hz). */
3432 cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS);
3433 } else {
3434 /* f = 200 Hz */
3435 cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS);
3436 }
1da177e4 3437
02f1175c
JS
3438 /*
3439 printk(" chip #%d at %#6lx is rev 0x%2x\n",
3440 chip_number, (unsigned long)base_addr,
db05c3b1 3441 readb(base_addr+(CyGFRCR<<index)));
02f1175c
JS
3442 */
3443 }
3444 return chip_number;
3445} /* cyy_init_card */
1da177e4
LT
3446
3447/*
3448 * ---------------------------------------------------------------------
3449 * cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
3450 * sets global variables and return the number of ISA boards found.
3451 * ---------------------------------------------------------------------
3452 */
02f1175c 3453static int __init cy_detect_isa(void)
1da177e4
LT
3454{
3455#ifdef CONFIG_ISA
02f1175c
JS
3456 unsigned short cy_isa_irq, nboard;
3457 void __iomem *cy_isa_address;
3458 unsigned short i, j, cy_isa_nchan;
1da177e4 3459#ifdef MODULE
02f1175c 3460 int isparam = 0;
1da177e4
LT
3461#endif
3462
02f1175c 3463 nboard = 0;
1da177e4
LT
3464
3465#ifdef MODULE
3466 /* Check for module parameters */
02f1175c
JS
3467 for (i = 0; i < NR_CARDS; i++) {
3468 if (maddr[i] || i) {
3469 isparam = 1;
3470 cy_isa_addresses[i] = maddr[i];
3471 }
3472 if (!maddr[i])
3473 break;
1da177e4
LT
3474 }
3475#endif
3476
02f1175c
JS
3477 /* scan the address table probing for Cyclom-Y/ISA boards */
3478 for (i = 0; i < NR_ISA_ADDRS; i++) {
3479 unsigned int isa_address = cy_isa_addresses[i];
15ed6cc0 3480 if (isa_address == 0x0000)
096dcfce 3481 return nboard;
1da177e4 3482
02f1175c 3483 /* probe for CD1400... */
cd989b3a 3484 cy_isa_address = ioremap_nocache(isa_address, CyISA_Ywin);
3137553d
JS
3485 if (cy_isa_address == NULL) {
3486 printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
3487 "address\n");
3488 continue;
3489 }
02f1175c
JS
3490 cy_isa_nchan = CyPORTS_PER_CHIP *
3491 cyy_init_card(cy_isa_address, 0);
3492 if (cy_isa_nchan == 0) {
3137553d 3493 iounmap(cy_isa_address);
02f1175c
JS
3494 continue;
3495 }
1da177e4
LT
3496#ifdef MODULE
3497 if (isparam && irq[i])
02f1175c 3498 cy_isa_irq = irq[i];
1da177e4
LT
3499 else
3500#endif
02f1175c
JS
3501 /* find out the board's irq by probing */
3502 cy_isa_irq = detect_isa_irq(cy_isa_address);
3503 if (cy_isa_irq == 0) {
21719191
JS
3504 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the "
3505 "IRQ could not be detected.\n",
02f1175c 3506 (unsigned long)cy_isa_address);
3137553d 3507 iounmap(cy_isa_address);
02f1175c
JS
3508 continue;
3509 }
3510
3511 if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
21719191
JS
3512 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
3513 "more channels are available. Change NR_PORTS "
3514 "in cyclades.c and recompile kernel.\n",
02f1175c 3515 (unsigned long)cy_isa_address);
3137553d 3516 iounmap(cy_isa_address);
096dcfce 3517 return nboard;
02f1175c
JS
3518 }
3519 /* fill the next cy_card structure available */
3520 for (j = 0; j < NR_CARDS; j++) {
f7429034 3521 if (cy_card[j].base_addr == NULL)
02f1175c
JS
3522 break;
3523 }
3524 if (j == NR_CARDS) { /* no more cy_cards available */
21719191
JS
3525 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
3526 "more cards can be used. Change NR_CARDS in "
3527 "cyclades.c and recompile kernel.\n",
02f1175c 3528 (unsigned long)cy_isa_address);
3137553d 3529 iounmap(cy_isa_address);
096dcfce 3530 return nboard;
02f1175c
JS
3531 }
3532
3533 /* allocate IRQ */
3534 if (request_irq(cy_isa_irq, cyy_interrupt,
3535 IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
21719191
JS
3536 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
3537 "could not allocate IRQ#%d.\n",
3538 (unsigned long)cy_isa_address, cy_isa_irq);
3137553d 3539 iounmap(cy_isa_address);
096dcfce 3540 return nboard;
02f1175c
JS
3541 }
3542
3543 /* set cy_card */
3544 cy_card[j].base_addr = cy_isa_address;
97e87f8e 3545 cy_card[j].ctl_addr.p9050 = NULL;
02f1175c
JS
3546 cy_card[j].irq = (int)cy_isa_irq;
3547 cy_card[j].bus_index = 0;
3548 cy_card[j].first_line = cy_next_channel;
963118ee
JS
3549 cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
3550 cy_card[j].nports = cy_isa_nchan;
3137553d
JS
3551 if (cy_init_card(&cy_card[j])) {
3552 cy_card[j].base_addr = NULL;
3553 free_irq(cy_isa_irq, &cy_card[j]);
3554 iounmap(cy_isa_address);
3555 continue;
3556 }
02f1175c
JS
3557 nboard++;
3558
21719191
JS
3559 printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: "
3560 "%d channels starting from port %d\n",
02f1175c
JS
3561 j + 1, (unsigned long)cy_isa_address,
3562 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
21719191
JS
3563 cy_isa_irq, cy_isa_nchan, cy_next_channel);
3564
6ad1ccc1
JS
3565 for (j = cy_next_channel;
3566 j < cy_next_channel + cy_isa_nchan; j++)
3567 tty_register_device(cy_serial_driver, j, NULL);
02f1175c
JS
3568 cy_next_channel += cy_isa_nchan;
3569 }
096dcfce 3570 return nboard;
1da177e4 3571#else
096dcfce 3572 return 0;
02f1175c
JS
3573#endif /* CONFIG_ISA */
3574} /* cy_detect_isa */
1da177e4 3575
58936d8d 3576#ifdef CONFIG_PCI
054f5b0a
JS
3577static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
3578{
3579 unsigned int a;
3580
3581 for (a = 0; a < size && *str; a++, str++)
3582 if (*str & 0x80)
3583 return -EINVAL;
3584
3585 for (; a < size; a++, str++)
3586 if (*str)
3587 return -EINVAL;
3588
3589 return 0;
3590}
3591
f61e761e 3592static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
054f5b0a
JS
3593 unsigned int size)
3594{
3595 for (; size > 0; size--) {
3596 cy_writel(fpga, *data++);
3597 udelay(10);
3598 }
3599}
3600
3601static void __devinit plx_init(struct pci_dev *pdev, int irq,
3602 struct RUNTIME_9060 __iomem *addr)
1da177e4 3603{
02f1175c 3604 /* Reset PLX */
054f5b0a 3605 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x40000000);
02f1175c 3606 udelay(100L);
054f5b0a 3607 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x40000000);
02f1175c
JS
3608
3609 /* Reload Config. Registers from EEPROM */
054f5b0a 3610 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x20000000);
02f1175c 3611 udelay(100L);
054f5b0a
JS
3612 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x20000000);
3613
3614 /* For some yet unknown reason, once the PLX9060 reloads the EEPROM,
3615 * the IRQ is lost and, thus, we have to re-write it to the PCI config.
3616 * registers. This will remain here until we find a permanent fix.
3617 */
3618 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
3619}
3620
3621static int __devinit __cyz_load_fw(const struct firmware *fw,
3622 const char *name, const u32 mailbox, void __iomem *base,
3623 void __iomem *fpga)
3624{
f61e761e
DW
3625 const void *ptr = fw->data;
3626 const struct zfile_header *h = ptr;
3627 const struct zfile_config *c, *cs;
3628 const struct zfile_block *b, *bs;
054f5b0a
JS
3629 unsigned int a, tmp, len = fw->size;
3630#define BAD_FW KERN_ERR "Bad firmware: "
3631 if (len < sizeof(*h)) {
3632 printk(BAD_FW "too short: %u<%zu\n", len, sizeof(*h));
3633 return -EINVAL;
3634 }
3635
3636 cs = ptr + h->config_offset;
3637 bs = ptr + h->block_offset;
3638
3639 if ((void *)(cs + h->n_config) > ptr + len ||
3640 (void *)(bs + h->n_blocks) > ptr + len) {
3641 printk(BAD_FW "too short");
3642 return -EINVAL;
3643 }
3644
3645 if (cyc_isfwstr(h->name, sizeof(h->name)) ||
3646 cyc_isfwstr(h->date, sizeof(h->date))) {
3647 printk(BAD_FW "bad formatted header string\n");
3648 return -EINVAL;
3649 }
3650
3651 if (strncmp(name, h->name, sizeof(h->name))) {
3652 printk(BAD_FW "bad name '%s' (expected '%s')\n", h->name, name);
3653 return -EINVAL;
3654 }
3655
3656 tmp = 0;
3657 for (c = cs; c < cs + h->n_config; c++) {
3658 for (a = 0; a < c->n_blocks; a++)
3659 if (c->block_list[a] > h->n_blocks) {
3660 printk(BAD_FW "bad block ref number in cfgs\n");
3661 return -EINVAL;
3662 }
3663 if (c->mailbox == mailbox && c->function == 0) /* 0 is normal */
3664 tmp++;
3665 }
3666 if (!tmp) {
3667 printk(BAD_FW "nothing appropriate\n");
3668 return -EINVAL;
3669 }
3670
3671 for (b = bs; b < bs + h->n_blocks; b++)
3672 if (b->file_offset + b->size > len) {
3673 printk(BAD_FW "bad block data offset\n");
3674 return -EINVAL;
3675 }
3676
3677 /* everything is OK, let's seek'n'load it */
3678 for (c = cs; c < cs + h->n_config; c++)
3679 if (c->mailbox == mailbox && c->function == 0)
3680 break;
3681
3682 for (a = 0; a < c->n_blocks; a++) {
3683 b = &bs[c->block_list[a]];
3684 if (b->type == ZBLOCK_FPGA) {
3685 if (fpga != NULL)
3686 cyz_fpga_copy(fpga, ptr + b->file_offset,
3687 b->size);
3688 } else {
3689 if (base != NULL)
3690 memcpy_toio(base + b->ram_offset,
3691 ptr + b->file_offset, b->size);
3692 }
3693 }
3694#undef BAD_FW
3695 return 0;
3696}
3697
3698static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
3699 struct RUNTIME_9060 __iomem *ctl_addr, int irq)
3700{
3701 const struct firmware *fw;
3702 struct FIRM_ID __iomem *fid = base_addr + ID_ADDRESS;
3703 struct CUSTOM_REG __iomem *cust = base_addr;
3704 struct ZFW_CTRL __iomem *pt_zfwctrl;
c4923b4f 3705 void __iomem *tmp;
963118ee 3706 u32 mailbox, status, nchan;
054f5b0a
JS
3707 unsigned int i;
3708 int retval;
3709
3710 retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev);
3711 if (retval) {
3712 dev_err(&pdev->dev, "can't get firmware\n");
3713 goto err;
3714 }
3715
3716 /* Check whether the firmware is already loaded and running. If
3717 positive, skip this board */
2693f485 3718 if (__cyz_fpga_loaded(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) {
054f5b0a
JS
3719 u32 cntval = readl(base_addr + 0x190);
3720
3721 udelay(100);
3722 if (cntval != readl(base_addr + 0x190)) {
3723 /* FW counter is working, FW is running */
3724 dev_dbg(&pdev->dev, "Cyclades-Z FW already loaded. "
3725 "Skipping board.\n");
3726 retval = 0;
3727 goto err_rel;
3728 }
3729 }
3730
3731 /* start boot */
3732 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) &
3733 ~0x00030800UL);
3734
3735 mailbox = readl(&ctl_addr->mail_box_0);
3736
2693f485 3737 if (mailbox == 0 || __cyz_fpga_loaded(ctl_addr)) {
054f5b0a
JS
3738 /* stops CPU and set window to beginning of RAM */
3739 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3740 cy_writel(&cust->cpu_stop, 0);
3741 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3742 udelay(100);
3743 }
3744
3745 plx_init(pdev, irq, ctl_addr);
3746
3747 if (mailbox != 0) {
3748 /* load FPGA */
3749 retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, NULL,
3750 base_addr);
3751 if (retval)
3752 goto err_rel;
2693f485 3753 if (!__cyz_fpga_loaded(ctl_addr)) {
054f5b0a
JS
3754 dev_err(&pdev->dev, "fw upload successful, but fw is "
3755 "not loaded\n");
3756 goto err_rel;
3757 }
3758 }
3759
3760 /* stops CPU and set window to beginning of RAM */
3761 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3762 cy_writel(&cust->cpu_stop, 0);
3763 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3764 udelay(100);
3765
3766 /* clear memory */
c4923b4f 3767 for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
054f5b0a
JS
3768 cy_writeb(tmp, 255);
3769 if (mailbox != 0) {
3770 /* set window to last 512K of RAM */
3771 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE);
c4923b4f 3772 for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
054f5b0a
JS
3773 cy_writeb(tmp, 255);
3774 /* set window to beginning of RAM */
3775 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
054f5b0a
JS
3776 }
3777
3778 retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL);
3779 release_firmware(fw);
3780 if (retval)
3781 goto err;
3782
3783 /* finish boot and start boards */
3784 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3785 cy_writel(&cust->cpu_start, 0);
3786 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3787 i = 0;
3788 while ((status = readl(&fid->signature)) != ZFIRM_ID && i++ < 40)
3789 msleep(100);
3790 if (status != ZFIRM_ID) {
3791 if (status == ZFIRM_HLT) {
3792 dev_err(&pdev->dev, "you need an external power supply "
3793 "for this number of ports. Firmware halted and "
3794 "board reset.\n");
3795 retval = -EIO;
3796 goto err;
3797 }
3798 dev_warn(&pdev->dev, "fid->signature = 0x%x... Waiting "
3799 "some more time\n", status);
3800 while ((status = readl(&fid->signature)) != ZFIRM_ID &&
3801 i++ < 200)
3802 msleep(100);
3803 if (status != ZFIRM_ID) {
3804 dev_err(&pdev->dev, "Board not started in 20 seconds! "
3805 "Giving up. (fid->signature = 0x%x)\n",
3806 status);
3807 dev_info(&pdev->dev, "*** Warning ***: if you are "
3808 "upgrading the FW, please power cycle the "
3809 "system before loading the new FW to the "
3810 "Cyclades-Z.\n");
3811
2693f485 3812 if (__cyz_fpga_loaded(ctl_addr))
054f5b0a
JS
3813 plx_init(pdev, irq, ctl_addr);
3814
3815 retval = -EIO;
3816 goto err;
3817 }
3818 dev_dbg(&pdev->dev, "Firmware started after %d seconds.\n",
3819 i / 10);
3820 }
3821 pt_zfwctrl = base_addr + readl(&fid->zfwctrl_addr);
3822
3823 dev_dbg(&pdev->dev, "fid=> %p, zfwctrl_addr=> %x, npt_zfwctrl=> %p\n",
3824 base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr),
3825 base_addr + readl(&fid->zfwctrl_addr));
3826
963118ee 3827 nchan = readl(&pt_zfwctrl->board_ctrl.n_channel);
054f5b0a 3828 dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n",
963118ee 3829 readl(&pt_zfwctrl->board_ctrl.fw_version), nchan);
054f5b0a 3830
963118ee 3831 if (nchan == 0) {
054f5b0a
JS
3832 dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please "
3833 "check the connection between the Z host card and the "
3834 "serial expanders.\n");
3835
2693f485 3836 if (__cyz_fpga_loaded(ctl_addr))
054f5b0a
JS
3837 plx_init(pdev, irq, ctl_addr);
3838
3839 dev_info(&pdev->dev, "Null number of ports detected. Board "
3840 "reset.\n");
3841 retval = 0;
3842 goto err;
3843 }
3844
3845 cy_writel(&pt_zfwctrl->board_ctrl.op_system, C_OS_LINUX);
3846 cy_writel(&pt_zfwctrl->board_ctrl.dr_version, DRIVER_VERSION);
3847
3848 /*
3849 Early firmware failed to start looking for commands.
3850 This enables firmware interrupts for those commands.
3851 */
3852 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
3853 (1 << 17));
3854 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
3855 0x00030800UL);
3856
963118ee 3857 return nchan;
054f5b0a
JS
3858err_rel:
3859 release_firmware(fw);
3860err:
3861 return retval;
1da177e4
LT
3862}
3863
58936d8d
JS
3864static int __devinit cy_pci_probe(struct pci_dev *pdev,
3865 const struct pci_device_id *ent)
1da177e4 3866{
3137553d
JS
3867 void __iomem *addr0 = NULL, *addr2 = NULL;
3868 char *card_name = NULL;
101b8159 3869 u32 uninitialized_var(mailbox);
3137553d
JS
3870 unsigned int device_id, nchan = 0, card_no, i;
3871 unsigned char plx_ver;
3872 int retval, irq;
02f1175c 3873
58936d8d
JS
3874 retval = pci_enable_device(pdev);
3875 if (retval) {
3876 dev_err(&pdev->dev, "cannot enable device\n");
3137553d 3877 goto err;
58936d8d 3878 }
1da177e4 3879
58936d8d 3880 /* read PCI configuration area */
3137553d 3881 irq = pdev->irq;
58936d8d 3882 device_id = pdev->device & ~PCI_DEVICE_ID_MASK;
1da177e4 3883
3137553d
JS
3884#if defined(__alpha__)
3885 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
3886 dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low "
3887 "addresses on Alpha systems.\n");
3888 retval = -EIO;
3889 goto err_dis;
3890 }
3891#endif
3892 if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
3893 dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low "
3894 "addresses\n");
3895 retval = -EIO;
3896 goto err_dis;
3897 }
3898
3899 if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
3900 dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring "
3901 "it...\n");
3902 pdev->resource[2].flags &= ~IORESOURCE_IO;
3903 }
3904
3905 retval = pci_request_regions(pdev, "cyclades");
3906 if (retval) {
3907 dev_err(&pdev->dev, "failed to reserve resources\n");
3908 goto err_dis;
3909 }
3910
3911 retval = -EIO;
58936d8d
JS
3912 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
3913 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
3137553d 3914 card_name = "Cyclom-Y";
1da177e4 3915
24e6fd4c
JS
3916 addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
3917 CyPCI_Yctl);
3137553d
JS
3918 if (addr0 == NULL) {
3919 dev_err(&pdev->dev, "can't remap ctl region\n");
3920 goto err_reg;
58936d8d 3921 }
24e6fd4c
JS
3922 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
3923 CyPCI_Ywin);
3137553d
JS
3924 if (addr2 == NULL) {
3925 dev_err(&pdev->dev, "can't remap base region\n");
3926 goto err_unmap;
58936d8d 3927 }
1da177e4 3928
3137553d
JS
3929 nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1);
3930 if (nchan == 0) {
21719191
JS
3931 dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
3932 "Serial-Modules\n");
c847d47c 3933 goto err_unmap;
58936d8d 3934 }
58936d8d 3935 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
3137553d 3936 struct RUNTIME_9060 __iomem *ctl_addr;
21719191 3937
24e6fd4c
JS
3938 ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
3939 CyPCI_Zctl);
3137553d
JS
3940 if (addr0 == NULL) {
3941 dev_err(&pdev->dev, "can't remap ctl region\n");
3942 goto err_reg;
3943 }
58936d8d
JS
3944
3945 /* Disable interrupts on the PLX before resetting it */
97e87f8e
JS
3946 cy_writew(&ctl_addr->intr_ctrl_stat,
3947 readw(&ctl_addr->intr_ctrl_stat) & ~0x0900);
58936d8d 3948
054f5b0a 3949 plx_init(pdev, irq, addr0);
02f1175c 3950
101b8159 3951 mailbox = readl(&ctl_addr->mail_box_0);
58936d8d 3952
24e6fd4c
JS
3953 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
3954 mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin);
3137553d
JS
3955 if (addr2 == NULL) {
3956 dev_err(&pdev->dev, "can't remap base region\n");
3957 goto err_unmap;
58936d8d
JS
3958 }
3959
3960 if (mailbox == ZE_V1) {
3137553d 3961 card_name = "Cyclades-Ze";
58936d8d 3962 } else {
3137553d 3963 card_name = "Cyclades-8Zo";
1da177e4 3964#ifdef CY_PCI_DEBUG
3137553d
JS
3965 if (mailbox == ZO_V1) {
3966 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3967 dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA "
3968 "id %lx, ver %lx\n", (ulong)(0xff &
3969 readl(&((struct CUSTOM_REG *)addr2)->
3970 fpga_id)), (ulong)(0xff &
3971 readl(&((struct CUSTOM_REG *)addr2)->
3972 fpga_version)));
3973 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3974 } else {
3975 dev_info(&pdev->dev, "Cyclades-Z/PCI: New "
3976 "Cyclades-Z board. FPGA not loaded\n");
3977 }
1da177e4 3978#endif
3137553d
JS
3979 /* The following clears the firmware id word. This
3980 ensures that the driver will not attempt to talk to
3981 the board until it has been properly initialized.
3982 */
3983 if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
3984 cy_writel(addr2 + ID_ADDRESS, 0L);
58936d8d 3985 }
ace08c3c
JS
3986
3987 retval = cyz_load_fw(pdev, addr2, addr0, irq);
963118ee 3988 if (retval <= 0)
ace08c3c 3989 goto err_unmap;
963118ee 3990 nchan = retval;
3137553d
JS
3991 }
3992
3993 if ((cy_next_channel + nchan) > NR_PORTS) {
3994 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
3995 "channels are available. Change NR_PORTS in "
3996 "cyclades.c and recompile kernel.\n");
3997 goto err_unmap;
3998 }
3999 /* fill the next cy_card structure available */
4000 for (card_no = 0; card_no < NR_CARDS; card_no++) {
4001 if (cy_card[card_no].base_addr == NULL)
4002 break;
4003 }
4004 if (card_no == NR_CARDS) { /* no more cy_cards available */
4005 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
4006 "more cards can be used. Change NR_CARDS in "
4007 "cyclades.c and recompile kernel.\n");
4008 goto err_unmap;
4009 }
4010
4011 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
4012 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
4013 /* allocate IRQ */
4014 retval = request_irq(irq, cyy_interrupt,
4015 IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
4016 if (retval) {
4017 dev_err(&pdev->dev, "could not allocate IRQ\n");
4018 goto err_unmap;
58936d8d 4019 }
963118ee 4020 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
3137553d 4021 } else {
f0eefdc3
JS
4022 struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
4023 struct ZFW_CTRL __iomem *zfw_ctrl;
4024
4025 zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
4026
101b8159
JS
4027 cy_card[card_no].hw_ver = mailbox;
4028 cy_card[card_no].num_chips = (unsigned int)-1;
f0eefdc3 4029 cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
02f1175c 4030#ifdef CONFIG_CYZ_INTR
58936d8d 4031 /* allocate IRQ only if board has an IRQ */
3137553d
JS
4032 if (irq != 0 && irq != 255) {
4033 retval = request_irq(irq, cyz_interrupt,
58936d8d 4034 IRQF_SHARED, "Cyclades-Z",
3137553d 4035 &cy_card[card_no]);
58936d8d 4036 if (retval) {
21719191 4037 dev_err(&pdev->dev, "could not allocate IRQ\n");
3137553d 4038 goto err_unmap;
02f1175c 4039 }
58936d8d 4040 }
02f1175c 4041#endif /* CONFIG_CYZ_INTR */
3137553d 4042 }
02f1175c 4043
3137553d
JS
4044 /* set cy_card */
4045 cy_card[card_no].base_addr = addr2;
97e87f8e 4046 cy_card[card_no].ctl_addr.p9050 = addr0;
3137553d
JS
4047 cy_card[card_no].irq = irq;
4048 cy_card[card_no].bus_index = 1;
4049 cy_card[card_no].first_line = cy_next_channel;
963118ee 4050 cy_card[card_no].nports = nchan;
3137553d
JS
4051 retval = cy_init_card(&cy_card[card_no]);
4052 if (retval)
4053 goto err_null;
58936d8d 4054
3137553d 4055 pci_set_drvdata(pdev, &cy_card[card_no]);
58936d8d 4056
3137553d
JS
4057 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
4058 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
4059 /* enable interrupts in the PCI interface */
4060 plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
4061 switch (plx_ver) {
4062 case PLX_9050:
3137553d
JS
4063 cy_writeb(addr0 + 0x4c, 0x43);
4064 break;
4065
4066 case PLX_9060:
4067 case PLX_9080:
4068 default: /* Old boards, use PLX_9060 */
97e87f8e
JS
4069 {
4070 struct RUNTIME_9060 __iomem *ctl_addr = addr0;
4071 plx_init(pdev, irq, ctl_addr);
4072 cy_writew(&ctl_addr->intr_ctrl_stat,
4073 readw(&ctl_addr->intr_ctrl_stat) | 0x0900);
3137553d
JS
4074 break;
4075 }
97e87f8e 4076 }
58936d8d
JS
4077 }
4078
3137553d
JS
4079 dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
4080 "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel);
4081 for (i = cy_next_channel; i < cy_next_channel + nchan; i++)
4082 tty_register_device(cy_serial_driver, i, &pdev->dev);
4083 cy_next_channel += nchan;
4084
58936d8d 4085 return 0;
3137553d
JS
4086err_null:
4087 cy_card[card_no].base_addr = NULL;
4088 free_irq(irq, &cy_card[card_no]);
4089err_unmap:
24e6fd4c 4090 iounmap(addr0);
3137553d 4091 if (addr2)
24e6fd4c 4092 iounmap(addr2);
3137553d
JS
4093err_reg:
4094 pci_release_regions(pdev);
4095err_dis:
4096 pci_disable_device(pdev);
4097err:
4098 return retval;
58936d8d 4099}
58936d8d 4100
6747cd93 4101static void __devexit cy_pci_remove(struct pci_dev *pdev)
58936d8d 4102{
38d09093 4103 struct cyclades_card *cinfo = pci_get_drvdata(pdev);
f3851e73 4104 unsigned int i;
38d09093 4105
85c93fa9 4106 /* non-Z with old PLX */
2693f485 4107 if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
c2ad4c75 4108 PLX_9050)
97e87f8e 4109 cy_writeb(cinfo->ctl_addr.p9050 + 0x4c, 0);
85c93fa9
JS
4110 else
4111#ifndef CONFIG_CYZ_INTR
2693f485 4112 if (!cy_is_Z(cinfo))
85c93fa9 4113#endif
97e87f8e
JS
4114 cy_writew(&cinfo->ctl_addr.p9060->intr_ctrl_stat,
4115 readw(&cinfo->ctl_addr.p9060->intr_ctrl_stat) &
4116 ~0x0900);
85c93fa9 4117
24e6fd4c 4118 iounmap(cinfo->base_addr);
97e87f8e
JS
4119 if (cinfo->ctl_addr.p9050)
4120 iounmap(cinfo->ctl_addr.p9050);
38d09093
JS
4121 if (cinfo->irq
4122#ifndef CONFIG_CYZ_INTR
2693f485 4123 && !cy_is_Z(cinfo)
38d09093
JS
4124#endif /* CONFIG_CYZ_INTR */
4125 )
4126 free_irq(cinfo->irq, cinfo);
4127 pci_release_regions(pdev);
4128
4129 cinfo->base_addr = NULL;
6ad1ccc1
JS
4130 for (i = cinfo->first_line; i < cinfo->first_line +
4131 cinfo->nports; i++)
4132 tty_unregister_device(cy_serial_driver, i);
dd025c0c
JS
4133 cinfo->nports = 0;
4134 kfree(cinfo->ports);
38d09093
JS
4135}
4136
6747cd93
JS
4137static struct pci_driver cy_pci_driver = {
4138 .name = "cyclades",
4139 .id_table = cy_pci_dev_id,
4140 .probe = cy_pci_probe,
4141 .remove = __devexit_p(cy_pci_remove)
4142};
4143#endif
4144
444697d6 4145static int cyclades_proc_show(struct seq_file *m, void *v)
1da177e4 4146{
02f1175c 4147 struct cyclades_port *info;
dd025c0c 4148 unsigned int i, j;
02f1175c
JS
4149 __u32 cur_jifs = jiffies;
4150
444697d6 4151 seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn "
02f1175c
JS
4152 "IdleIn Overruns Ldisc\n");
4153
02f1175c 4154 /* Output one line for each known port */
dd025c0c
JS
4155 for (i = 0; i < NR_CARDS; i++)
4156 for (j = 0; j < cy_card[i].nports; j++) {
4157 info = &cy_card[i].ports[j];
4158
d13549f8
JS
4159 if (info->port.count) {
4160 /* XXX is the ldisc num worth this? */
4161 struct tty_struct *tty;
4162 struct tty_ldisc *ld;
4163 int num = 0;
4164 tty = tty_port_tty_get(&info->port);
4165 if (tty) {
4166 ld = tty_ldisc_ref(tty);
4167 if (ld) {
4168 num = ld->ops->num;
4169 tty_ldisc_deref(ld);
4170 }
4171 tty_kref_put(tty);
4172 }
444697d6 4173 seq_printf(m, "%3d %8lu %10lu %8lu "
d13549f8 4174 "%10lu %8lu %9lu %6d\n", info->line,
dd025c0c
JS
4175 (cur_jifs - info->idle_stats.in_use) /
4176 HZ, info->idle_stats.xmit_bytes,
4177 (cur_jifs - info->idle_stats.xmit_idle)/
4178 HZ, info->idle_stats.recv_bytes,
4179 (cur_jifs - info->idle_stats.recv_idle)/
4180 HZ, info->idle_stats.overruns,
d13549f8
JS
4181 num);
4182 } else
444697d6 4183 seq_printf(m, "%3d %8lu %10lu %8lu "
dd025c0c
JS
4184 "%10lu %8lu %9lu %6ld\n",
4185 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
02f1175c 4186 }
444697d6
AD
4187 return 0;
4188}
4189
4190static int cyclades_proc_open(struct inode *inode, struct file *file)
4191{
4192 return single_open(file, cyclades_proc_show, NULL);
1da177e4
LT
4193}
4194
444697d6
AD
4195static const struct file_operations cyclades_proc_fops = {
4196 .owner = THIS_MODULE,
4197 .open = cyclades_proc_open,
4198 .read = seq_read,
4199 .llseek = seq_lseek,
4200 .release = single_release,
4201};
4202
1da177e4
LT
4203/* The serial driver boot-time initialization code!
4204 Hardware I/O ports are mapped to character special devices on a
4205 first found, first allocated manner. That is, this code searches
4206 for Cyclom cards in the system. As each is found, it is probed
4207 to discover how many chips (and thus how many ports) are present.
4208 These ports are mapped to the tty ports 32 and upward in monotonic
4209 fashion. If an 8-port card is replaced with a 16-port card, the
4210 port mapping on a following card will shift.
4211
4212 This approach is different from what is used in the other serial
4213 device driver because the Cyclom is more properly a multiplexer,
4214 not just an aggregation of serial ports on one card.
4215
4216 If there are more cards with more ports than have been
4217 statically allocated above, a warning is printed and the
4218 extra ports are ignored.
4219 */
4220
b68e31d0 4221static const struct tty_operations cy_ops = {
02f1175c
JS
4222 .open = cy_open,
4223 .close = cy_close,
4224 .write = cy_write,
4225 .put_char = cy_put_char,
4226 .flush_chars = cy_flush_chars,
4227 .write_room = cy_write_room,
4228 .chars_in_buffer = cy_chars_in_buffer,
4229 .flush_buffer = cy_flush_buffer,
4230 .ioctl = cy_ioctl,
4231 .throttle = cy_throttle,
4232 .unthrottle = cy_unthrottle,
4233 .set_termios = cy_set_termios,
4234 .stop = cy_stop,
4235 .start = cy_start,
4236 .hangup = cy_hangup,
4237 .break_ctl = cy_break,
4238 .wait_until_sent = cy_wait_until_sent,
02f1175c
JS
4239 .tiocmget = cy_tiocmget,
4240 .tiocmset = cy_tiocmset,
444697d6 4241 .proc_fops = &cyclades_proc_fops,
1da177e4
LT
4242};
4243
02f1175c 4244static int __init cy_init(void)
1da177e4 4245{
dd025c0c 4246 unsigned int nboards;
9dacf3b2 4247 int retval = -ENOMEM;
02f1175c
JS
4248
4249 cy_serial_driver = alloc_tty_driver(NR_PORTS);
4250 if (!cy_serial_driver)
9dacf3b2 4251 goto err;
21719191
JS
4252
4253 printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
4254 __DATE__, __TIME__);
02f1175c
JS
4255
4256 /* Initialize the tty_driver structure */
4257
4258 cy_serial_driver->owner = THIS_MODULE;
4259 cy_serial_driver->driver_name = "cyclades";
4260 cy_serial_driver->name = "ttyC";
4261 cy_serial_driver->major = CYCLADES_MAJOR;
4262 cy_serial_driver->minor_start = 0;
4263 cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
4264 cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
4265 cy_serial_driver->init_termios = tty_std_termios;
4266 cy_serial_driver->init_termios.c_cflag =
4267 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
6ad1ccc1 4268 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
02f1175c
JS
4269 tty_set_operations(cy_serial_driver, &cy_ops);
4270
9dacf3b2
JS
4271 retval = tty_register_driver(cy_serial_driver);
4272 if (retval) {
4273 printk(KERN_ERR "Couldn't register Cyclades serial driver\n");
4274 goto err_frtty;
4275 }
02f1175c 4276
02f1175c
JS
4277 /* the code below is responsible to find the boards. Each different
4278 type of board has its own detection routine. If a board is found,
4279 the next cy_card structure available is set by the detection
4280 routine. These functions are responsible for checking the
4281 availability of cy_card and cy_port data structures and updating
4282 the cy_next_channel. */
4283
4284 /* look for isa boards */
14a55a67 4285 nboards = cy_detect_isa();
02f1175c 4286
6747cd93 4287#ifdef CONFIG_PCI
02f1175c 4288 /* look for pci boards */
6747cd93 4289 retval = pci_register_driver(&cy_pci_driver);
d941ea7d
JJ
4290 if (retval && !nboards) {
4291 tty_unregister_driver(cy_serial_driver);
4292 goto err_frtty;
4293 }
6747cd93 4294#endif
9dacf3b2
JS
4295
4296 return 0;
9dacf3b2
JS
4297err_frtty:
4298 put_tty_driver(cy_serial_driver);
4299err:
4300 return retval;
02f1175c 4301} /* cy_init */
1da177e4 4302
02f1175c 4303static void __exit cy_cleanup_module(void)
1da177e4 4304{
dd025c0c 4305 struct cyclades_card *card;
65f76a82 4306 unsigned int i, e1;
1da177e4
LT
4307
4308#ifndef CONFIG_CYZ_INTR
b7050906 4309 del_timer_sync(&cyz_timerlist);
1da177e4
LT
4310#endif /* CONFIG_CYZ_INTR */
4311
15ed6cc0
AC
4312 e1 = tty_unregister_driver(cy_serial_driver);
4313 if (e1)
21719191
JS
4314 printk(KERN_ERR "failed to unregister Cyclades serial "
4315 "driver(%d)\n", e1);
1da177e4 4316
6747cd93
JS
4317#ifdef CONFIG_PCI
4318 pci_unregister_driver(&cy_pci_driver);
4319#endif
4320
02f1175c 4321 for (i = 0; i < NR_CARDS; i++) {
dd025c0c
JS
4322 card = &cy_card[i];
4323 if (card->base_addr) {
85c93fa9 4324 /* clear interrupt */
dd025c0c
JS
4325 cy_writeb(card->base_addr + Cy_ClrIntr, 0);
4326 iounmap(card->base_addr);
97e87f8e
JS
4327 if (card->ctl_addr.p9050)
4328 iounmap(card->ctl_addr.p9050);
dd025c0c 4329 if (card->irq
1da177e4 4330#ifndef CONFIG_CYZ_INTR
2693f485 4331 && !cy_is_Z(card)
1da177e4 4332#endif /* CONFIG_CYZ_INTR */
02f1175c 4333 )
dd025c0c 4334 free_irq(card->irq, card);
65f76a82 4335 for (e1 = card->first_line; e1 < card->first_line +
dd025c0c 4336 card->nports; e1++)
6ad1ccc1 4337 tty_unregister_device(cy_serial_driver, e1);
dd025c0c 4338 kfree(card->ports);
02f1175c
JS
4339 }
4340 }
f2462bfe
JS
4341
4342 put_tty_driver(cy_serial_driver);
1da177e4
LT
4343} /* cy_cleanup_module */
4344
4345module_init(cy_init);
4346module_exit(cy_cleanup_module);
4347
4348MODULE_LICENSE("GPL");
c8e1693a 4349MODULE_VERSION(CY_VERSION);
9f56fad7 4350MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);