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