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