cyclades: ioctls cleanup
[linux-2.6-block.git] / drivers / char / cyclades.c
CommitLineData
1da177e4
LT
1#undef BLOCKMOVE
2#define Z_WAKE
3#undef Z_EXT_CHARS_IN_BUFFER
1da177e4
LT
4
5/*
6 * linux/drivers/char/cyclades.c
7 *
8 * This file contains the driver for the Cyclades async multiport
9 * serial boards.
10 *
11 * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
12 * Modified and maintained by Marcio Saito <marcio@cyclades.com>.
1da177e4 13 *
ebdb5135 14 * Copyright (C) 2007-2009 Jiri Slaby <jirislaby@gmail.com>
1da177e4
LT
15 *
16 * Much of the design and some of the code came from serial.c
17 * which was copyright (C) 1991, 1992 Linus Torvalds. It was
18 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
19 * and then fixed as suggested by Michael K. Johnson 12/12/92.
c8e1693a 20 * Converted to pci probing and cleaned up by Jiri Slaby.
1da177e4 21 *
1da177e4
LT
22 */
23
ebdb5135 24#define CY_VERSION "2.6"
096dcfce 25
1da177e4
LT
26/* If you need to install more boards than NR_CARDS, change the constant
27 in the definition below. No other change is necessary to support up to
28 eight boards. Beyond that you'll have to extend cy_isa_addresses. */
29
02f1175c 30#define NR_CARDS 4
1da177e4
LT
31
32/*
33 If the total number of ports is larger than NR_PORTS, change this
34 constant in the definition below. No other change is necessary to
35 support more boards/ports. */
36
02f1175c 37#define NR_PORTS 256
1da177e4 38
1da177e4
LT
39#define ZO_V1 0
40#define ZO_V2 1
41#define ZE_V1 2
42
43#define SERIAL_PARANOIA_CHECK
44#undef CY_DEBUG_OPEN
45#undef CY_DEBUG_THROTTLE
46#undef CY_DEBUG_OTHER
47#undef CY_DEBUG_IO
48#undef CY_DEBUG_COUNT
49#undef CY_DEBUG_DTR
50#undef CY_DEBUG_WAIT_UNTIL_SENT
51#undef CY_DEBUG_INTERRUPTS
52#undef CY_16Y_HACK
53#undef CY_ENABLE_MONITORING
54#undef CY_PCI_DEBUG
55
1da177e4 56/*
15ed6cc0 57 * Include section
1da177e4 58 */
1da177e4
LT
59#include <linux/module.h>
60#include <linux/errno.h>
61#include <linux/signal.h>
62#include <linux/sched.h>
63#include <linux/timer.h>
64#include <linux/interrupt.h>
65#include <linux/tty.h>
33f0f88f 66#include <linux/tty_flip.h>
1da177e4 67#include <linux/serial.h>
405f5571 68#include <linux/smp_lock.h>
1da177e4
LT
69#include <linux/major.h>
70#include <linux/string.h>
71#include <linux/fcntl.h>
72#include <linux/ptrace.h>
73#include <linux/cyclades.h>
74#include <linux/mm.h>
75#include <linux/ioport.h>
76#include <linux/init.h>
77#include <linux/delay.h>
78#include <linux/spinlock.h>
79#include <linux/bitops.h>
054f5b0a 80#include <linux/firmware.h>
9f56fad7 81#include <linux/device.h>
1da177e4 82
15ed6cc0 83#include <linux/io.h>
15ed6cc0 84#include <linux/uaccess.h>
1da177e4 85
1da177e4
LT
86#include <linux/kernel.h>
87#include <linux/pci.h>
88
89#include <linux/stat.h>
90#include <linux/proc_fs.h>
444697d6 91#include <linux/seq_file.h>
1da177e4 92
02f1175c
JS
93static void cy_throttle(struct tty_struct *tty);
94static void cy_send_xchar(struct tty_struct *tty, char ch);
1da177e4 95
1da177e4
LT
96#ifndef SERIAL_XMIT_SIZE
97#define SERIAL_XMIT_SIZE (min(PAGE_SIZE, 4096))
98#endif
1da177e4
LT
99
100#define STD_COM_FLAGS (0)
101
054f5b0a
JS
102/* firmware stuff */
103#define ZL_MAX_BLOCKS 16
104#define DRIVER_VERSION 0x02010203
105#define RAM_SIZE 0x80000
106
054f5b0a
JS
107enum zblock_type {
108 ZBLOCK_PRG = 0,
109 ZBLOCK_FPGA = 1
110};
111
112struct zfile_header {
113 char name[64];
114 char date[32];
115 char aux[32];
116 u32 n_config;
117 u32 config_offset;
118 u32 n_blocks;
119 u32 block_offset;
120 u32 reserved[9];
121} __attribute__ ((packed));
122
123struct zfile_config {
124 char name[64];
125 u32 mailbox;
126 u32 function;
127 u32 n_blocks;
128 u32 block_list[ZL_MAX_BLOCKS];
129} __attribute__ ((packed));
130
131struct zfile_block {
132 u32 type;
133 u32 file_offset;
134 u32 ram_offset;
135 u32 size;
136} __attribute__ ((packed));
137
1da177e4
LT
138static struct tty_driver *cy_serial_driver;
139
140#ifdef CONFIG_ISA
141/* This is the address lookup table. The driver will probe for
142 Cyclom-Y/ISA boards at all addresses in here. If you want the
143 driver to probe addresses at a different address, add it to
144 this table. If the driver is probing some other board and
145 causing problems, remove the offending address from this table.
1da177e4
LT
146*/
147
148static unsigned int cy_isa_addresses[] = {
02f1175c
JS
149 0xD0000,
150 0xD2000,
151 0xD4000,
152 0xD6000,
153 0xD8000,
154 0xDA000,
155 0xDC000,
156 0xDE000,
157 0, 0, 0, 0, 0, 0, 0, 0
1da177e4 158};
02f1175c 159
fe971071 160#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
1da177e4
LT
161
162#ifdef MODULE
3046d50e
JS
163static long maddr[NR_CARDS];
164static int irq[NR_CARDS];
1da177e4
LT
165
166module_param_array(maddr, long, NULL, 0);
167module_param_array(irq, int, NULL, 0);
168#endif
169
02f1175c 170#endif /* CONFIG_ISA */
1da177e4
LT
171
172/* This is the per-card data structure containing address, irq, number of
173 channels, etc. This driver supports a maximum of NR_CARDS cards.
174*/
175static struct cyclades_card cy_card[NR_CARDS];
176
02f1175c 177static int cy_next_channel; /* next minor available */
1da177e4 178
1da177e4
LT
179/*
180 * This is used to look up the divisor speeds and the timeouts
181 * We're normally limited to 15 distinct baud rates. The extra
77451e53 182 * are accessed via settings in info->port.flags.
1da177e4
LT
183 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
184 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
185 * HI VHI
186 * 20
187 */
ebdb5135 188static const int baud_table[] = {
02f1175c
JS
189 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
190 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
191 230400, 0
192};
193
ebdb5135 194static const char baud_co_25[] = { /* 25 MHz clock option table */
02f1175c
JS
195 /* value => 00 01 02 03 04 */
196 /* divide by 8 32 128 512 2048 */
197 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
198 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
199};
200
ebdb5135 201static const char baud_bpr_25[] = { /* 25 MHz baud rate period table */
02f1175c
JS
202 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
203 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
204};
205
ebdb5135 206static const char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */
02f1175c
JS
207 /* value => 00 01 02 03 04 */
208 /* divide by 8 32 128 512 2048 */
209 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
210 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00
212};
213
ebdb5135 214static const char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */
02f1175c
JS
215 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
216 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
217 0x21
218};
219
ebdb5135 220static const char baud_cor3[] = { /* receive threshold */
02f1175c
JS
221 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
222 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
223 0x07
224};
1da177e4
LT
225
226/*
227 * The Cyclades driver implements HW flow control as any serial driver.
15ed6cc0
AC
228 * The cyclades_port structure member rflow and the vector rflow_thr
229 * allows us to take advantage of a special feature in the CD1400 to avoid
230 * data loss even when the system interrupt latency is too high. These flags
231 * are to be used only with very special applications. Setting these flags
232 * requires the use of a special cable (DTR and RTS reversed). In the new
233 * CD1400-based boards (rev. 6.00 or later), there is no need for special
1da177e4
LT
234 * cables.
235 */
236
ebdb5135 237static const char rflow_thr[] = { /* rflow threshold */
02f1175c
JS
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
240 0x0a
241};
1da177e4
LT
242
243/* The Cyclom-Ye has placed the sequential chips in non-sequential
244 * address order. This look-up table overcomes that problem.
245 */
f0eefdc3 246static const unsigned int cy_chip_offset[] = { 0x0000,
02f1175c
JS
247 0x0400,
248 0x0800,
249 0x0C00,
250 0x0200,
251 0x0600,
252 0x0A00,
253 0x0E00
254};
1da177e4
LT
255
256/* PCI related definitions */
257
1da177e4 258#ifdef CONFIG_PCI
ebdb5135 259static const struct pci_device_id cy_pci_dev_id[] = {
15ed6cc0
AC
260 /* PCI < 1Mb */
261 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) },
262 /* PCI > 1Mb */
263 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) },
264 /* 4Y PCI < 1Mb */
265 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) },
266 /* 4Y PCI > 1Mb */
267 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) },
268 /* 8Y PCI < 1Mb */
269 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) },
270 /* 8Y PCI > 1Mb */
271 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) },
272 /* Z PCI < 1Mb */
273 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) },
274 /* Z PCI > 1Mb */
275 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) },
893de2df 276 { } /* end of table */
02f1175c 277};
893de2df 278MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
1da177e4
LT
279#endif
280
281static void cy_start(struct tty_struct *);
d13549f8 282static void cy_set_line_char(struct cyclades_port *, struct tty_struct *);
1a86b5e3 283static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
1da177e4
LT
284#ifdef CONFIG_ISA
285static unsigned detect_isa_irq(void __iomem *);
02f1175c 286#endif /* CONFIG_ISA */
1da177e4 287
1da177e4
LT
288#ifndef CONFIG_CYZ_INTR
289static void cyz_poll(unsigned long);
290
291/* The Cyclades-Z polling cycle is defined by this variable */
292static long cyz_polling_cycle = CZ_DEF_POLL;
293
8d06afab 294static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
1da177e4 295
02f1175c 296#else /* CONFIG_CYZ_INTR */
1da177e4
LT
297static void cyz_rx_restart(unsigned long);
298static struct timer_list cyz_rx_full_timer[NR_PORTS];
02f1175c 299#endif /* CONFIG_CYZ_INTR */
1da177e4 300
2693f485
JS
301static inline bool cy_is_Z(struct cyclades_card *card)
302{
303 return card->num_chips == (unsigned int)-1;
304}
305
306static inline bool __cyz_fpga_loaded(struct RUNTIME_9060 __iomem *ctl_addr)
307{
308 return readl(&ctl_addr->init_ctrl) & (1 << 17);
309}
310
311static inline bool cyz_fpga_loaded(struct cyclades_card *card)
312{
313 return __cyz_fpga_loaded(card->ctl_addr.p9060);
314}
315
316static inline bool cyz_is_loaded(struct cyclades_card *card)
317{
318 struct FIRM_ID __iomem *fw_id = card->base_addr + ID_ADDRESS;
319
320 return (card->hw_ver == ZO_V1 || cyz_fpga_loaded(card)) &&
321 readl(&fw_id->signature) == ZFIRM_ID;
322}
323
02f1175c 324static inline int serial_paranoia_check(struct cyclades_port *info,
ebdb5135 325 const char *name, const char *routine)
1da177e4
LT
326{
327#ifdef SERIAL_PARANOIA_CHECK
02f1175c 328 if (!info) {
21719191
JS
329 printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) "
330 "in %s\n", name, routine);
02f1175c
JS
331 return 1;
332 }
333
02f1175c 334 if (info->magic != CYCLADES_MAGIC) {
21719191
JS
335 printk(KERN_WARNING "cyc Warning: bad magic number for serial "
336 "struct (%s) in %s\n", name, routine);
02f1175c
JS
337 return 1;
338 }
1da177e4 339#endif
02f1175c 340 return 0;
ebdb5135 341}
1da177e4 342
1da177e4
LT
343/***********************************************************/
344/********* Start of block of Cyclom-Y specific code ********/
345
346/* This routine waits up to 1000 micro-seconds for the previous
347 command to the Cirrus chip to complete and then issues the
348 new command. An error is returned if the previous command
349 didn't finish within the time limit.
350
351 This function is only called from inside spinlock-protected code.
352 */
15ed6cc0 353static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
1da177e4 354{
ad39c300 355 unsigned int i;
1da177e4 356
02f1175c
JS
357 /* Check to see that the previous command has completed */
358 for (i = 0; i < 100; i++) {
15ed6cc0 359 if (readb(base_addr + (CyCCR << index)) == 0)
02f1175c 360 break;
02f1175c 361 udelay(10L);
1da177e4 362 }
02f1175c
JS
363 /* if the CCR never cleared, the previous command
364 didn't finish within the "reasonable time" */
365 if (i == 100)
096dcfce 366 return -1;
1da177e4 367
02f1175c
JS
368 /* Issue the new command */
369 cy_writeb(base_addr + (CyCCR << index), cmd);
1da177e4 370
096dcfce 371 return 0;
02f1175c 372} /* cyy_issue_cmd */
1da177e4
LT
373
374#ifdef CONFIG_ISA
375/* ISA interrupt detection code */
15ed6cc0 376static unsigned detect_isa_irq(void __iomem *address)
1da177e4 377{
02f1175c
JS
378 int irq;
379 unsigned long irqs, flags;
380 int save_xir, save_car;
381 int index = 0; /* IRQ probing is only for ISA */
382
383 /* forget possible initially masked and pending IRQ */
384 irq = probe_irq_off(probe_irq_on());
385
386 /* Clear interrupts on the board first */
387 cy_writeb(address + (Cy_ClrIntr << index), 0);
388 /* Cy_ClrIntr is 0x1800 */
389
390 irqs = probe_irq_on();
391 /* Wait ... */
f6e208c1 392 msleep(5);
02f1175c
JS
393
394 /* Enable the Tx interrupts on the CD1400 */
395 local_irq_save(flags);
396 cy_writeb(address + (CyCAR << index), 0);
397 cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
398
399 cy_writeb(address + (CyCAR << index), 0);
400 cy_writeb(address + (CySRER << index),
db05c3b1 401 readb(address + (CySRER << index)) | CyTxRdy);
02f1175c
JS
402 local_irq_restore(flags);
403
404 /* Wait ... */
f6e208c1 405 msleep(5);
02f1175c
JS
406
407 /* Check which interrupt is in use */
408 irq = probe_irq_off(irqs);
409
410 /* Clean up */
db05c3b1
JS
411 save_xir = (u_char) readb(address + (CyTIR << index));
412 save_car = readb(address + (CyCAR << index));
02f1175c
JS
413 cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
414 cy_writeb(address + (CySRER << index),
db05c3b1 415 readb(address + (CySRER << index)) & ~CyTxRdy);
02f1175c
JS
416 cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
417 cy_writeb(address + (CyCAR << index), (save_car));
418 cy_writeb(address + (Cy_ClrIntr << index), 0);
419 /* Cy_ClrIntr is 0x1800 */
420
421 return (irq > 0) ? irq : 0;
1da177e4 422}
02f1175c 423#endif /* CONFIG_ISA */
1da177e4 424
ce97a097
JS
425static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
426 void __iomem *base_addr)
e941027f
JS
427{
428 struct cyclades_port *info;
429 struct tty_struct *tty;
65f76a82
JS
430 int len, index = cinfo->bus_index;
431 u8 save_xir, channel, save_car, data, char_count;
e941027f 432
e941027f 433#ifdef CY_DEBUG_INTERRUPTS
ce97a097 434 printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
e941027f 435#endif
ce97a097 436 /* determine the channel & change to that context */
65f76a82
JS
437 save_xir = readb(base_addr + (CyRIR << index));
438 channel = save_xir & CyIRChannel;
ce97a097
JS
439 info = &cinfo->ports[channel + chip * 4];
440 save_car = readb(base_addr + (CyCAR << index));
441 cy_writeb(base_addr + (CyCAR << index), save_xir);
442
d13549f8 443 tty = tty_port_tty_get(&info->port);
ce97a097 444 /* if there is nowhere to put the data, discard it */
d13549f8 445 if (tty == NULL) {
65f76a82
JS
446 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
447 CyIVRRxEx) { /* exception */
ce97a097
JS
448 data = readb(base_addr + (CyRDSR << index));
449 } else { /* normal character reception */
450 char_count = readb(base_addr + (CyRDCR << index));
451 while (char_count--)
db05c3b1 452 data = readb(base_addr + (CyRDSR << index));
ce97a097
JS
453 }
454 goto end;
455 }
456 /* there is an open port for this data */
65f76a82
JS
457 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
458 CyIVRRxEx) { /* exception */
ce97a097
JS
459 data = readb(base_addr + (CyRDSR << index));
460
461 /* For statistics only */
462 if (data & CyBREAK)
463 info->icount.brk++;
464 else if (data & CyFRAME)
465 info->icount.frame++;
466 else if (data & CyPARITY)
467 info->icount.parity++;
468 else if (data & CyOVERRUN)
469 info->icount.overrun++;
470
471 if (data & info->ignore_status_mask) {
472 info->icount.rx++;
d13549f8 473 tty_kref_put(tty);
ce97a097
JS
474 return;
475 }
476 if (tty_buffer_request_room(tty, 1)) {
477 if (data & info->read_status_mask) {
478 if (data & CyBREAK) {
479 tty_insert_flip_char(tty,
480 readb(base_addr + (CyRDSR <<
481 index)), TTY_BREAK);
482 info->icount.rx++;
77451e53 483 if (info->port.flags & ASYNC_SAK)
ce97a097
JS
484 do_SAK(tty);
485 } else if (data & CyFRAME) {
15ed6cc0 486 tty_insert_flip_char(tty,
ce97a097
JS
487 readb(base_addr + (CyRDSR <<
488 index)), TTY_FRAME);
489 info->icount.rx++;
490 info->idle_stats.frame_errs++;
491 } else if (data & CyPARITY) {
492 /* Pieces of seven... */
493 tty_insert_flip_char(tty,
494 readb(base_addr + (CyRDSR <<
495 index)), TTY_PARITY);
496 info->icount.rx++;
497 info->idle_stats.parity_errs++;
498 } else if (data & CyOVERRUN) {
499 tty_insert_flip_char(tty, 0,
500 TTY_OVERRUN);
501 info->icount.rx++;
502 /* If the flip buffer itself is
503 overflowing, we still lose
504 the next incoming character.
505 */
506 tty_insert_flip_char(tty,
507 readb(base_addr + (CyRDSR <<
508 index)), TTY_FRAME);
02f1175c 509 info->icount.rx++;
02f1175c 510 info->idle_stats.overruns++;
ce97a097
JS
511 /* These two conditions may imply */
512 /* a normal read should be done. */
513 /* } else if(data & CyTIMEOUT) { */
514 /* } else if(data & CySPECHAR) { */
515 } else {
516 tty_insert_flip_char(tty, 0,
517 TTY_NORMAL);
518 info->icount.rx++;
02f1175c 519 }
ce97a097
JS
520 } else {
521 tty_insert_flip_char(tty, 0, TTY_NORMAL);
522 info->icount.rx++;
523 }
524 } else {
525 /* there was a software buffer overrun and nothing
526 * could be done about it!!! */
527 info->icount.buf_overrun++;
528 info->idle_stats.overruns++;
529 }
530 } else { /* normal character reception */
531 /* load # chars available from the chip */
532 char_count = readb(base_addr + (CyRDCR << index));
e941027f
JS
533
534#ifdef CY_ENABLE_MONITORING
ce97a097
JS
535 ++info->mon.int_count;
536 info->mon.char_count += char_count;
537 if (char_count > info->mon.char_max)
538 info->mon.char_max = char_count;
539 info->mon.char_last = char_count;
e941027f 540#endif
ce97a097
JS
541 len = tty_buffer_request_room(tty, char_count);
542 while (len--) {
543 data = readb(base_addr + (CyRDSR << index));
544 tty_insert_flip_char(tty, data, TTY_NORMAL);
545 info->idle_stats.recv_bytes++;
546 info->icount.rx++;
e941027f 547#ifdef CY_16Y_HACK
ce97a097 548 udelay(10L);
e941027f 549#endif
e941027f 550 }
ce97a097 551 info->idle_stats.recv_idle = jiffies;
e941027f 552 }
ce97a097 553 tty_schedule_flip(tty);
d13549f8 554 tty_kref_put(tty);
ce97a097
JS
555end:
556 /* end of service */
557 cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
558 cy_writeb(base_addr + (CyCAR << index), save_car);
ce97a097 559}
e941027f 560
65f76a82 561static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
ce97a097
JS
562 void __iomem *base_addr)
563{
564 struct cyclades_port *info;
d13549f8 565 struct tty_struct *tty;
65f76a82
JS
566 int char_count, index = cinfo->bus_index;
567 u8 save_xir, channel, save_car, outch;
ce97a097
JS
568
569 /* Since we only get here when the transmit buffer
570 is empty, we know we can always stuff a dozen
571 characters. */
e941027f 572#ifdef CY_DEBUG_INTERRUPTS
ce97a097 573 printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
e941027f
JS
574#endif
575
ce97a097 576 /* determine the channel & change to that context */
65f76a82
JS
577 save_xir = readb(base_addr + (CyTIR << index));
578 channel = save_xir & CyIRChannel;
ce97a097
JS
579 save_car = readb(base_addr + (CyCAR << index));
580 cy_writeb(base_addr + (CyCAR << index), save_xir);
581
582 /* validate the port# (as configured and open) */
583 if (channel + chip * 4 >= cinfo->nports) {
584 cy_writeb(base_addr + (CySRER << index),
585 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
586 goto end;
587 }
588 info = &cinfo->ports[channel + chip * 4];
d13549f8
JS
589 tty = tty_port_tty_get(&info->port);
590 if (tty == NULL) {
ce97a097
JS
591 cy_writeb(base_addr + (CySRER << index),
592 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
593 goto end;
594 }
02f1175c 595
ce97a097
JS
596 /* load the on-chip space for outbound data */
597 char_count = info->xmit_fifo_size;
02f1175c 598
ce97a097
JS
599 if (info->x_char) { /* send special char */
600 outch = info->x_char;
601 cy_writeb(base_addr + (CyTDR << index), outch);
602 char_count--;
603 info->icount.tx++;
604 info->x_char = 0;
605 }
02f1175c 606
ce97a097
JS
607 if (info->breakon || info->breakoff) {
608 if (info->breakon) {
609 cy_writeb(base_addr + (CyTDR << index), 0);
610 cy_writeb(base_addr + (CyTDR << index), 0x81);
611 info->breakon = 0;
612 char_count -= 2;
e941027f 613 }
ce97a097
JS
614 if (info->breakoff) {
615 cy_writeb(base_addr + (CyTDR << index), 0);
616 cy_writeb(base_addr + (CyTDR << index), 0x83);
617 info->breakoff = 0;
618 char_count -= 2;
e941027f 619 }
ce97a097 620 }
02f1175c 621
ce97a097
JS
622 while (char_count-- > 0) {
623 if (!info->xmit_cnt) {
624 if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
625 cy_writeb(base_addr + (CySRER << index),
626 readb(base_addr + (CySRER << index)) &
02f1175c 627 ~CyTxMpty);
ce97a097
JS
628 } else {
629 cy_writeb(base_addr + (CySRER << index),
630 (readb(base_addr + (CySRER << index)) &
02f1175c 631 ~CyTxRdy) | CyTxMpty);
02f1175c 632 }
ce97a097
JS
633 goto done;
634 }
77451e53 635 if (info->port.xmit_buf == NULL) {
ce97a097
JS
636 cy_writeb(base_addr + (CySRER << index),
637 readb(base_addr + (CySRER << index)) &
02f1175c 638 ~CyTxRdy);
ce97a097
JS
639 goto done;
640 }
d13549f8 641 if (tty->stopped || tty->hw_stopped) {
ce97a097
JS
642 cy_writeb(base_addr + (CySRER << index),
643 readb(base_addr + (CySRER << index)) &
02f1175c 644 ~CyTxRdy);
ce97a097
JS
645 goto done;
646 }
647 /* Because the Embedded Transmit Commands have been enabled,
648 * we must check to see if the escape character, NULL, is being
649 * sent. If it is, we must ensure that there is room for it to
650 * be doubled in the output stream. Therefore we no longer
651 * advance the pointer when the character is fetched, but
652 * rather wait until after the check for a NULL output
653 * character. This is necessary because there may not be room
654 * for the two chars needed to send a NULL.)
655 */
77451e53 656 outch = info->port.xmit_buf[info->xmit_tail];
ce97a097
JS
657 if (outch) {
658 info->xmit_cnt--;
659 info->xmit_tail = (info->xmit_tail + 1) &
660 (SERIAL_XMIT_SIZE - 1);
661 cy_writeb(base_addr + (CyTDR << index), outch);
662 info->icount.tx++;
663 } else {
664 if (char_count > 1) {
02f1175c
JS
665 info->xmit_cnt--;
666 info->xmit_tail = (info->xmit_tail + 1) &
ce97a097 667 (SERIAL_XMIT_SIZE - 1);
02f1175c 668 cy_writeb(base_addr + (CyTDR << index), outch);
ce97a097 669 cy_writeb(base_addr + (CyTDR << index), 0);
02f1175c 670 info->icount.tx++;
ce97a097 671 char_count--;
02f1175c 672 }
e941027f 673 }
e941027f
JS
674 }
675
ce97a097 676done:
d13549f8
JS
677 tty_wakeup(tty);
678 tty_kref_put(tty);
ce97a097
JS
679end:
680 /* end of service */
681 cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
682 cy_writeb(base_addr + (CyCAR << index), save_car);
ce97a097 683}
02f1175c 684
ce97a097
JS
685static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
686 void __iomem *base_addr)
687{
688 struct cyclades_port *info;
d13549f8 689 struct tty_struct *tty;
65f76a82
JS
690 int index = cinfo->bus_index;
691 u8 save_xir, channel, save_car, mdm_change, mdm_status;
ce97a097
JS
692
693 /* determine the channel & change to that context */
65f76a82
JS
694 save_xir = readb(base_addr + (CyMIR << index));
695 channel = save_xir & CyIRChannel;
ce97a097
JS
696 info = &cinfo->ports[channel + chip * 4];
697 save_car = readb(base_addr + (CyCAR << index));
698 cy_writeb(base_addr + (CyCAR << index), save_xir);
699
700 mdm_change = readb(base_addr + (CyMISR << index));
701 mdm_status = readb(base_addr + (CyMSVR1 << index));
702
d13549f8
JS
703 tty = tty_port_tty_get(&info->port);
704 if (!tty)
ce97a097
JS
705 goto end;
706
707 if (mdm_change & CyANY_DELTA) {
708 /* For statistics only */
709 if (mdm_change & CyDCD)
710 info->icount.dcd++;
711 if (mdm_change & CyCTS)
712 info->icount.cts++;
713 if (mdm_change & CyDSR)
714 info->icount.dsr++;
715 if (mdm_change & CyRI)
716 info->icount.rng++;
717
718 wake_up_interruptible(&info->delta_msr_wait);
719 }
720
77451e53 721 if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
174e6fe0
JS
722 if (mdm_status & CyDCD)
723 wake_up_interruptible(&info->port.open_wait);
724 else
d13549f8 725 tty_hangup(tty);
ce97a097 726 }
77451e53 727 if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
d13549f8 728 if (tty->hw_stopped) {
ce97a097
JS
729 if (mdm_status & CyCTS) {
730 /* cy_start isn't used
731 because... !!! */
d13549f8 732 tty->hw_stopped = 0;
ce97a097
JS
733 cy_writeb(base_addr + (CySRER << index),
734 readb(base_addr + (CySRER << index)) |
735 CyTxRdy);
d13549f8 736 tty_wakeup(tty);
02f1175c 737 }
ce97a097
JS
738 } else {
739 if (!(mdm_status & CyCTS)) {
740 /* cy_stop isn't used
741 because ... !!! */
d13549f8 742 tty->hw_stopped = 1;
ce97a097
JS
743 cy_writeb(base_addr + (CySRER << index),
744 readb(base_addr + (CySRER << index)) &
745 ~CyTxRdy);
02f1175c 746 }
e941027f 747 }
e941027f 748 }
ce97a097
JS
749/* if (mdm_change & CyDSR) {
750 }
751 if (mdm_change & CyRI) {
752 }*/
d13549f8 753 tty_kref_put(tty);
ce97a097
JS
754end:
755 /* end of service */
756 cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
757 cy_writeb(base_addr + (CyCAR << index), save_car);
e941027f
JS
758}
759
1da177e4
LT
760/* The real interrupt service routine is called
761 whenever the card wants its hand held--chars
762 received, out buffer empty, modem change, etc.
763 */
02f1175c 764static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1da177e4 765{
02f1175c 766 int status;
f7429034 767 struct cyclades_card *cinfo = dev_id;
02f1175c 768 void __iomem *base_addr, *card_base_addr;
65f76a82 769 unsigned int chip, too_many, had_work;
02f1175c 770 int index;
02f1175c 771
f7429034 772 if (unlikely(cinfo == NULL)) {
1da177e4 773#ifdef CY_DEBUG_INTERRUPTS
15ed6cc0
AC
774 printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",
775 irq);
1da177e4 776#endif
02f1175c
JS
777 return IRQ_NONE; /* spurious interrupt */
778 }
779
780 card_base_addr = cinfo->base_addr;
781 index = cinfo->bus_index;
782
f1e83c6c
JS
783 /* card was not initialized yet (e.g. DEBUG_SHIRQ) */
784 if (unlikely(card_base_addr == NULL))
785 return IRQ_HANDLED;
786
02f1175c
JS
787 /* This loop checks all chips in the card. Make a note whenever
788 _any_ chip had some work to do, as this is considered an
789 indication that there will be more to do. Only when no chip
790 has any work does this outermost loop exit.
791 */
792 do {
793 had_work = 0;
794 for (chip = 0; chip < cinfo->num_chips; chip++) {
795 base_addr = cinfo->base_addr +
796 (cy_chip_offset[chip] << index);
797 too_many = 0;
db05c3b1 798 while ((status = readb(base_addr +
02f1175c
JS
799 (CySVRR << index))) != 0x00) {
800 had_work++;
801 /* The purpose of the following test is to ensure that
802 no chip can monopolize the driver. This forces the
803 chips to be checked in a round-robin fashion (after
804 draining each of a bunch (1000) of characters).
805 */
ce97a097 806 if (1000 < too_many++)
02f1175c 807 break;
1c0a387c 808 spin_lock(&cinfo->card_lock);
ce97a097
JS
809 if (status & CySRReceive) /* rx intr */
810 cyy_chip_rx(cinfo, chip, base_addr);
811 if (status & CySRTransmit) /* tx intr */
812 cyy_chip_tx(cinfo, chip, base_addr);
813 if (status & CySRModem) /* modem intr */
814 cyy_chip_modem(cinfo, chip, base_addr);
1c0a387c 815 spin_unlock(&cinfo->card_lock);
02f1175c
JS
816 }
817 }
818 } while (had_work);
819
820 /* clear interrupts */
821 spin_lock(&cinfo->card_lock);
822 cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0);
823 /* Cy_ClrIntr is 0x1800 */
824 spin_unlock(&cinfo->card_lock);
825 return IRQ_HANDLED;
826} /* cyy_interrupt */
1da177e4 827
4d768200
JS
828static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set,
829 unsigned int clear)
830{
831 struct cyclades_card *card = info->card;
832 void __iomem *base_addr;
833 int chip, channel, index;
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 2413
6c28181c 2414static int cy_get_serial_info(struct cyclades_port *info,
15ed6cc0 2415 struct serial_struct __user *retinfo)
1da177e4 2416{
875b206b 2417 struct cyclades_card *cinfo = info->card;
6c28181c
JS
2418 struct serial_struct tmp = {
2419 .type = info->type,
2420 .line = info->line,
2421 .port = (info->card - cy_card) * 0x100 + info->line -
2422 cinfo->first_line,
2423 .irq = cinfo->irq,
2424 .flags = info->port.flags,
2425 .close_delay = info->port.close_delay,
2426 .closing_wait = info->port.closing_wait,
2427 .baud_base = info->baud,
2428 .custom_divisor = info->custom_divisor,
2429 .hub6 = 0, /*!!! */
2430 };
02f1175c 2431 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
6c28181c 2432}
1da177e4
LT
2433
2434static int
d13549f8 2435cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
15ed6cc0 2436 struct serial_struct __user *new_info)
1da177e4 2437{
02f1175c 2438 struct serial_struct new_serial;
02f1175c
JS
2439
2440 if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2441 return -EFAULT;
02f1175c
JS
2442
2443 if (!capable(CAP_SYS_ADMIN)) {
44b7d1b3 2444 if (new_serial.close_delay != info->port.close_delay ||
02f1175c
JS
2445 new_serial.baud_base != info->baud ||
2446 (new_serial.flags & ASYNC_FLAGS &
2447 ~ASYNC_USR_MASK) !=
77451e53 2448 (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
02f1175c 2449 return -EPERM;
77451e53 2450 info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) |
02f1175c
JS
2451 (new_serial.flags & ASYNC_USR_MASK);
2452 info->baud = new_serial.baud_base;
2453 info->custom_divisor = new_serial.custom_divisor;
2454 goto check_and_exit;
2455 }
2456
2457 /*
2458 * OK, past this point, all the error checking has been done.
2459 * At this point, we start making changes.....
2460 */
2461
2462 info->baud = new_serial.baud_base;
2463 info->custom_divisor = new_serial.custom_divisor;
77451e53 2464 info->port.flags = (info->port.flags & ~ASYNC_FLAGS) |
02f1175c 2465 (new_serial.flags & ASYNC_FLAGS);
44b7d1b3
AC
2466 info->port.close_delay = new_serial.close_delay * HZ / 100;
2467 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
1da177e4
LT
2468
2469check_and_exit:
77451e53 2470 if (info->port.flags & ASYNC_INITIALIZED) {
d13549f8 2471 cy_set_line_char(info, tty);
02f1175c
JS
2472 return 0;
2473 } else {
d13549f8 2474 return cy_startup(info, tty);
02f1175c
JS
2475 }
2476} /* set_serial_info */
1da177e4
LT
2477
2478/*
2479 * get_lsr_info - get line status register info
2480 *
2481 * Purpose: Let user call ioctl() to get info when the UART physically
2482 * is emptied. On bus types like RS485, the transmitter must
2483 * release the bus after transmitting. This must be done when
2484 * the transmit shift register is empty, not be done when the
2485 * transmit holding register is empty. This functionality
2486 * allows an RS485 driver to be written in user space.
2487 */
15ed6cc0 2488static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
1da177e4 2489{
875b206b
JS
2490 struct cyclades_card *card;
2491 int chip, channel, index;
02f1175c
JS
2492 unsigned char status;
2493 unsigned int result;
2494 unsigned long flags;
2495 void __iomem *base_addr;
1da177e4 2496
02f1175c 2497 card = info->card;
875b206b 2498 channel = (info->line) - (card->first_line);
2693f485 2499 if (!cy_is_Z(card)) {
02f1175c
JS
2500 chip = channel >> 2;
2501 channel &= 0x03;
875b206b
JS
2502 index = card->bus_index;
2503 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 2504
9fa1b3b1 2505 spin_lock_irqsave(&card->card_lock, flags);
db05c3b1 2506 status = readb(base_addr + (CySRER << index)) &
02f1175c 2507 (CyTxRdy | CyTxMpty);
9fa1b3b1 2508 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2509 result = (status ? 0 : TIOCSER_TEMT);
2510 } else {
2511 /* Not supported yet */
2512 return -EINVAL;
2513 }
2514 return put_user(result, (unsigned long __user *)value);
1da177e4
LT
2515}
2516
02f1175c 2517static int cy_tiocmget(struct tty_struct *tty, struct file *file)
1da177e4 2518{
cab9bdd1 2519 struct cyclades_port *info = tty->driver_data;
875b206b
JS
2520 struct cyclades_card *card;
2521 int chip, channel, index;
02f1175c
JS
2522 void __iomem *base_addr;
2523 unsigned long flags;
2524 unsigned char status;
2525 unsigned long lstatus;
2526 unsigned int result;
02f1175c 2527
bf9d8929 2528 if (serial_paranoia_check(info, tty->name, __func__))
02f1175c 2529 return -ENODEV;
1da177e4 2530
7b130c0e
AC
2531 lock_kernel();
2532
02f1175c 2533 card = info->card;
875b206b 2534 channel = info->line - card->first_line;
2693f485 2535 if (!cy_is_Z(card)) {
02f1175c
JS
2536 chip = channel >> 2;
2537 channel &= 0x03;
875b206b
JS
2538 index = card->bus_index;
2539 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4 2540
9fa1b3b1 2541 spin_lock_irqsave(&card->card_lock, flags);
02f1175c 2542 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
db05c3b1
JS
2543 status = readb(base_addr + (CyMSVR1 << index));
2544 status |= readb(base_addr + (CyMSVR2 << index));
9fa1b3b1 2545 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2546
2547 if (info->rtsdtr_inv) {
2548 result = ((status & CyRTS) ? TIOCM_DTR : 0) |
2549 ((status & CyDTR) ? TIOCM_RTS : 0);
2550 } else {
2551 result = ((status & CyRTS) ? TIOCM_RTS : 0) |
2552 ((status & CyDTR) ? TIOCM_DTR : 0);
2553 }
2554 result |= ((status & CyDCD) ? TIOCM_CAR : 0) |
2555 ((status & CyRI) ? TIOCM_RNG : 0) |
2556 ((status & CyDSR) ? TIOCM_DSR : 0) |
2557 ((status & CyCTS) ? TIOCM_CTS : 0);
1da177e4 2558 } else {
2693f485 2559 if (cyz_is_loaded(card)) {
f0eefdc3 2560 lstatus = readl(&info->u.cyz.ch_ctrl->rs_status);
02f1175c
JS
2561 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
2562 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
2563 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
2564 ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
2565 ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
2566 ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
2567 } else {
2568 result = 0;
7b130c0e 2569 unlock_kernel();
02f1175c
JS
2570 return -ENODEV;
2571 }
1da177e4 2572
02f1175c 2573 }
7b130c0e 2574 unlock_kernel();
02f1175c
JS
2575 return result;
2576} /* cy_tiomget */
1da177e4
LT
2577
2578static int
2579cy_tiocmset(struct tty_struct *tty, struct file *file,
02f1175c 2580 unsigned int set, unsigned int clear)
1da177e4 2581{
cab9bdd1 2582 struct cyclades_port *info = tty->driver_data;
875b206b 2583 struct cyclades_card *card;
02f1175c 2584 unsigned long flags;
4d768200 2585 int channel, retval;
02f1175c 2586
bf9d8929 2587 if (serial_paranoia_check(info, tty->name, __func__))
02f1175c
JS
2588 return -ENODEV;
2589
2590 card = info->card;
875b206b 2591 channel = (info->line) - (card->first_line);
2693f485 2592 if (!cy_is_Z(card)) {
4d768200
JS
2593 spin_lock_irqsave(&card->card_lock, flags);
2594 cyy_change_rts_dtr(info, set, clear);
2595 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2596 } else {
2693f485 2597 if (cyz_is_loaded(card)) {
f0eefdc3 2598 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
02f1175c
JS
2599
2600 if (set & TIOCM_RTS) {
9fa1b3b1 2601 spin_lock_irqsave(&card->card_lock, flags);
f0eefdc3
JS
2602 cy_writel(&ch_ctrl->rs_control,
2603 readl(&ch_ctrl->rs_control) | C_RS_RTS);
9fa1b3b1 2604 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2605 }
2606 if (clear & TIOCM_RTS) {
9fa1b3b1 2607 spin_lock_irqsave(&card->card_lock, flags);
f0eefdc3
JS
2608 cy_writel(&ch_ctrl->rs_control,
2609 readl(&ch_ctrl->rs_control) &
db05c3b1 2610 ~C_RS_RTS);
9fa1b3b1 2611 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2612 }
2613 if (set & TIOCM_DTR) {
9fa1b3b1 2614 spin_lock_irqsave(&card->card_lock, flags);
f0eefdc3
JS
2615 cy_writel(&ch_ctrl->rs_control,
2616 readl(&ch_ctrl->rs_control) | C_RS_DTR);
1da177e4 2617#ifdef CY_DEBUG_DTR
21719191
JS
2618 printk(KERN_DEBUG "cyc:set_modem_info raising "
2619 "Z DTR\n");
1da177e4 2620#endif
9fa1b3b1 2621 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2622 }
2623 if (clear & TIOCM_DTR) {
9fa1b3b1 2624 spin_lock_irqsave(&card->card_lock, flags);
f0eefdc3
JS
2625 cy_writel(&ch_ctrl->rs_control,
2626 readl(&ch_ctrl->rs_control) &
db05c3b1 2627 ~C_RS_DTR);
1da177e4 2628#ifdef CY_DEBUG_DTR
21719191
JS
2629 printk(KERN_DEBUG "cyc:set_modem_info clearing "
2630 "Z DTR\n");
1da177e4 2631#endif
9fa1b3b1 2632 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2633 }
2634 } else {
2635 return -ENODEV;
2636 }
9fa1b3b1
JS
2637 spin_lock_irqsave(&card->card_lock, flags);
2638 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
02f1175c 2639 if (retval != 0) {
21719191
JS
2640 printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
2641 "was %x\n", info->line, retval);
02f1175c 2642 }
9fa1b3b1 2643 spin_unlock_irqrestore(&card->card_lock, flags);
1da177e4 2644 }
02f1175c
JS
2645 return 0;
2646} /* cy_tiocmset */
1da177e4
LT
2647
2648/*
2649 * cy_break() --- routine which turns the break handling on or off
2650 */
9e98966c 2651static int cy_break(struct tty_struct *tty, int break_state)
1da177e4 2652{
cab9bdd1 2653 struct cyclades_port *info = tty->driver_data;
9fa1b3b1 2654 struct cyclades_card *card;
02f1175c 2655 unsigned long flags;
9e98966c 2656 int retval = 0;
1da177e4 2657
02f1175c 2658 if (serial_paranoia_check(info, tty->name, "cy_break"))
9e98966c 2659 return -EINVAL;
1da177e4 2660
9fa1b3b1
JS
2661 card = info->card;
2662
2663 spin_lock_irqsave(&card->card_lock, flags);
2693f485 2664 if (!cy_is_Z(card)) {
02f1175c
JS
2665 /* Let the transmit ISR take care of this (since it
2666 requires stuffing characters into the output stream).
2667 */
2668 if (break_state == -1) {
2669 if (!info->breakon) {
2670 info->breakon = 1;
2671 if (!info->xmit_cnt) {
9fa1b3b1 2672 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2673 start_xmit(info);
9fa1b3b1 2674 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2675 }
2676 }
2677 } else {
2678 if (!info->breakoff) {
2679 info->breakoff = 1;
2680 if (!info->xmit_cnt) {
9fa1b3b1 2681 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c 2682 start_xmit(info);
9fa1b3b1 2683 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2684 }
2685 }
1da177e4 2686 }
1da177e4 2687 } else {
02f1175c 2688 if (break_state == -1) {
9fa1b3b1
JS
2689 retval = cyz_issue_cmd(card,
2690 info->line - card->first_line,
02f1175c
JS
2691 C_CM_SET_BREAK, 0L);
2692 if (retval != 0) {
21719191
JS
2693 printk(KERN_ERR "cyc:cy_break (set) retval on "
2694 "ttyC%d was %x\n", info->line, retval);
02f1175c
JS
2695 }
2696 } else {
9fa1b3b1
JS
2697 retval = cyz_issue_cmd(card,
2698 info->line - card->first_line,
02f1175c
JS
2699 C_CM_CLR_BREAK, 0L);
2700 if (retval != 0) {
21719191
JS
2701 printk(KERN_DEBUG "cyc:cy_break (clr) retval "
2702 "on ttyC%d was %x\n", info->line,
2703 retval);
02f1175c 2704 }
1da177e4 2705 }
1da177e4 2706 }
9fa1b3b1 2707 spin_unlock_irqrestore(&card->card_lock, flags);
9e98966c 2708 return retval;
02f1175c 2709} /* cy_break */
1da177e4 2710
02f1175c 2711static int set_threshold(struct cyclades_port *info, unsigned long value)
1da177e4 2712{
875b206b 2713 struct cyclades_card *card;
02f1175c 2714 void __iomem *base_addr;
875b206b 2715 int channel, chip, index;
02f1175c 2716 unsigned long flags;
1da177e4 2717
02f1175c 2718 card = info->card;
875b206b 2719 channel = info->line - card->first_line;
2693f485 2720 if (!cy_is_Z(card)) {
02f1175c
JS
2721 chip = channel >> 2;
2722 channel &= 0x03;
875b206b 2723 index = card->bus_index;
02f1175c 2724 base_addr =
875b206b 2725 card->base_addr + (cy_chip_offset[chip] << index);
02f1175c
JS
2726
2727 info->cor3 &= ~CyREC_FIFO;
2728 info->cor3 |= value & CyREC_FIFO;
1da177e4 2729
9fa1b3b1 2730 spin_lock_irqsave(&card->card_lock, flags);
02f1175c
JS
2731 cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
2732 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
9fa1b3b1 2733 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2734 }
2735 return 0;
2736} /* set_threshold */
1da177e4 2737
15ed6cc0
AC
2738static int get_threshold(struct cyclades_port *info,
2739 unsigned long __user *value)
1da177e4 2740{
875b206b 2741 struct cyclades_card *card;
02f1175c 2742 void __iomem *base_addr;
875b206b 2743 int channel, chip, index;
02f1175c 2744 unsigned long tmp;
1da177e4 2745
02f1175c 2746 card = info->card;
875b206b 2747 channel = info->line - card->first_line;
2693f485 2748 if (!cy_is_Z(card)) {
02f1175c
JS
2749 chip = channel >> 2;
2750 channel &= 0x03;
875b206b
JS
2751 index = card->bus_index;
2752 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 2753
db05c3b1 2754 tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
02f1175c 2755 return put_user(tmp, value);
02f1175c 2756 }
f7429034 2757 return 0;
02f1175c 2758} /* get_threshold */
1da177e4 2759
02f1175c 2760static int set_timeout(struct cyclades_port *info, unsigned long value)
1da177e4 2761{
875b206b 2762 struct cyclades_card *card;
02f1175c 2763 void __iomem *base_addr;
875b206b 2764 int channel, chip, index;
02f1175c 2765 unsigned long flags;
1da177e4 2766
02f1175c 2767 card = info->card;
875b206b 2768 channel = info->line - card->first_line;
2693f485 2769 if (!cy_is_Z(card)) {
02f1175c
JS
2770 chip = channel >> 2;
2771 channel &= 0x03;
875b206b
JS
2772 index = card->bus_index;
2773 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
1da177e4 2774
9fa1b3b1 2775 spin_lock_irqsave(&card->card_lock, flags);
02f1175c 2776 cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
9fa1b3b1 2777 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
2778 }
2779 return 0;
2780} /* set_timeout */
1da177e4 2781
15ed6cc0
AC
2782static int get_timeout(struct cyclades_port *info,
2783 unsigned long __user *value)
1da177e4 2784{
875b206b 2785 struct cyclades_card *card;
02f1175c 2786 void __iomem *base_addr;
875b206b 2787 int channel, chip, index;
02f1175c 2788 unsigned long tmp;
1da177e4 2789
02f1175c 2790 card = info->card;
875b206b 2791 channel = info->line - card->first_line;
2693f485 2792 if (!cy_is_Z(card)) {
02f1175c
JS
2793 chip = channel >> 2;
2794 channel &= 0x03;
875b206b
JS
2795 index = card->bus_index;
2796 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
02f1175c 2797
db05c3b1 2798 tmp = readb(base_addr + (CyRTPR << index));
02f1175c 2799 return put_user(tmp, value);
02f1175c 2800 }
f7429034 2801 return 0;
02f1175c 2802} /* get_timeout */
1da177e4 2803
6c28181c
JS
2804static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg,
2805 struct cyclades_icount *cprev)
1da177e4 2806{
6c28181c
JS
2807 struct cyclades_icount cnow;
2808 unsigned long flags;
2809 int ret;
1da177e4 2810
6c28181c
JS
2811 spin_lock_irqsave(&info->card->card_lock, flags);
2812 cnow = info->icount; /* atomic copy */
2813 spin_unlock_irqrestore(&info->card->card_lock, flags);
2814
2815 ret = ((arg & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
2816 ((arg & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
2817 ((arg & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
2818 ((arg & TIOCM_CTS) && (cnow.cts != cprev->cts));
2819
2820 *cprev = cnow;
2821
2822 return ret;
2823}
1da177e4
LT
2824
2825/*
2826 * This routine allows the tty driver to implement device-
2827 * specific ioctl's. If the ioctl number passed in cmd is
2828 * not recognized by the driver, it should return ENOIOCTLCMD.
2829 */
2830static int
02f1175c
JS
2831cy_ioctl(struct tty_struct *tty, struct file *file,
2832 unsigned int cmd, unsigned long arg)
1da177e4 2833{
cab9bdd1 2834 struct cyclades_port *info = tty->driver_data;
6c28181c 2835 struct cyclades_icount cnow; /* kernel counter temps */
02f1175c
JS
2836 int ret_val = 0;
2837 unsigned long flags;
2838 void __user *argp = (void __user *)arg;
2839
2840 if (serial_paranoia_check(info, tty->name, "cy_ioctl"))
2841 return -ENODEV;
1da177e4
LT
2842
2843#ifdef CY_DEBUG_OTHER
21719191
JS
2844 printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
2845 info->line, cmd, arg);
1da177e4 2846#endif
7b130c0e 2847 lock_kernel();
1da177e4 2848
02f1175c
JS
2849 switch (cmd) {
2850 case CYGETMON:
6c28181c
JS
2851 if (copy_to_user(argp, &info->mon, sizeof(info->mon))) {
2852 ret_val = -EFAULT;
2853 break;
2854 }
2855 memset(&info->mon, 0, sizeof(info->mon));
02f1175c
JS
2856 break;
2857 case CYGETTHRESH:
2858 ret_val = get_threshold(info, argp);
2859 break;
2860 case CYSETTHRESH:
2861 ret_val = set_threshold(info, arg);
2862 break;
2863 case CYGETDEFTHRESH:
6c28181c
JS
2864 ret_val = put_user(info->default_threshold,
2865 (unsigned long __user *)argp);
02f1175c
JS
2866 break;
2867 case CYSETDEFTHRESH:
6c28181c 2868 info->default_threshold = arg & 0x0f;
02f1175c
JS
2869 break;
2870 case CYGETTIMEOUT:
2871 ret_val = get_timeout(info, argp);
2872 break;
2873 case CYSETTIMEOUT:
2874 ret_val = set_timeout(info, arg);
2875 break;
2876 case CYGETDEFTIMEOUT:
6c28181c
JS
2877 ret_val = put_user(info->default_timeout,
2878 (unsigned long __user *)argp);
02f1175c
JS
2879 break;
2880 case CYSETDEFTIMEOUT:
6c28181c 2881 info->default_timeout = arg & 0xff;
02f1175c 2882 break;
1da177e4 2883 case CYSETRFLOW:
02f1175c 2884 info->rflow = (int)arg;
02f1175c 2885 break;
1da177e4 2886 case CYGETRFLOW:
02f1175c
JS
2887 ret_val = info->rflow;
2888 break;
1da177e4 2889 case CYSETRTSDTR_INV:
02f1175c 2890 info->rtsdtr_inv = (int)arg;
02f1175c 2891 break;
1da177e4 2892 case CYGETRTSDTR_INV:
02f1175c
JS
2893 ret_val = info->rtsdtr_inv;
2894 break;
1da177e4 2895 case CYGETCD1400VER:
02f1175c
JS
2896 ret_val = info->chip_rev;
2897 break;
1da177e4
LT
2898#ifndef CONFIG_CYZ_INTR
2899 case CYZSETPOLLCYCLE:
02f1175c 2900 cyz_polling_cycle = (arg * HZ) / 1000;
02f1175c 2901 break;
1da177e4 2902 case CYZGETPOLLCYCLE:
02f1175c
JS
2903 ret_val = (cyz_polling_cycle * 1000) / HZ;
2904 break;
2905#endif /* CONFIG_CYZ_INTR */
1da177e4 2906 case CYSETWAIT:
44b7d1b3 2907 info->port.closing_wait = (unsigned short)arg * HZ / 100;
02f1175c 2908 break;
1da177e4 2909 case CYGETWAIT:
44b7d1b3 2910 ret_val = info->port.closing_wait / (HZ / 100);
02f1175c
JS
2911 break;
2912 case TIOCGSERIAL:
6c28181c 2913 ret_val = cy_get_serial_info(info, argp);
02f1175c
JS
2914 break;
2915 case TIOCSSERIAL:
d13549f8 2916 ret_val = cy_set_serial_info(info, tty, argp);
02f1175c
JS
2917 break;
2918 case TIOCSERGETLSR: /* Get line status register */
2919 ret_val = get_lsr_info(info, argp);
2920 break;
2921 /*
2922 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
2923 * - mask passed in arg for lines of interest
2924 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
2925 * Caller should use TIOCGICOUNT to see which one it was
2926 */
1da177e4 2927 case TIOCMIWAIT:
9fa1b3b1 2928 spin_lock_irqsave(&info->card->card_lock, flags);
02f1175c 2929 /* note the counters on entry */
2c7fea99 2930 cnow = info->icount;
9fa1b3b1 2931 spin_unlock_irqrestore(&info->card->card_lock, flags);
6c28181c
JS
2932 ret_val = wait_event_interruptible(info->delta_msr_wait,
2933 cy_cflags_changed(info, arg, &cnow));
2c7fea99 2934 break;
1da177e4 2935
02f1175c
JS
2936 /*
2937 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2938 * Return: write counters to the user passed counter struct
2939 * NB: both 1->0 and 0->1 transitions are counted except for
2940 * RI where only 0->1 is counted.
2941 */
6c28181c
JS
2942 case TIOCGICOUNT: {
2943 struct serial_icounter_struct sic = { };
2944
9fa1b3b1 2945 spin_lock_irqsave(&info->card->card_lock, flags);
02f1175c 2946 cnow = info->icount;
9fa1b3b1 2947 spin_unlock_irqrestore(&info->card->card_lock, flags);
6c28181c
JS
2948
2949 sic.cts = cnow.cts;
2950 sic.dsr = cnow.dsr;
2951 sic.rng = cnow.rng;
2952 sic.dcd = cnow.dcd;
2953 sic.rx = cnow.rx;
2954 sic.tx = cnow.tx;
2955 sic.frame = cnow.frame;
2956 sic.overrun = cnow.overrun;
2957 sic.parity = cnow.parity;
2958 sic.brk = cnow.brk;
2959 sic.buf_overrun = cnow.buf_overrun;
2960
2961 if (copy_to_user(argp, &sic, sizeof(sic)))
2962 ret_val = -EFAULT;
02f1175c 2963 break;
6c28181c 2964 }
02f1175c
JS
2965 default:
2966 ret_val = -ENOIOCTLCMD;
2967 }
7b130c0e 2968 unlock_kernel();
1da177e4
LT
2969
2970#ifdef CY_DEBUG_OTHER
21719191 2971 printk(KERN_DEBUG "cyc:cy_ioctl done\n");
1da177e4 2972#endif
02f1175c
JS
2973 return ret_val;
2974} /* cy_ioctl */
1da177e4
LT
2975
2976/*
2977 * This routine allows the tty driver to be notified when
2978 * device's termios settings have changed. Note that a
2979 * well-designed tty driver should be prepared to accept the case
2980 * where old == NULL, and try to do something rational.
2981 */
02f1175c 2982static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
1da177e4 2983{
cab9bdd1 2984 struct cyclades_port *info = tty->driver_data;
1da177e4
LT
2985
2986#ifdef CY_DEBUG_OTHER
21719191 2987 printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
1da177e4
LT
2988#endif
2989
d13549f8 2990 cy_set_line_char(info, tty);
02f1175c
JS
2991
2992 if ((old_termios->c_cflag & CRTSCTS) &&
2993 !(tty->termios->c_cflag & CRTSCTS)) {
2994 tty->hw_stopped = 0;
2995 cy_start(tty);
2996 }
1da177e4 2997#if 0
02f1175c
JS
2998 /*
2999 * No need to wake up processes in open wait, since they
3000 * sample the CLOCAL flag once, and don't recheck it.
3001 * XXX It's not clear whether the current behavior is correct
3002 * or not. Hence, this may change.....
3003 */
3004 if (!(old_termios->c_cflag & CLOCAL) &&
3005 (tty->termios->c_cflag & CLOCAL))
77451e53 3006 wake_up_interruptible(&info->port.open_wait);
1da177e4 3007#endif
02f1175c 3008} /* cy_set_termios */
1da177e4
LT
3009
3010/* This function is used to send a high-priority XON/XOFF character to
3011 the device.
3012*/
02f1175c 3013static void cy_send_xchar(struct tty_struct *tty, char ch)
1da177e4 3014{
cab9bdd1 3015 struct cyclades_port *info = tty->driver_data;
875b206b
JS
3016 struct cyclades_card *card;
3017 int channel;
1da177e4 3018
02f1175c 3019 if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
1da177e4
LT
3020 return;
3021
02f1175c 3022 info->x_char = ch;
1da177e4
LT
3023
3024 if (ch)
02f1175c 3025 cy_start(tty);
1da177e4
LT
3026
3027 card = info->card;
875b206b 3028 channel = info->line - card->first_line;
1da177e4 3029
2693f485 3030 if (cy_is_Z(card)) {
02f1175c 3031 if (ch == STOP_CHAR(tty))
875b206b 3032 cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
02f1175c 3033 else if (ch == START_CHAR(tty))
875b206b 3034 cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L);
1da177e4
LT
3035 }
3036}
3037
3038/* This routine is called by the upper-layer tty layer to signal
3039 that incoming characters should be throttled because the input
3040 buffers are close to full.
3041 */
02f1175c 3042static void cy_throttle(struct tty_struct *tty)
1da177e4 3043{
cab9bdd1 3044 struct cyclades_port *info = tty->driver_data;
875b206b 3045 struct cyclades_card *card;
02f1175c 3046 unsigned long flags;
1da177e4
LT
3047
3048#ifdef CY_DEBUG_THROTTLE
02f1175c 3049 char buf[64];
1da177e4 3050
21719191 3051 printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf),
02f1175c 3052 tty->ldisc.chars_in_buffer(tty), info->line);
1da177e4
LT
3053#endif
3054
15ed6cc0 3055 if (serial_paranoia_check(info, tty->name, "cy_throttle"))
02f1175c 3056 return;
02f1175c
JS
3057
3058 card = info->card;
3059
3060 if (I_IXOFF(tty)) {
2693f485 3061 if (!cy_is_Z(card))
02f1175c
JS
3062 cy_send_xchar(tty, STOP_CHAR(tty));
3063 else
3064 info->throttle = 1;
3065 }
1da177e4 3066
02f1175c 3067 if (tty->termios->c_cflag & CRTSCTS) {
2693f485 3068 if (!cy_is_Z(card)) {
9fa1b3b1 3069 spin_lock_irqsave(&card->card_lock, flags);
4d768200 3070 cyy_change_rts_dtr(info, 0, TIOCM_RTS);
9fa1b3b1 3071 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
3072 } else {
3073 info->throttle = 1;
3074 }
3075 }
02f1175c 3076} /* cy_throttle */
1da177e4
LT
3077
3078/*
3079 * This routine notifies the tty driver that it should signal
3080 * that characters can now be sent to the tty without fear of
3081 * overrunning the input buffers of the line disciplines.
3082 */
02f1175c 3083static void cy_unthrottle(struct tty_struct *tty)
1da177e4 3084{
cab9bdd1 3085 struct cyclades_port *info = tty->driver_data;
875b206b 3086 struct cyclades_card *card;
02f1175c 3087 unsigned long flags;
1da177e4
LT
3088
3089#ifdef CY_DEBUG_THROTTLE
02f1175c
JS
3090 char buf[64];
3091
21719191 3092 printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
15ed6cc0 3093 tty_name(tty, buf), tty_chars_in_buffer(tty), info->line);
1da177e4
LT
3094#endif
3095
15ed6cc0 3096 if (serial_paranoia_check(info, tty->name, "cy_unthrottle"))
02f1175c 3097 return;
1da177e4 3098
02f1175c
JS
3099 if (I_IXOFF(tty)) {
3100 if (info->x_char)
3101 info->x_char = 0;
3102 else
3103 cy_send_xchar(tty, START_CHAR(tty));
1da177e4 3104 }
1da177e4 3105
02f1175c
JS
3106 if (tty->termios->c_cflag & CRTSCTS) {
3107 card = info->card;
2693f485 3108 if (!cy_is_Z(card)) {
9fa1b3b1 3109 spin_lock_irqsave(&card->card_lock, flags);
4d768200 3110 cyy_change_rts_dtr(info, TIOCM_RTS, 0);
9fa1b3b1 3111 spin_unlock_irqrestore(&card->card_lock, flags);
02f1175c
JS
3112 } else {
3113 info->throttle = 0;
3114 }
3115 }
02f1175c 3116} /* cy_unthrottle */
1da177e4
LT
3117
3118/* cy_start and cy_stop provide software output flow control as a
3119 function of XON/XOFF, software CTS, and other such stuff.
3120*/
02f1175c 3121static void cy_stop(struct tty_struct *tty)
1da177e4 3122{
02f1175c 3123 struct cyclades_card *cinfo;
cab9bdd1 3124 struct cyclades_port *info = tty->driver_data;
02f1175c
JS
3125 void __iomem *base_addr;
3126 int chip, channel, index;
3127 unsigned long flags;
1da177e4
LT
3128
3129#ifdef CY_DEBUG_OTHER
21719191 3130 printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line);
1da177e4
LT
3131#endif
3132
02f1175c
JS
3133 if (serial_paranoia_check(info, tty->name, "cy_stop"))
3134 return;
1da177e4 3135
875b206b 3136 cinfo = info->card;
02f1175c 3137 channel = info->line - cinfo->first_line;
2693f485 3138 if (!cy_is_Z(cinfo)) {
02f1175c
JS
3139 index = cinfo->bus_index;
3140 chip = channel >> 2;
3141 channel &= 0x03;
9fa1b3b1 3142 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
1da177e4 3143
9fa1b3b1 3144 spin_lock_irqsave(&cinfo->card_lock, flags);
02f1175c
JS
3145 cy_writeb(base_addr + (CyCAR << index),
3146 (u_char)(channel & 0x0003)); /* index channel */
3147 cy_writeb(base_addr + (CySRER << index),
db05c3b1 3148 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
9fa1b3b1 3149 spin_unlock_irqrestore(&cinfo->card_lock, flags);
02f1175c 3150 }
02f1175c 3151} /* cy_stop */
1da177e4 3152
02f1175c 3153static void cy_start(struct tty_struct *tty)
1da177e4 3154{
02f1175c 3155 struct cyclades_card *cinfo;
cab9bdd1 3156 struct cyclades_port *info = tty->driver_data;
02f1175c
JS
3157 void __iomem *base_addr;
3158 int chip, channel, index;
3159 unsigned long flags;
1da177e4
LT
3160
3161#ifdef CY_DEBUG_OTHER
21719191 3162 printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line);
1da177e4
LT
3163#endif
3164
02f1175c
JS
3165 if (serial_paranoia_check(info, tty->name, "cy_start"))
3166 return;
1da177e4 3167
875b206b 3168 cinfo = info->card;
02f1175c
JS
3169 channel = info->line - cinfo->first_line;
3170 index = cinfo->bus_index;
2693f485 3171 if (!cy_is_Z(cinfo)) {
02f1175c
JS
3172 chip = channel >> 2;
3173 channel &= 0x03;
9fa1b3b1 3174 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
1da177e4 3175
9fa1b3b1 3176 spin_lock_irqsave(&cinfo->card_lock, flags);
15ed6cc0
AC
3177 cy_writeb(base_addr + (CyCAR << index),
3178 (u_char) (channel & 0x0003)); /* index channel */
02f1175c 3179 cy_writeb(base_addr + (CySRER << index),
db05c3b1 3180 readb(base_addr + (CySRER << index)) | CyTxRdy);
9fa1b3b1 3181 spin_unlock_irqrestore(&cinfo->card_lock, flags);
02f1175c 3182 }
02f1175c 3183} /* cy_start */
1da177e4 3184
1da177e4
LT
3185/*
3186 * cy_hangup() --- called by tty_hangup() when a hangup is signaled.
3187 */
02f1175c 3188static void cy_hangup(struct tty_struct *tty)
1da177e4 3189{
cab9bdd1 3190 struct cyclades_port *info = tty->driver_data;
02f1175c 3191
1da177e4 3192#ifdef CY_DEBUG_OTHER
21719191 3193 printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line);
1da177e4
LT
3194#endif
3195
02f1175c
JS
3196 if (serial_paranoia_check(info, tty->name, "cy_hangup"))
3197 return;
1da177e4 3198
02f1175c 3199 cy_flush_buffer(tty);
d13549f8 3200 cy_shutdown(info, tty);
174e6fe0 3201 tty_port_hangup(&info->port);
02f1175c 3202} /* cy_hangup */
1da177e4 3203
f0737579
JS
3204static int cyy_carrier_raised(struct tty_port *port)
3205{
3206 struct cyclades_port *info = container_of(port, struct cyclades_port,
3207 port);
3208 struct cyclades_card *cinfo = info->card;
3209 void __iomem *base = cinfo->base_addr;
3210 unsigned long flags;
3211 int channel = info->line - cinfo->first_line;
3212 int chip = channel >> 2, index = cinfo->bus_index;
3213 u32 cd;
3214
3215 channel &= 0x03;
3216 base += cy_chip_offset[chip] << index;
3217
3218 spin_lock_irqsave(&cinfo->card_lock, flags);
3219 cy_writeb(base + (CyCAR << index), (u8)channel);
3220 cd = readb(base + (CyMSVR1 << index)) & CyDCD;
3221 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3222
3223 return cd;
3224}
3225
3226static void cyy_dtr_rts(struct tty_port *port, int raise)
3227{
3228 struct cyclades_port *info = container_of(port, struct cyclades_port,
3229 port);
3230 struct cyclades_card *cinfo = info->card;
f0737579 3231 unsigned long flags;
f0737579
JS
3232
3233 spin_lock_irqsave(&cinfo->card_lock, flags);
4d768200
JS
3234 cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0,
3235 raise ? 0 : TIOCM_RTS | TIOCM_DTR);
f0737579
JS
3236 spin_unlock_irqrestore(&cinfo->card_lock, flags);
3237}
3238
3239static int cyz_carrier_raised(struct tty_port *port)
3240{
3241 struct cyclades_port *info = container_of(port, struct cyclades_port,
3242 port);
f0737579 3243
f0eefdc3 3244 return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD;
f0737579
JS
3245}
3246
3247static void cyz_dtr_rts(struct tty_port *port, int raise)
3248{
3249 struct cyclades_port *info = container_of(port, struct cyclades_port,
3250 port);
3251 struct cyclades_card *cinfo = info->card;
f0eefdc3 3252 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
f0737579
JS
3253 int ret, channel = info->line - cinfo->first_line;
3254 u32 rs;
3255
f0eefdc3 3256 rs = readl(&ch_ctrl->rs_control);
f0737579
JS
3257 if (raise)
3258 rs |= C_RS_RTS | C_RS_DTR;
3259 else
3260 rs &= ~(C_RS_RTS | C_RS_DTR);
f0eefdc3 3261 cy_writel(&ch_ctrl->rs_control, rs);
f0737579
JS
3262 ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L);
3263 if (ret != 0)
3264 printk(KERN_ERR "%s: retval on ttyC%d was %x\n",
3265 __func__, info->line, ret);
3266#ifdef CY_DEBUG_DTR
3267 printk(KERN_DEBUG "%s: raising Z DTR\n", __func__);
3268#endif
3269}
3270
3271static const struct tty_port_operations cyy_port_ops = {
3272 .carrier_raised = cyy_carrier_raised,
3273 .dtr_rts = cyy_dtr_rts,
3274};
3275
3276static const struct tty_port_operations cyz_port_ops = {
3277 .carrier_raised = cyz_carrier_raised,
3278 .dtr_rts = cyz_dtr_rts,
3279};
3280
1da177e4
LT
3281/*
3282 * ---------------------------------------------------------------------
3283 * cy_init() and friends
3284 *
3285 * cy_init() is called at boot-time to initialize the serial driver.
3286 * ---------------------------------------------------------------------
3287 */
3288
dd025c0c 3289static int __devinit cy_init_card(struct cyclades_card *cinfo)
0809e267
JS
3290{
3291 struct cyclades_port *info;
f0eefdc3 3292 unsigned int channel, port;
0809e267 3293
3046d50e 3294 spin_lock_init(&cinfo->card_lock);
963118ee 3295 cinfo->intr_enabled = 0;
3046d50e 3296
963118ee
JS
3297 cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports),
3298 GFP_KERNEL);
dd025c0c
JS
3299 if (cinfo->ports == NULL) {
3300 printk(KERN_ERR "Cyclades: cannot allocate ports\n");
3301 return -ENOMEM;
3302 }
3303
f0eefdc3
JS
3304 for (channel = 0, port = cinfo->first_line; channel < cinfo->nports;
3305 channel++, port++) {
3306 info = &cinfo->ports[channel];
44b7d1b3 3307 tty_port_init(&info->port);
3046d50e 3308 info->magic = CYCLADES_MAGIC;
875b206b 3309 info->card = cinfo;
3046d50e 3310 info->line = port;
3046d50e 3311
44b7d1b3
AC
3312 info->port.closing_wait = CLOSING_WAIT_DELAY;
3313 info->port.close_delay = 5 * HZ / 10;
77451e53 3314 info->port.flags = STD_COM_FLAGS;
2c7fea99 3315 init_completion(&info->shutdown_wait);
3046d50e
JS
3316 init_waitqueue_head(&info->delta_msr_wait);
3317
2693f485 3318 if (cy_is_Z(cinfo)) {
f0eefdc3
JS
3319 struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS;
3320 struct ZFW_CTRL *zfw_ctrl;
3321
f0737579 3322 info->port.ops = &cyz_port_ops;
0809e267 3323 info->type = PORT_STARTECH;
f0eefdc3
JS
3324
3325 zfw_ctrl = cinfo->base_addr +
3326 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3327 info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel];
3328 info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3329
101b8159 3330 if (cinfo->hw_ver == ZO_V1)
0809e267
JS
3331 info->xmit_fifo_size = CYZ_FIFO_SIZE;
3332 else
3046d50e 3333 info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
0809e267 3334#ifdef CONFIG_CYZ_INTR
3991428d
JS
3335 setup_timer(&cyz_rx_full_timer[port],
3336 cyz_rx_restart, (unsigned long)info);
0809e267 3337#endif
3046d50e 3338 } else {
f0eefdc3 3339 unsigned short chip_number;
963118ee 3340 int index = cinfo->bus_index;
f0eefdc3 3341
f0737579 3342 info->port.ops = &cyy_port_ops;
0809e267 3343 info->type = PORT_CIRRUS;
0809e267 3344 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
3046d50e 3345 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
0809e267
JS
3346 info->cor2 = CyETC;
3347 info->cor3 = 0x08; /* _very_ small rcv threshold */
3046d50e 3348
f0eefdc3 3349 chip_number = channel / CyPORTS_PER_CHIP;
15ed6cc0
AC
3350 info->chip_rev = readb(cinfo->base_addr +
3351 (cy_chip_offset[chip_number] << index) +
3352 (CyGFRCR << index));
3353
3354 if (info->chip_rev >= CD1400_REV_J) {
0809e267
JS
3355 /* It is a CD1400 rev. J or later */
3356 info->tbpr = baud_bpr_60[13]; /* Tx BPR */
3357 info->tco = baud_co_60[13]; /* Tx CO */
3358 info->rbpr = baud_bpr_60[13]; /* Rx BPR */
3359 info->rco = baud_co_60[13]; /* Rx CO */
0809e267
JS
3360 info->rtsdtr_inv = 1;
3361 } else {
3362 info->tbpr = baud_bpr_25[13]; /* Tx BPR */
3363 info->tco = baud_co_25[13]; /* Tx CO */
3364 info->rbpr = baud_bpr_25[13]; /* Rx BPR */
3365 info->rco = baud_co_25[13]; /* Rx CO */
0809e267
JS
3366 info->rtsdtr_inv = 0;
3367 }
3046d50e
JS
3368 info->read_status_mask = CyTIMEOUT | CySPECHAR |
3369 CyBREAK | CyPARITY | CyFRAME | CyOVERRUN;
0809e267 3370 }
3046d50e 3371
0809e267 3372 }
3046d50e
JS
3373
3374#ifndef CONFIG_CYZ_INTR
2693f485 3375 if (cy_is_Z(cinfo) && !timer_pending(&cyz_timerlist)) {
3046d50e
JS
3376 mod_timer(&cyz_timerlist, jiffies + 1);
3377#ifdef CY_PCI_DEBUG
3378 printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
3379#endif
3380 }
3381#endif
dd025c0c 3382 return 0;
0809e267
JS
3383}
3384
1da177e4
LT
3385/* initialize chips on Cyclom-Y card -- return number of valid
3386 chips (which is number of ports/4) */
31b4f0a1
JS
3387static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
3388 int index)
1da177e4 3389{
02f1175c
JS
3390 unsigned int chip_number;
3391 void __iomem *base_addr;
3392
3393 cy_writeb(true_base_addr + (Cy_HwReset << index), 0);
3394 /* Cy_HwReset is 0x1400 */
3395 cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0);
3396 /* Cy_ClrIntr is 0x1800 */
3397 udelay(500L);
3398
15ed6cc0
AC
3399 for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD;
3400 chip_number++) {
02f1175c
JS
3401 base_addr =
3402 true_base_addr + (cy_chip_offset[chip_number] << index);
3403 mdelay(1);
db05c3b1 3404 if (readb(base_addr + (CyCCR << index)) != 0x00) {
02f1175c
JS
3405 /*************
3406 printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
3407 chip_number, (unsigned long)base_addr);
3408 *************/
3409 return chip_number;
3410 }
3411
3412 cy_writeb(base_addr + (CyGFRCR << index), 0);
3413 udelay(10L);
3414
3415 /* The Cyclom-16Y does not decode address bit 9 and therefore
3416 cannot distinguish between references to chip 0 and a non-
3417 existent chip 4. If the preceding clearing of the supposed
3418 chip 4 GFRCR register appears at chip 0, there is no chip 4
3419 and this must be a Cyclom-16Y, not a Cyclom-32Ye.
3420 */
db05c3b1 3421 if (chip_number == 4 && readb(true_base_addr +
02f1175c
JS
3422 (cy_chip_offset[0] << index) +
3423 (CyGFRCR << index)) == 0) {
3424 return chip_number;
3425 }
3426
3427 cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
3428 mdelay(1);
3429
db05c3b1 3430 if (readb(base_addr + (CyGFRCR << index)) == 0x00) {
02f1175c
JS
3431 /*
3432 printk(" chip #%d at %#6lx is not responding ",
3433 chip_number, (unsigned long)base_addr);
3434 printk("(GFRCR stayed 0)\n",
3435 */
3436 return chip_number;
3437 }
db05c3b1 3438 if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) !=
02f1175c
JS
3439 0x40) {
3440 /*
3441 printk(" chip #%d at %#6lx is not valid (GFRCR == "
3442 "%#2x)\n",
3443 chip_number, (unsigned long)base_addr,
3444 base_addr[CyGFRCR<<index]);
3445 */
3446 return chip_number;
3447 }
3448 cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
db05c3b1 3449 if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
02f1175c
JS
3450 /* It is a CD1400 rev. J or later */
3451 /* Impossible to reach 5ms with this chip.
3452 Changed to 2ms instead (f = 500 Hz). */
3453 cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS);
3454 } else {
3455 /* f = 200 Hz */
3456 cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS);
3457 }
1da177e4 3458
02f1175c
JS
3459 /*
3460 printk(" chip #%d at %#6lx is rev 0x%2x\n",
3461 chip_number, (unsigned long)base_addr,
db05c3b1 3462 readb(base_addr+(CyGFRCR<<index)));
02f1175c
JS
3463 */
3464 }
3465 return chip_number;
3466} /* cyy_init_card */
1da177e4
LT
3467
3468/*
3469 * ---------------------------------------------------------------------
3470 * cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
3471 * sets global variables and return the number of ISA boards found.
3472 * ---------------------------------------------------------------------
3473 */
02f1175c 3474static int __init cy_detect_isa(void)
1da177e4
LT
3475{
3476#ifdef CONFIG_ISA
02f1175c
JS
3477 unsigned short cy_isa_irq, nboard;
3478 void __iomem *cy_isa_address;
3479 unsigned short i, j, cy_isa_nchan;
1da177e4 3480#ifdef MODULE
02f1175c 3481 int isparam = 0;
1da177e4
LT
3482#endif
3483
02f1175c 3484 nboard = 0;
1da177e4
LT
3485
3486#ifdef MODULE
3487 /* Check for module parameters */
02f1175c
JS
3488 for (i = 0; i < NR_CARDS; i++) {
3489 if (maddr[i] || i) {
3490 isparam = 1;
3491 cy_isa_addresses[i] = maddr[i];
3492 }
3493 if (!maddr[i])
3494 break;
1da177e4
LT
3495 }
3496#endif
3497
02f1175c
JS
3498 /* scan the address table probing for Cyclom-Y/ISA boards */
3499 for (i = 0; i < NR_ISA_ADDRS; i++) {
3500 unsigned int isa_address = cy_isa_addresses[i];
15ed6cc0 3501 if (isa_address == 0x0000)
096dcfce 3502 return nboard;
1da177e4 3503
02f1175c 3504 /* probe for CD1400... */
cd989b3a 3505 cy_isa_address = ioremap_nocache(isa_address, CyISA_Ywin);
3137553d
JS
3506 if (cy_isa_address == NULL) {
3507 printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
3508 "address\n");
3509 continue;
3510 }
02f1175c
JS
3511 cy_isa_nchan = CyPORTS_PER_CHIP *
3512 cyy_init_card(cy_isa_address, 0);
3513 if (cy_isa_nchan == 0) {
3137553d 3514 iounmap(cy_isa_address);
02f1175c
JS
3515 continue;
3516 }
1da177e4
LT
3517#ifdef MODULE
3518 if (isparam && irq[i])
02f1175c 3519 cy_isa_irq = irq[i];
1da177e4
LT
3520 else
3521#endif
02f1175c
JS
3522 /* find out the board's irq by probing */
3523 cy_isa_irq = detect_isa_irq(cy_isa_address);
3524 if (cy_isa_irq == 0) {
21719191
JS
3525 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the "
3526 "IRQ could not be detected.\n",
02f1175c 3527 (unsigned long)cy_isa_address);
3137553d 3528 iounmap(cy_isa_address);
02f1175c
JS
3529 continue;
3530 }
3531
3532 if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
21719191
JS
3533 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
3534 "more channels are available. Change NR_PORTS "
3535 "in cyclades.c and recompile kernel.\n",
02f1175c 3536 (unsigned long)cy_isa_address);
3137553d 3537 iounmap(cy_isa_address);
096dcfce 3538 return nboard;
02f1175c
JS
3539 }
3540 /* fill the next cy_card structure available */
3541 for (j = 0; j < NR_CARDS; j++) {
f7429034 3542 if (cy_card[j].base_addr == NULL)
02f1175c
JS
3543 break;
3544 }
3545 if (j == NR_CARDS) { /* no more cy_cards available */
21719191
JS
3546 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
3547 "more cards can be used. Change NR_CARDS in "
3548 "cyclades.c and recompile kernel.\n",
02f1175c 3549 (unsigned long)cy_isa_address);
3137553d 3550 iounmap(cy_isa_address);
096dcfce 3551 return nboard;
02f1175c
JS
3552 }
3553
3554 /* allocate IRQ */
3555 if (request_irq(cy_isa_irq, cyy_interrupt,
3556 IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
21719191
JS
3557 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
3558 "could not allocate IRQ#%d.\n",
3559 (unsigned long)cy_isa_address, cy_isa_irq);
3137553d 3560 iounmap(cy_isa_address);
096dcfce 3561 return nboard;
02f1175c
JS
3562 }
3563
3564 /* set cy_card */
3565 cy_card[j].base_addr = cy_isa_address;
97e87f8e 3566 cy_card[j].ctl_addr.p9050 = NULL;
02f1175c
JS
3567 cy_card[j].irq = (int)cy_isa_irq;
3568 cy_card[j].bus_index = 0;
3569 cy_card[j].first_line = cy_next_channel;
963118ee
JS
3570 cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
3571 cy_card[j].nports = cy_isa_nchan;
3137553d
JS
3572 if (cy_init_card(&cy_card[j])) {
3573 cy_card[j].base_addr = NULL;
3574 free_irq(cy_isa_irq, &cy_card[j]);
3575 iounmap(cy_isa_address);
3576 continue;
3577 }
02f1175c
JS
3578 nboard++;
3579
21719191
JS
3580 printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: "
3581 "%d channels starting from port %d\n",
02f1175c
JS
3582 j + 1, (unsigned long)cy_isa_address,
3583 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
21719191
JS
3584 cy_isa_irq, cy_isa_nchan, cy_next_channel);
3585
6ad1ccc1
JS
3586 for (j = cy_next_channel;
3587 j < cy_next_channel + cy_isa_nchan; j++)
3588 tty_register_device(cy_serial_driver, j, NULL);
02f1175c
JS
3589 cy_next_channel += cy_isa_nchan;
3590 }
096dcfce 3591 return nboard;
1da177e4 3592#else
096dcfce 3593 return 0;
02f1175c
JS
3594#endif /* CONFIG_ISA */
3595} /* cy_detect_isa */
1da177e4 3596
58936d8d 3597#ifdef CONFIG_PCI
054f5b0a
JS
3598static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
3599{
3600 unsigned int a;
3601
3602 for (a = 0; a < size && *str; a++, str++)
3603 if (*str & 0x80)
3604 return -EINVAL;
3605
3606 for (; a < size; a++, str++)
3607 if (*str)
3608 return -EINVAL;
3609
3610 return 0;
3611}
3612
f61e761e 3613static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
054f5b0a
JS
3614 unsigned int size)
3615{
3616 for (; size > 0; size--) {
3617 cy_writel(fpga, *data++);
3618 udelay(10);
3619 }
3620}
3621
3622static void __devinit plx_init(struct pci_dev *pdev, int irq,
3623 struct RUNTIME_9060 __iomem *addr)
1da177e4 3624{
02f1175c 3625 /* Reset PLX */
054f5b0a 3626 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x40000000);
02f1175c 3627 udelay(100L);
054f5b0a 3628 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x40000000);
02f1175c
JS
3629
3630 /* Reload Config. Registers from EEPROM */
054f5b0a 3631 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) | 0x20000000);
02f1175c 3632 udelay(100L);
054f5b0a
JS
3633 cy_writel(&addr->init_ctrl, readl(&addr->init_ctrl) & ~0x20000000);
3634
3635 /* For some yet unknown reason, once the PLX9060 reloads the EEPROM,
3636 * the IRQ is lost and, thus, we have to re-write it to the PCI config.
3637 * registers. This will remain here until we find a permanent fix.
3638 */
3639 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
3640}
3641
3642static int __devinit __cyz_load_fw(const struct firmware *fw,
3643 const char *name, const u32 mailbox, void __iomem *base,
3644 void __iomem *fpga)
3645{
f61e761e
DW
3646 const void *ptr = fw->data;
3647 const struct zfile_header *h = ptr;
3648 const struct zfile_config *c, *cs;
3649 const struct zfile_block *b, *bs;
054f5b0a
JS
3650 unsigned int a, tmp, len = fw->size;
3651#define BAD_FW KERN_ERR "Bad firmware: "
3652 if (len < sizeof(*h)) {
3653 printk(BAD_FW "too short: %u<%zu\n", len, sizeof(*h));
3654 return -EINVAL;
3655 }
3656
3657 cs = ptr + h->config_offset;
3658 bs = ptr + h->block_offset;
3659
3660 if ((void *)(cs + h->n_config) > ptr + len ||
3661 (void *)(bs + h->n_blocks) > ptr + len) {
3662 printk(BAD_FW "too short");
3663 return -EINVAL;
3664 }
3665
3666 if (cyc_isfwstr(h->name, sizeof(h->name)) ||
3667 cyc_isfwstr(h->date, sizeof(h->date))) {
3668 printk(BAD_FW "bad formatted header string\n");
3669 return -EINVAL;
3670 }
3671
3672 if (strncmp(name, h->name, sizeof(h->name))) {
3673 printk(BAD_FW "bad name '%s' (expected '%s')\n", h->name, name);
3674 return -EINVAL;
3675 }
3676
3677 tmp = 0;
3678 for (c = cs; c < cs + h->n_config; c++) {
3679 for (a = 0; a < c->n_blocks; a++)
3680 if (c->block_list[a] > h->n_blocks) {
3681 printk(BAD_FW "bad block ref number in cfgs\n");
3682 return -EINVAL;
3683 }
3684 if (c->mailbox == mailbox && c->function == 0) /* 0 is normal */
3685 tmp++;
3686 }
3687 if (!tmp) {
3688 printk(BAD_FW "nothing appropriate\n");
3689 return -EINVAL;
3690 }
3691
3692 for (b = bs; b < bs + h->n_blocks; b++)
3693 if (b->file_offset + b->size > len) {
3694 printk(BAD_FW "bad block data offset\n");
3695 return -EINVAL;
3696 }
3697
3698 /* everything is OK, let's seek'n'load it */
3699 for (c = cs; c < cs + h->n_config; c++)
3700 if (c->mailbox == mailbox && c->function == 0)
3701 break;
3702
3703 for (a = 0; a < c->n_blocks; a++) {
3704 b = &bs[c->block_list[a]];
3705 if (b->type == ZBLOCK_FPGA) {
3706 if (fpga != NULL)
3707 cyz_fpga_copy(fpga, ptr + b->file_offset,
3708 b->size);
3709 } else {
3710 if (base != NULL)
3711 memcpy_toio(base + b->ram_offset,
3712 ptr + b->file_offset, b->size);
3713 }
3714 }
3715#undef BAD_FW
3716 return 0;
3717}
3718
3719static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
3720 struct RUNTIME_9060 __iomem *ctl_addr, int irq)
3721{
3722 const struct firmware *fw;
3723 struct FIRM_ID __iomem *fid = base_addr + ID_ADDRESS;
3724 struct CUSTOM_REG __iomem *cust = base_addr;
3725 struct ZFW_CTRL __iomem *pt_zfwctrl;
c4923b4f 3726 void __iomem *tmp;
963118ee 3727 u32 mailbox, status, nchan;
054f5b0a
JS
3728 unsigned int i;
3729 int retval;
3730
3731 retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev);
3732 if (retval) {
3733 dev_err(&pdev->dev, "can't get firmware\n");
3734 goto err;
3735 }
3736
3737 /* Check whether the firmware is already loaded and running. If
3738 positive, skip this board */
2693f485 3739 if (__cyz_fpga_loaded(ctl_addr) && readl(&fid->signature) == ZFIRM_ID) {
054f5b0a
JS
3740 u32 cntval = readl(base_addr + 0x190);
3741
3742 udelay(100);
3743 if (cntval != readl(base_addr + 0x190)) {
3744 /* FW counter is working, FW is running */
3745 dev_dbg(&pdev->dev, "Cyclades-Z FW already loaded. "
3746 "Skipping board.\n");
3747 retval = 0;
3748 goto err_rel;
3749 }
3750 }
3751
3752 /* start boot */
3753 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) &
3754 ~0x00030800UL);
3755
3756 mailbox = readl(&ctl_addr->mail_box_0);
3757
2693f485 3758 if (mailbox == 0 || __cyz_fpga_loaded(ctl_addr)) {
054f5b0a
JS
3759 /* stops CPU and set window to beginning of RAM */
3760 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3761 cy_writel(&cust->cpu_stop, 0);
3762 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3763 udelay(100);
3764 }
3765
3766 plx_init(pdev, irq, ctl_addr);
3767
3768 if (mailbox != 0) {
3769 /* load FPGA */
3770 retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, NULL,
3771 base_addr);
3772 if (retval)
3773 goto err_rel;
2693f485 3774 if (!__cyz_fpga_loaded(ctl_addr)) {
054f5b0a
JS
3775 dev_err(&pdev->dev, "fw upload successful, but fw is "
3776 "not loaded\n");
3777 goto err_rel;
3778 }
3779 }
3780
3781 /* stops CPU and set window to beginning of RAM */
3782 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3783 cy_writel(&cust->cpu_stop, 0);
3784 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3785 udelay(100);
3786
3787 /* clear memory */
c4923b4f 3788 for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
054f5b0a
JS
3789 cy_writeb(tmp, 255);
3790 if (mailbox != 0) {
3791 /* set window to last 512K of RAM */
3792 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM + RAM_SIZE);
c4923b4f 3793 for (tmp = base_addr; tmp < base_addr + RAM_SIZE; tmp++)
054f5b0a
JS
3794 cy_writeb(tmp, 255);
3795 /* set window to beginning of RAM */
3796 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
054f5b0a
JS
3797 }
3798
3799 retval = __cyz_load_fw(fw, "Cyclom-Z", mailbox, base_addr, NULL);
3800 release_firmware(fw);
3801 if (retval)
3802 goto err;
3803
3804 /* finish boot and start boards */
3805 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3806 cy_writel(&cust->cpu_start, 0);
3807 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3808 i = 0;
3809 while ((status = readl(&fid->signature)) != ZFIRM_ID && i++ < 40)
3810 msleep(100);
3811 if (status != ZFIRM_ID) {
3812 if (status == ZFIRM_HLT) {
3813 dev_err(&pdev->dev, "you need an external power supply "
3814 "for this number of ports. Firmware halted and "
3815 "board reset.\n");
3816 retval = -EIO;
3817 goto err;
3818 }
3819 dev_warn(&pdev->dev, "fid->signature = 0x%x... Waiting "
3820 "some more time\n", status);
3821 while ((status = readl(&fid->signature)) != ZFIRM_ID &&
3822 i++ < 200)
3823 msleep(100);
3824 if (status != ZFIRM_ID) {
3825 dev_err(&pdev->dev, "Board not started in 20 seconds! "
3826 "Giving up. (fid->signature = 0x%x)\n",
3827 status);
3828 dev_info(&pdev->dev, "*** Warning ***: if you are "
3829 "upgrading the FW, please power cycle the "
3830 "system before loading the new FW to the "
3831 "Cyclades-Z.\n");
3832
2693f485 3833 if (__cyz_fpga_loaded(ctl_addr))
054f5b0a
JS
3834 plx_init(pdev, irq, ctl_addr);
3835
3836 retval = -EIO;
3837 goto err;
3838 }
3839 dev_dbg(&pdev->dev, "Firmware started after %d seconds.\n",
3840 i / 10);
3841 }
3842 pt_zfwctrl = base_addr + readl(&fid->zfwctrl_addr);
3843
3844 dev_dbg(&pdev->dev, "fid=> %p, zfwctrl_addr=> %x, npt_zfwctrl=> %p\n",
3845 base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr),
3846 base_addr + readl(&fid->zfwctrl_addr));
3847
963118ee 3848 nchan = readl(&pt_zfwctrl->board_ctrl.n_channel);
054f5b0a 3849 dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n",
963118ee 3850 readl(&pt_zfwctrl->board_ctrl.fw_version), nchan);
054f5b0a 3851
963118ee 3852 if (nchan == 0) {
054f5b0a
JS
3853 dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please "
3854 "check the connection between the Z host card and the "
3855 "serial expanders.\n");
3856
2693f485 3857 if (__cyz_fpga_loaded(ctl_addr))
054f5b0a
JS
3858 plx_init(pdev, irq, ctl_addr);
3859
3860 dev_info(&pdev->dev, "Null number of ports detected. Board "
3861 "reset.\n");
3862 retval = 0;
3863 goto err;
3864 }
3865
3866 cy_writel(&pt_zfwctrl->board_ctrl.op_system, C_OS_LINUX);
3867 cy_writel(&pt_zfwctrl->board_ctrl.dr_version, DRIVER_VERSION);
3868
3869 /*
3870 Early firmware failed to start looking for commands.
3871 This enables firmware interrupts for those commands.
3872 */
3873 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
3874 (1 << 17));
3875 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
3876 0x00030800UL);
3877
963118ee 3878 return nchan;
054f5b0a
JS
3879err_rel:
3880 release_firmware(fw);
3881err:
3882 return retval;
1da177e4
LT
3883}
3884
58936d8d
JS
3885static int __devinit cy_pci_probe(struct pci_dev *pdev,
3886 const struct pci_device_id *ent)
1da177e4 3887{
3137553d
JS
3888 void __iomem *addr0 = NULL, *addr2 = NULL;
3889 char *card_name = NULL;
101b8159 3890 u32 uninitialized_var(mailbox);
3137553d
JS
3891 unsigned int device_id, nchan = 0, card_no, i;
3892 unsigned char plx_ver;
3893 int retval, irq;
02f1175c 3894
58936d8d
JS
3895 retval = pci_enable_device(pdev);
3896 if (retval) {
3897 dev_err(&pdev->dev, "cannot enable device\n");
3137553d 3898 goto err;
58936d8d 3899 }
1da177e4 3900
58936d8d 3901 /* read PCI configuration area */
3137553d 3902 irq = pdev->irq;
58936d8d 3903 device_id = pdev->device & ~PCI_DEVICE_ID_MASK;
1da177e4 3904
3137553d
JS
3905#if defined(__alpha__)
3906 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
3907 dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low "
3908 "addresses on Alpha systems.\n");
3909 retval = -EIO;
3910 goto err_dis;
3911 }
3912#endif
3913 if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
3914 dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low "
3915 "addresses\n");
3916 retval = -EIO;
3917 goto err_dis;
3918 }
3919
3920 if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
3921 dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring "
3922 "it...\n");
3923 pdev->resource[2].flags &= ~IORESOURCE_IO;
3924 }
3925
3926 retval = pci_request_regions(pdev, "cyclades");
3927 if (retval) {
3928 dev_err(&pdev->dev, "failed to reserve resources\n");
3929 goto err_dis;
3930 }
3931
3932 retval = -EIO;
58936d8d
JS
3933 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
3934 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
3137553d 3935 card_name = "Cyclom-Y";
1da177e4 3936
24e6fd4c
JS
3937 addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
3938 CyPCI_Yctl);
3137553d
JS
3939 if (addr0 == NULL) {
3940 dev_err(&pdev->dev, "can't remap ctl region\n");
3941 goto err_reg;
58936d8d 3942 }
24e6fd4c
JS
3943 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
3944 CyPCI_Ywin);
3137553d
JS
3945 if (addr2 == NULL) {
3946 dev_err(&pdev->dev, "can't remap base region\n");
3947 goto err_unmap;
58936d8d 3948 }
1da177e4 3949
3137553d
JS
3950 nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1);
3951 if (nchan == 0) {
21719191
JS
3952 dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
3953 "Serial-Modules\n");
c847d47c 3954 goto err_unmap;
58936d8d 3955 }
58936d8d 3956 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
3137553d 3957 struct RUNTIME_9060 __iomem *ctl_addr;
21719191 3958
24e6fd4c
JS
3959 ctl_addr = addr0 = ioremap_nocache(pci_resource_start(pdev, 0),
3960 CyPCI_Zctl);
3137553d
JS
3961 if (addr0 == NULL) {
3962 dev_err(&pdev->dev, "can't remap ctl region\n");
3963 goto err_reg;
3964 }
58936d8d
JS
3965
3966 /* Disable interrupts on the PLX before resetting it */
97e87f8e
JS
3967 cy_writew(&ctl_addr->intr_ctrl_stat,
3968 readw(&ctl_addr->intr_ctrl_stat) & ~0x0900);
58936d8d 3969
054f5b0a 3970 plx_init(pdev, irq, addr0);
02f1175c 3971
101b8159 3972 mailbox = readl(&ctl_addr->mail_box_0);
58936d8d 3973
24e6fd4c
JS
3974 addr2 = ioremap_nocache(pci_resource_start(pdev, 2),
3975 mailbox == ZE_V1 ? CyPCI_Ze_win : CyPCI_Zwin);
3137553d
JS
3976 if (addr2 == NULL) {
3977 dev_err(&pdev->dev, "can't remap base region\n");
3978 goto err_unmap;
58936d8d
JS
3979 }
3980
3981 if (mailbox == ZE_V1) {
3137553d 3982 card_name = "Cyclades-Ze";
58936d8d 3983 } else {
3137553d 3984 card_name = "Cyclades-8Zo";
1da177e4 3985#ifdef CY_PCI_DEBUG
3137553d
JS
3986 if (mailbox == ZO_V1) {
3987 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
3988 dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA "
3989 "id %lx, ver %lx\n", (ulong)(0xff &
3990 readl(&((struct CUSTOM_REG *)addr2)->
3991 fpga_id)), (ulong)(0xff &
3992 readl(&((struct CUSTOM_REG *)addr2)->
3993 fpga_version)));
3994 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
3995 } else {
3996 dev_info(&pdev->dev, "Cyclades-Z/PCI: New "
3997 "Cyclades-Z board. FPGA not loaded\n");
3998 }
1da177e4 3999#endif
3137553d
JS
4000 /* The following clears the firmware id word. This
4001 ensures that the driver will not attempt to talk to
4002 the board until it has been properly initialized.
4003 */
4004 if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
4005 cy_writel(addr2 + ID_ADDRESS, 0L);
58936d8d 4006 }
ace08c3c
JS
4007
4008 retval = cyz_load_fw(pdev, addr2, addr0, irq);
963118ee 4009 if (retval <= 0)
ace08c3c 4010 goto err_unmap;
963118ee 4011 nchan = retval;
3137553d
JS
4012 }
4013
4014 if ((cy_next_channel + nchan) > NR_PORTS) {
4015 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
4016 "channels are available. Change NR_PORTS in "
4017 "cyclades.c and recompile kernel.\n");
4018 goto err_unmap;
4019 }
4020 /* fill the next cy_card structure available */
4021 for (card_no = 0; card_no < NR_CARDS; card_no++) {
4022 if (cy_card[card_no].base_addr == NULL)
4023 break;
4024 }
4025 if (card_no == NR_CARDS) { /* no more cy_cards available */
4026 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
4027 "more cards can be used. Change NR_CARDS in "
4028 "cyclades.c and recompile kernel.\n");
4029 goto err_unmap;
4030 }
4031
4032 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
4033 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
4034 /* allocate IRQ */
4035 retval = request_irq(irq, cyy_interrupt,
4036 IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
4037 if (retval) {
4038 dev_err(&pdev->dev, "could not allocate IRQ\n");
4039 goto err_unmap;
58936d8d 4040 }
963118ee 4041 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
3137553d 4042 } else {
f0eefdc3
JS
4043 struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
4044 struct ZFW_CTRL __iomem *zfw_ctrl;
4045
4046 zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
4047
101b8159
JS
4048 cy_card[card_no].hw_ver = mailbox;
4049 cy_card[card_no].num_chips = (unsigned int)-1;
f0eefdc3 4050 cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
02f1175c 4051#ifdef CONFIG_CYZ_INTR
58936d8d 4052 /* allocate IRQ only if board has an IRQ */
3137553d
JS
4053 if (irq != 0 && irq != 255) {
4054 retval = request_irq(irq, cyz_interrupt,
58936d8d 4055 IRQF_SHARED, "Cyclades-Z",
3137553d 4056 &cy_card[card_no]);
58936d8d 4057 if (retval) {
21719191 4058 dev_err(&pdev->dev, "could not allocate IRQ\n");
3137553d 4059 goto err_unmap;
02f1175c 4060 }
58936d8d 4061 }
02f1175c 4062#endif /* CONFIG_CYZ_INTR */
3137553d 4063 }
02f1175c 4064
3137553d
JS
4065 /* set cy_card */
4066 cy_card[card_no].base_addr = addr2;
97e87f8e 4067 cy_card[card_no].ctl_addr.p9050 = addr0;
3137553d
JS
4068 cy_card[card_no].irq = irq;
4069 cy_card[card_no].bus_index = 1;
4070 cy_card[card_no].first_line = cy_next_channel;
963118ee 4071 cy_card[card_no].nports = nchan;
3137553d
JS
4072 retval = cy_init_card(&cy_card[card_no]);
4073 if (retval)
4074 goto err_null;
58936d8d 4075
3137553d 4076 pci_set_drvdata(pdev, &cy_card[card_no]);
58936d8d 4077
3137553d
JS
4078 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
4079 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
4080 /* enable interrupts in the PCI interface */
4081 plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
4082 switch (plx_ver) {
4083 case PLX_9050:
3137553d
JS
4084 cy_writeb(addr0 + 0x4c, 0x43);
4085 break;
4086
4087 case PLX_9060:
4088 case PLX_9080:
4089 default: /* Old boards, use PLX_9060 */
97e87f8e
JS
4090 {
4091 struct RUNTIME_9060 __iomem *ctl_addr = addr0;
4092 plx_init(pdev, irq, ctl_addr);
4093 cy_writew(&ctl_addr->intr_ctrl_stat,
4094 readw(&ctl_addr->intr_ctrl_stat) | 0x0900);
3137553d
JS
4095 break;
4096 }
97e87f8e 4097 }
58936d8d
JS
4098 }
4099
3137553d
JS
4100 dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
4101 "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel);
4102 for (i = cy_next_channel; i < cy_next_channel + nchan; i++)
4103 tty_register_device(cy_serial_driver, i, &pdev->dev);
4104 cy_next_channel += nchan;
4105
58936d8d 4106 return 0;
3137553d
JS
4107err_null:
4108 cy_card[card_no].base_addr = NULL;
4109 free_irq(irq, &cy_card[card_no]);
4110err_unmap:
24e6fd4c 4111 iounmap(addr0);
3137553d 4112 if (addr2)
24e6fd4c 4113 iounmap(addr2);
3137553d
JS
4114err_reg:
4115 pci_release_regions(pdev);
4116err_dis:
4117 pci_disable_device(pdev);
4118err:
4119 return retval;
58936d8d 4120}
58936d8d 4121
6747cd93 4122static void __devexit cy_pci_remove(struct pci_dev *pdev)
58936d8d 4123{
38d09093 4124 struct cyclades_card *cinfo = pci_get_drvdata(pdev);
f3851e73 4125 unsigned int i;
38d09093 4126
85c93fa9 4127 /* non-Z with old PLX */
2693f485 4128 if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
c2ad4c75 4129 PLX_9050)
97e87f8e 4130 cy_writeb(cinfo->ctl_addr.p9050 + 0x4c, 0);
85c93fa9
JS
4131 else
4132#ifndef CONFIG_CYZ_INTR
2693f485 4133 if (!cy_is_Z(cinfo))
85c93fa9 4134#endif
97e87f8e
JS
4135 cy_writew(&cinfo->ctl_addr.p9060->intr_ctrl_stat,
4136 readw(&cinfo->ctl_addr.p9060->intr_ctrl_stat) &
4137 ~0x0900);
85c93fa9 4138
24e6fd4c 4139 iounmap(cinfo->base_addr);
97e87f8e
JS
4140 if (cinfo->ctl_addr.p9050)
4141 iounmap(cinfo->ctl_addr.p9050);
38d09093
JS
4142 if (cinfo->irq
4143#ifndef CONFIG_CYZ_INTR
2693f485 4144 && !cy_is_Z(cinfo)
38d09093
JS
4145#endif /* CONFIG_CYZ_INTR */
4146 )
4147 free_irq(cinfo->irq, cinfo);
4148 pci_release_regions(pdev);
4149
4150 cinfo->base_addr = NULL;
6ad1ccc1
JS
4151 for (i = cinfo->first_line; i < cinfo->first_line +
4152 cinfo->nports; i++)
4153 tty_unregister_device(cy_serial_driver, i);
dd025c0c
JS
4154 cinfo->nports = 0;
4155 kfree(cinfo->ports);
38d09093
JS
4156}
4157
6747cd93
JS
4158static struct pci_driver cy_pci_driver = {
4159 .name = "cyclades",
4160 .id_table = cy_pci_dev_id,
4161 .probe = cy_pci_probe,
4162 .remove = __devexit_p(cy_pci_remove)
4163};
4164#endif
4165
444697d6 4166static int cyclades_proc_show(struct seq_file *m, void *v)
1da177e4 4167{
02f1175c 4168 struct cyclades_port *info;
dd025c0c 4169 unsigned int i, j;
02f1175c
JS
4170 __u32 cur_jifs = jiffies;
4171
444697d6 4172 seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn "
02f1175c
JS
4173 "IdleIn Overruns Ldisc\n");
4174
02f1175c 4175 /* Output one line for each known port */
dd025c0c
JS
4176 for (i = 0; i < NR_CARDS; i++)
4177 for (j = 0; j < cy_card[i].nports; j++) {
4178 info = &cy_card[i].ports[j];
4179
d13549f8
JS
4180 if (info->port.count) {
4181 /* XXX is the ldisc num worth this? */
4182 struct tty_struct *tty;
4183 struct tty_ldisc *ld;
4184 int num = 0;
4185 tty = tty_port_tty_get(&info->port);
4186 if (tty) {
4187 ld = tty_ldisc_ref(tty);
4188 if (ld) {
4189 num = ld->ops->num;
4190 tty_ldisc_deref(ld);
4191 }
4192 tty_kref_put(tty);
4193 }
444697d6 4194 seq_printf(m, "%3d %8lu %10lu %8lu "
d13549f8 4195 "%10lu %8lu %9lu %6d\n", info->line,
dd025c0c
JS
4196 (cur_jifs - info->idle_stats.in_use) /
4197 HZ, info->idle_stats.xmit_bytes,
4198 (cur_jifs - info->idle_stats.xmit_idle)/
4199 HZ, info->idle_stats.recv_bytes,
4200 (cur_jifs - info->idle_stats.recv_idle)/
4201 HZ, info->idle_stats.overruns,
d13549f8
JS
4202 num);
4203 } else
444697d6 4204 seq_printf(m, "%3d %8lu %10lu %8lu "
dd025c0c
JS
4205 "%10lu %8lu %9lu %6ld\n",
4206 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
02f1175c 4207 }
444697d6
AD
4208 return 0;
4209}
4210
4211static int cyclades_proc_open(struct inode *inode, struct file *file)
4212{
4213 return single_open(file, cyclades_proc_show, NULL);
1da177e4
LT
4214}
4215
444697d6
AD
4216static const struct file_operations cyclades_proc_fops = {
4217 .owner = THIS_MODULE,
4218 .open = cyclades_proc_open,
4219 .read = seq_read,
4220 .llseek = seq_lseek,
4221 .release = single_release,
4222};
4223
1da177e4
LT
4224/* The serial driver boot-time initialization code!
4225 Hardware I/O ports are mapped to character special devices on a
4226 first found, first allocated manner. That is, this code searches
4227 for Cyclom cards in the system. As each is found, it is probed
4228 to discover how many chips (and thus how many ports) are present.
4229 These ports are mapped to the tty ports 32 and upward in monotonic
4230 fashion. If an 8-port card is replaced with a 16-port card, the
4231 port mapping on a following card will shift.
4232
4233 This approach is different from what is used in the other serial
4234 device driver because the Cyclom is more properly a multiplexer,
4235 not just an aggregation of serial ports on one card.
4236
4237 If there are more cards with more ports than have been
4238 statically allocated above, a warning is printed and the
4239 extra ports are ignored.
4240 */
4241
b68e31d0 4242static const struct tty_operations cy_ops = {
02f1175c
JS
4243 .open = cy_open,
4244 .close = cy_close,
4245 .write = cy_write,
4246 .put_char = cy_put_char,
4247 .flush_chars = cy_flush_chars,
4248 .write_room = cy_write_room,
4249 .chars_in_buffer = cy_chars_in_buffer,
4250 .flush_buffer = cy_flush_buffer,
4251 .ioctl = cy_ioctl,
4252 .throttle = cy_throttle,
4253 .unthrottle = cy_unthrottle,
4254 .set_termios = cy_set_termios,
4255 .stop = cy_stop,
4256 .start = cy_start,
4257 .hangup = cy_hangup,
4258 .break_ctl = cy_break,
4259 .wait_until_sent = cy_wait_until_sent,
02f1175c
JS
4260 .tiocmget = cy_tiocmget,
4261 .tiocmset = cy_tiocmset,
444697d6 4262 .proc_fops = &cyclades_proc_fops,
1da177e4
LT
4263};
4264
02f1175c 4265static int __init cy_init(void)
1da177e4 4266{
dd025c0c 4267 unsigned int nboards;
9dacf3b2 4268 int retval = -ENOMEM;
02f1175c
JS
4269
4270 cy_serial_driver = alloc_tty_driver(NR_PORTS);
4271 if (!cy_serial_driver)
9dacf3b2 4272 goto err;
21719191
JS
4273
4274 printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
4275 __DATE__, __TIME__);
02f1175c
JS
4276
4277 /* Initialize the tty_driver structure */
4278
4279 cy_serial_driver->owner = THIS_MODULE;
4280 cy_serial_driver->driver_name = "cyclades";
4281 cy_serial_driver->name = "ttyC";
4282 cy_serial_driver->major = CYCLADES_MAJOR;
4283 cy_serial_driver->minor_start = 0;
4284 cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
4285 cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
4286 cy_serial_driver->init_termios = tty_std_termios;
4287 cy_serial_driver->init_termios.c_cflag =
4288 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
6ad1ccc1 4289 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
02f1175c
JS
4290 tty_set_operations(cy_serial_driver, &cy_ops);
4291
9dacf3b2
JS
4292 retval = tty_register_driver(cy_serial_driver);
4293 if (retval) {
4294 printk(KERN_ERR "Couldn't register Cyclades serial driver\n");
4295 goto err_frtty;
4296 }
02f1175c 4297
02f1175c
JS
4298 /* the code below is responsible to find the boards. Each different
4299 type of board has its own detection routine. If a board is found,
4300 the next cy_card structure available is set by the detection
4301 routine. These functions are responsible for checking the
4302 availability of cy_card and cy_port data structures and updating
4303 the cy_next_channel. */
4304
4305 /* look for isa boards */
14a55a67 4306 nboards = cy_detect_isa();
02f1175c 4307
6747cd93 4308#ifdef CONFIG_PCI
02f1175c 4309 /* look for pci boards */
6747cd93 4310 retval = pci_register_driver(&cy_pci_driver);
d941ea7d
JJ
4311 if (retval && !nboards) {
4312 tty_unregister_driver(cy_serial_driver);
4313 goto err_frtty;
4314 }
6747cd93 4315#endif
9dacf3b2
JS
4316
4317 return 0;
9dacf3b2
JS
4318err_frtty:
4319 put_tty_driver(cy_serial_driver);
4320err:
4321 return retval;
02f1175c 4322} /* cy_init */
1da177e4 4323
02f1175c 4324static void __exit cy_cleanup_module(void)
1da177e4 4325{
dd025c0c 4326 struct cyclades_card *card;
65f76a82 4327 unsigned int i, e1;
1da177e4
LT
4328
4329#ifndef CONFIG_CYZ_INTR
b7050906 4330 del_timer_sync(&cyz_timerlist);
1da177e4
LT
4331#endif /* CONFIG_CYZ_INTR */
4332
15ed6cc0
AC
4333 e1 = tty_unregister_driver(cy_serial_driver);
4334 if (e1)
21719191
JS
4335 printk(KERN_ERR "failed to unregister Cyclades serial "
4336 "driver(%d)\n", e1);
1da177e4 4337
6747cd93
JS
4338#ifdef CONFIG_PCI
4339 pci_unregister_driver(&cy_pci_driver);
4340#endif
4341
02f1175c 4342 for (i = 0; i < NR_CARDS; i++) {
dd025c0c
JS
4343 card = &cy_card[i];
4344 if (card->base_addr) {
85c93fa9 4345 /* clear interrupt */
dd025c0c
JS
4346 cy_writeb(card->base_addr + Cy_ClrIntr, 0);
4347 iounmap(card->base_addr);
97e87f8e
JS
4348 if (card->ctl_addr.p9050)
4349 iounmap(card->ctl_addr.p9050);
dd025c0c 4350 if (card->irq
1da177e4 4351#ifndef CONFIG_CYZ_INTR
2693f485 4352 && !cy_is_Z(card)
1da177e4 4353#endif /* CONFIG_CYZ_INTR */
02f1175c 4354 )
dd025c0c 4355 free_irq(card->irq, card);
65f76a82 4356 for (e1 = card->first_line; e1 < card->first_line +
dd025c0c 4357 card->nports; e1++)
6ad1ccc1 4358 tty_unregister_device(cy_serial_driver, e1);
dd025c0c 4359 kfree(card->ports);
02f1175c
JS
4360 }
4361 }
f2462bfe
JS
4362
4363 put_tty_driver(cy_serial_driver);
1da177e4
LT
4364} /* cy_cleanup_module */
4365
4366module_init(cy_init);
4367module_exit(cy_cleanup_module);
4368
4369MODULE_LICENSE("GPL");
c8e1693a 4370MODULE_VERSION(CY_VERSION);
9f56fad7 4371MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);