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