[PATCH] sysctl: remove sys_sysctl support from the hpet timer driver
[linux-2.6/linux-mips.git] / drivers / serial / icom.c
blob41431d0d5512633f184f6fb8c92cd5aad6ed343a
1 /*
2 * icom.c
4 * Copyright (C) 2001 IBM Corporation. All rights reserved.
6 * Serial device driver.
8 * Based on code from serial.c
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #define SERIAL_DO_RESTART
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/errno.h>
29 #include <linux/signal.h>
30 #include <linux/timer.h>
31 #include <linux/interrupt.h>
32 #include <linux/tty.h>
33 #include <linux/termios.h>
34 #include <linux/fs.h>
35 #include <linux/tty_flip.h>
36 #include <linux/serial.h>
37 #include <linux/serial_reg.h>
38 #include <linux/major.h>
39 #include <linux/string.h>
40 #include <linux/fcntl.h>
41 #include <linux/ptrace.h>
42 #include <linux/ioport.h>
43 #include <linux/mm.h>
44 #include <linux/slab.h>
45 #include <linux/init.h>
46 #include <linux/delay.h>
47 #include <linux/pci.h>
48 #include <linux/vmalloc.h>
49 #include <linux/smp.h>
50 #include <linux/smp_lock.h>
51 #include <linux/spinlock.h>
52 #include <linux/kobject.h>
53 #include <linux/firmware.h>
54 #include <linux/bitops.h>
56 #include <asm/system.h>
57 #include <asm/io.h>
58 #include <asm/irq.h>
59 #include <asm/uaccess.h>
61 #include "icom.h"
63 /*#define ICOM_TRACE enable port trace capabilities */
65 #define ICOM_DRIVER_NAME "icom"
66 #define ICOM_VERSION_STR "1.3.1"
67 #define NR_PORTS 128
68 #define ICOM_PORT ((struct icom_port *)port)
69 #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj)
71 static const struct pci_device_id icom_pci_table[] = {
73 .vendor = PCI_VENDOR_ID_IBM,
74 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1,
75 .subvendor = PCI_ANY_ID,
76 .subdevice = PCI_ANY_ID,
77 .driver_data = ADAPTER_V1,
80 .vendor = PCI_VENDOR_ID_IBM,
81 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
82 .subvendor = PCI_VENDOR_ID_IBM,
83 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX,
84 .driver_data = ADAPTER_V2,
87 .vendor = PCI_VENDOR_ID_IBM,
88 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
89 .subvendor = PCI_VENDOR_ID_IBM,
90 .subdevice = PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM,
91 .driver_data = ADAPTER_V2,
94 .vendor = PCI_VENDOR_ID_IBM,
95 .device = PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2,
96 .subvendor = PCI_VENDOR_ID_IBM,
97 .subdevice = PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL,
98 .driver_data = ADAPTER_V2,
103 struct lookup_proc_table start_proc[4] = {
104 {NULL, ICOM_CONTROL_START_A},
105 {NULL, ICOM_CONTROL_START_B},
106 {NULL, ICOM_CONTROL_START_C},
107 {NULL, ICOM_CONTROL_START_D}
111 struct lookup_proc_table stop_proc[4] = {
112 {NULL, ICOM_CONTROL_STOP_A},
113 {NULL, ICOM_CONTROL_STOP_B},
114 {NULL, ICOM_CONTROL_STOP_C},
115 {NULL, ICOM_CONTROL_STOP_D}
118 struct lookup_int_table int_mask_tbl[4] = {
119 {NULL, ICOM_INT_MASK_PRC_A},
120 {NULL, ICOM_INT_MASK_PRC_B},
121 {NULL, ICOM_INT_MASK_PRC_C},
122 {NULL, ICOM_INT_MASK_PRC_D},
126 MODULE_DEVICE_TABLE(pci, icom_pci_table);
128 static LIST_HEAD(icom_adapter_head);
130 /* spinlock for adapter initialization and changing adapter operations */
131 static spinlock_t icom_lock;
133 #ifdef ICOM_TRACE
134 static inline void trace(struct icom_port *, char *, unsigned long) {};
135 #else
136 static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {};
137 #endif
139 static void free_port_memory(struct icom_port *icom_port)
141 struct pci_dev *dev = icom_port->adapter->pci_dev;
143 trace(icom_port, "RET_PORT_MEM", 0);
144 if (icom_port->recv_buf) {
145 pci_free_consistent(dev, 4096, icom_port->recv_buf,
146 icom_port->recv_buf_pci);
147 icom_port->recv_buf = NULL;
149 if (icom_port->xmit_buf) {
150 pci_free_consistent(dev, 4096, icom_port->xmit_buf,
151 icom_port->xmit_buf_pci);
152 icom_port->xmit_buf = NULL;
154 if (icom_port->statStg) {
155 pci_free_consistent(dev, 4096, icom_port->statStg,
156 icom_port->statStg_pci);
157 icom_port->statStg = NULL;
160 if (icom_port->xmitRestart) {
161 pci_free_consistent(dev, 4096, icom_port->xmitRestart,
162 icom_port->xmitRestart_pci);
163 icom_port->xmitRestart = NULL;
167 static int __init get_port_memory(struct icom_port *icom_port)
169 int index;
170 unsigned long stgAddr;
171 unsigned long startStgAddr;
172 unsigned long offset;
173 struct pci_dev *dev = icom_port->adapter->pci_dev;
175 icom_port->xmit_buf =
176 pci_alloc_consistent(dev, 4096, &icom_port->xmit_buf_pci);
177 if (!icom_port->xmit_buf) {
178 dev_err(&dev->dev, "Can not allocate Transmit buffer\n");
179 return -ENOMEM;
182 trace(icom_port, "GET_PORT_MEM",
183 (unsigned long) icom_port->xmit_buf);
185 icom_port->recv_buf =
186 pci_alloc_consistent(dev, 4096, &icom_port->recv_buf_pci);
187 if (!icom_port->recv_buf) {
188 dev_err(&dev->dev, "Can not allocate Receive buffer\n");
189 free_port_memory(icom_port);
190 return -ENOMEM;
192 trace(icom_port, "GET_PORT_MEM",
193 (unsigned long) icom_port->recv_buf);
195 icom_port->statStg =
196 pci_alloc_consistent(dev, 4096, &icom_port->statStg_pci);
197 if (!icom_port->statStg) {
198 dev_err(&dev->dev, "Can not allocate Status buffer\n");
199 free_port_memory(icom_port);
200 return -ENOMEM;
202 trace(icom_port, "GET_PORT_MEM",
203 (unsigned long) icom_port->statStg);
205 icom_port->xmitRestart =
206 pci_alloc_consistent(dev, 4096, &icom_port->xmitRestart_pci);
207 if (!icom_port->xmitRestart) {
208 dev_err(&dev->dev,
209 "Can not allocate xmit Restart buffer\n");
210 free_port_memory(icom_port);
211 return -ENOMEM;
214 memset(icom_port->statStg, 0, 4096);
216 /* FODs: Frame Out Descriptor Queue, this is a FIFO queue that
217 indicates that frames are to be transmitted
220 stgAddr = (unsigned long) icom_port->statStg;
221 for (index = 0; index < NUM_XBUFFS; index++) {
222 trace(icom_port, "FOD_ADDR", stgAddr);
223 stgAddr = stgAddr + sizeof(icom_port->statStg->xmit[0]);
224 if (index < (NUM_XBUFFS - 1)) {
225 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
226 icom_port->statStg->xmit[index].leLengthASD =
227 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
228 trace(icom_port, "FOD_ADDR", stgAddr);
229 trace(icom_port, "FOD_XBUFF",
230 (unsigned long) icom_port->xmit_buf);
231 icom_port->statStg->xmit[index].leBuffer =
232 cpu_to_le32(icom_port->xmit_buf_pci);
233 } else if (index == (NUM_XBUFFS - 1)) {
234 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
235 icom_port->statStg->xmit[index].leLengthASD =
236 (unsigned short int) cpu_to_le16(XMIT_BUFF_SZ);
237 trace(icom_port, "FOD_XBUFF",
238 (unsigned long) icom_port->xmit_buf);
239 icom_port->statStg->xmit[index].leBuffer =
240 cpu_to_le32(icom_port->xmit_buf_pci);
241 } else {
242 memset(&icom_port->statStg->xmit[index], 0, sizeof(struct xmit_status_area));
245 /* FIDs */
246 startStgAddr = stgAddr;
248 /* fill in every entry, even if no buffer */
249 for (index = 0; index < NUM_RBUFFS; index++) {
250 trace(icom_port, "FID_ADDR", stgAddr);
251 stgAddr = stgAddr + sizeof(icom_port->statStg->rcv[0]);
252 icom_port->statStg->rcv[index].leLength = 0;
253 icom_port->statStg->rcv[index].WorkingLength =
254 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
255 if (index < (NUM_RBUFFS - 1) ) {
256 offset = stgAddr - (unsigned long) icom_port->statStg;
257 icom_port->statStg->rcv[index].leNext =
258 cpu_to_le32(icom_port-> statStg_pci + offset);
259 trace(icom_port, "FID_RBUFF",
260 (unsigned long) icom_port->recv_buf);
261 icom_port->statStg->rcv[index].leBuffer =
262 cpu_to_le32(icom_port->recv_buf_pci);
263 } else if (index == (NUM_RBUFFS -1) ) {
264 offset = startStgAddr - (unsigned long) icom_port->statStg;
265 icom_port->statStg->rcv[index].leNext =
266 cpu_to_le32(icom_port-> statStg_pci + offset);
267 trace(icom_port, "FID_RBUFF",
268 (unsigned long) icom_port->recv_buf + 2048);
269 icom_port->statStg->rcv[index].leBuffer =
270 cpu_to_le32(icom_port->recv_buf_pci + 2048);
271 } else {
272 icom_port->statStg->rcv[index].leNext = 0;
273 icom_port->statStg->rcv[index].leBuffer = 0;
277 return 0;
280 static void stop_processor(struct icom_port *icom_port)
282 unsigned long temp;
283 unsigned long flags;
284 int port;
286 spin_lock_irqsave(&icom_lock, flags);
288 port = icom_port->port;
289 if (port == 0 || port == 1)
290 stop_proc[port].global_control_reg = &icom_port->global_reg->control;
291 else
292 stop_proc[port].global_control_reg = &icom_port->global_reg->control_2;
295 if (port < 4) {
296 temp = readl(stop_proc[port].global_control_reg);
297 temp =
298 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
299 writel(temp, stop_proc[port].global_control_reg);
301 /* write flush */
302 readl(stop_proc[port].global_control_reg);
303 } else {
304 dev_err(&icom_port->adapter->pci_dev->dev,
305 "Invalid port assignment\n");
308 spin_unlock_irqrestore(&icom_lock, flags);
311 static void start_processor(struct icom_port *icom_port)
313 unsigned long temp;
314 unsigned long flags;
315 int port;
317 spin_lock_irqsave(&icom_lock, flags);
319 port = icom_port->port;
320 if (port == 0 || port == 1)
321 start_proc[port].global_control_reg = &icom_port->global_reg->control;
322 else
323 start_proc[port].global_control_reg = &icom_port->global_reg->control_2;
324 if (port < 4) {
325 temp = readl(start_proc[port].global_control_reg);
326 temp =
327 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
328 writel(temp, start_proc[port].global_control_reg);
330 /* write flush */
331 readl(start_proc[port].global_control_reg);
332 } else {
333 dev_err(&icom_port->adapter->pci_dev->dev,
334 "Invalid port assignment\n");
337 spin_unlock_irqrestore(&icom_lock, flags);
340 static void load_code(struct icom_port *icom_port)
342 const struct firmware *fw;
343 char __iomem *iram_ptr;
344 int index;
345 int status = 0;
346 void __iomem *dram_ptr = icom_port->dram;
347 dma_addr_t temp_pci;
348 unsigned char *new_page = NULL;
349 unsigned char cable_id = NO_CABLE;
350 struct pci_dev *dev = icom_port->adapter->pci_dev;
352 /* Clear out any pending interrupts */
353 writew(0x3FFF, icom_port->int_reg);
355 trace(icom_port, "CLEAR_INTERRUPTS", 0);
357 /* Stop processor */
358 stop_processor(icom_port);
360 /* Zero out DRAM */
361 memset_io(dram_ptr, 0, 512);
363 /* Load Call Setup into Adapter */
364 if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
365 dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
366 status = -1;
367 goto load_code_exit;
370 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
371 dev_err(&dev->dev, "Invalid firmware image for icom_call_setup.bin found.\n");
372 release_firmware(fw);
373 status = -1;
374 goto load_code_exit;
377 iram_ptr = (char __iomem *)icom_port->dram + ICOM_IRAM_OFFSET;
378 for (index = 0; index < fw->size; index++)
379 writeb(fw->data[index], &iram_ptr[index]);
381 release_firmware(fw);
383 /* Load Resident DCE portion of Adapter */
384 if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
385 dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
386 status = -1;
387 goto load_code_exit;
390 if (fw->size > ICOM_IRAM_SIZE) {
391 dev_err(&dev->dev, "Invalid firmware image for icom_res_dce.bin found.\n");
392 release_firmware(fw);
393 status = -1;
394 goto load_code_exit;
397 iram_ptr = (char __iomem *) icom_port->dram + ICOM_IRAM_OFFSET;
398 for (index = ICOM_DCE_IRAM_OFFSET; index < fw->size; index++)
399 writeb(fw->data[index], &iram_ptr[index]);
401 release_firmware(fw);
403 /* Set Hardware level */
404 if ((icom_port->adapter->version | ADAPTER_V2) == ADAPTER_V2)
405 writeb(V2_HARDWARE, &(icom_port->dram->misc_flags));
407 /* Start the processor in Adapter */
408 start_processor(icom_port);
410 writeb((HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL),
411 &(icom_port->dram->HDLCConfigReg));
412 writeb(0x04, &(icom_port->dram->FlagFillIdleTimer)); /* 0.5 seconds */
413 writeb(0x00, &(icom_port->dram->CmdReg));
414 writeb(0x10, &(icom_port->dram->async_config3));
415 writeb((ICOM_ACFG_DRIVE1 | ICOM_ACFG_NO_PARITY | ICOM_ACFG_8BPC |
416 ICOM_ACFG_1STOP_BIT), &(icom_port->dram->async_config2));
418 /*Set up data in icom DRAM to indicate where personality
419 *code is located and its length.
421 new_page = pci_alloc_consistent(dev, 4096, &temp_pci);
423 if (!new_page) {
424 dev_err(&dev->dev, "Can not allocate DMA buffer\n");
425 status = -1;
426 goto load_code_exit;
429 if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
430 dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
431 status = -1;
432 goto load_code_exit;
435 if (fw->size > ICOM_DCE_IRAM_OFFSET) {
436 dev_err(&dev->dev, "Invalid firmware image for icom_asc.bin found.\n");
437 release_firmware(fw);
438 status = -1;
439 goto load_code_exit;
442 for (index = 0; index < fw->size; index++)
443 new_page[index] = fw->data[index];
445 release_firmware(fw);
447 writeb((char) ((fw->size + 16)/16), &icom_port->dram->mac_length);
448 writel(temp_pci, &icom_port->dram->mac_load_addr);
450 /*Setting the syncReg to 0x80 causes adapter to start downloading
451 the personality code into adapter instruction RAM.
452 Once code is loaded, it will begin executing and, based on
453 information provided above, will start DMAing data from
454 shared memory to adapter DRAM.
456 /* the wait loop below verifies this write operation has been done
457 and processed
459 writeb(START_DOWNLOAD, &icom_port->dram->sync);
461 /* Wait max 1 Sec for data download and processor to start */
462 for (index = 0; index < 10; index++) {
463 msleep(100);
464 if (readb(&icom_port->dram->misc_flags) & ICOM_HDW_ACTIVE)
465 break;
468 if (index == 10)
469 status = -1;
472 * check Cable ID
474 cable_id = readb(&icom_port->dram->cable_id);
476 if (cable_id & ICOM_CABLE_ID_VALID) {
477 /* Get cable ID into the lower 4 bits (standard form) */
478 cable_id = (cable_id & ICOM_CABLE_ID_MASK) >> 4;
479 icom_port->cable_id = cable_id;
480 } else {
481 dev_err(&dev->dev,"Invalid or no cable attached\n");
482 icom_port->cable_id = NO_CABLE;
485 load_code_exit:
487 if (status != 0) {
488 /* Clear out any pending interrupts */
489 writew(0x3FFF, icom_port->int_reg);
491 /* Turn off port */
492 writeb(ICOM_DISABLE, &(icom_port->dram->disable));
494 /* Stop processor */
495 stop_processor(icom_port);
497 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
500 if (new_page != NULL)
501 pci_free_consistent(dev, 4096, new_page, temp_pci);
504 static int startup(struct icom_port *icom_port)
506 unsigned long temp;
507 unsigned char cable_id, raw_cable_id;
508 unsigned long flags;
509 int port;
511 trace(icom_port, "STARTUP", 0);
513 if (!icom_port->dram) {
514 /* should NEVER be NULL */
515 dev_err(&icom_port->adapter->pci_dev->dev,
516 "Unusable Port, port configuration missing\n");
517 return -ENODEV;
521 * check Cable ID
523 raw_cable_id = readb(&icom_port->dram->cable_id);
524 trace(icom_port, "CABLE_ID", raw_cable_id);
526 /* Get cable ID into the lower 4 bits (standard form) */
527 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
529 /* Check for valid Cable ID */
530 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
531 (cable_id != icom_port->cable_id)) {
533 /* reload adapter code, pick up any potential changes in cable id */
534 load_code(icom_port);
536 /* still no sign of cable, error out */
537 raw_cable_id = readb(&icom_port->dram->cable_id);
538 cable_id = (raw_cable_id & ICOM_CABLE_ID_MASK) >> 4;
539 if (!(raw_cable_id & ICOM_CABLE_ID_VALID) ||
540 (icom_port->cable_id == NO_CABLE))
541 return -EIO;
545 * Finally, clear and enable interrupts
547 spin_lock_irqsave(&icom_lock, flags);
548 port = icom_port->port;
549 if (port == 0 || port == 1)
550 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
551 else
552 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
554 if (port == 0 || port == 2)
555 writew(0x00FF, icom_port->int_reg);
556 else
557 writew(0x3F00, icom_port->int_reg);
558 if (port < 4) {
559 temp = readl(int_mask_tbl[port].global_int_mask);
560 writel(temp & ~int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
562 /* write flush */
563 readl(int_mask_tbl[port].global_int_mask);
564 } else {
565 dev_err(&icom_port->adapter->pci_dev->dev,
566 "Invalid port assignment\n");
569 spin_unlock_irqrestore(&icom_lock, flags);
570 return 0;
573 static void shutdown(struct icom_port *icom_port)
575 unsigned long temp;
576 unsigned char cmdReg;
577 unsigned long flags;
578 int port;
580 spin_lock_irqsave(&icom_lock, flags);
581 trace(icom_port, "SHUTDOWN", 0);
584 * disable all interrupts
586 port = icom_port->port;
587 if (port == 0 || port == 1)
588 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask;
589 else
590 int_mask_tbl[port].global_int_mask = &icom_port->global_reg->int_mask_2;
592 if (port < 4) {
593 temp = readl(int_mask_tbl[port].global_int_mask);
594 writel(temp | int_mask_tbl[port].processor_id, int_mask_tbl[port].global_int_mask);
596 /* write flush */
597 readl(int_mask_tbl[port].global_int_mask);
598 } else {
599 dev_err(&icom_port->adapter->pci_dev->dev,
600 "Invalid port assignment\n");
602 spin_unlock_irqrestore(&icom_lock, flags);
605 * disable break condition
607 cmdReg = readb(&icom_port->dram->CmdReg);
608 if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
609 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
613 static int icom_write(struct uart_port *port)
615 unsigned long data_count;
616 unsigned char cmdReg;
617 unsigned long offset;
618 int temp_tail = port->info->xmit.tail;
620 trace(ICOM_PORT, "WRITE", 0);
622 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
623 SA_FLAGS_READY_TO_XMIT) {
624 trace(ICOM_PORT, "WRITE_FULL", 0);
625 return 0;
628 data_count = 0;
629 while ((port->info->xmit.head != temp_tail) &&
630 (data_count <= XMIT_BUFF_SZ)) {
632 ICOM_PORT->xmit_buf[data_count++] =
633 port->info->xmit.buf[temp_tail];
635 temp_tail++;
636 temp_tail &= (UART_XMIT_SIZE - 1);
639 if (data_count) {
640 ICOM_PORT->statStg->xmit[0].flags =
641 cpu_to_le16(SA_FLAGS_READY_TO_XMIT);
642 ICOM_PORT->statStg->xmit[0].leLength =
643 cpu_to_le16(data_count);
644 offset =
645 (unsigned long) &ICOM_PORT->statStg->xmit[0] -
646 (unsigned long) ICOM_PORT->statStg;
647 *ICOM_PORT->xmitRestart =
648 cpu_to_le32(ICOM_PORT->statStg_pci + offset);
649 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
650 writeb(cmdReg | CMD_XMIT_RCV_ENABLE,
651 &ICOM_PORT->dram->CmdReg);
652 writeb(START_XMIT, &ICOM_PORT->dram->StartXmitCmd);
653 trace(ICOM_PORT, "WRITE_START", data_count);
654 /* write flush */
655 readb(&ICOM_PORT->dram->StartXmitCmd);
658 return data_count;
661 static inline void check_modem_status(struct icom_port *icom_port)
663 static char old_status = 0;
664 char delta_status;
665 unsigned char status;
667 spin_lock(&icom_port->uart_port.lock);
669 /*modem input register */
670 status = readb(&icom_port->dram->isr);
671 trace(icom_port, "CHECK_MODEM", status);
672 delta_status = status ^ old_status;
673 if (delta_status) {
674 if (delta_status & ICOM_RI)
675 icom_port->uart_port.icount.rng++;
676 if (delta_status & ICOM_DSR)
677 icom_port->uart_port.icount.dsr++;
678 if (delta_status & ICOM_DCD)
679 uart_handle_dcd_change(&icom_port->uart_port,
680 delta_status & ICOM_DCD);
681 if (delta_status & ICOM_CTS)
682 uart_handle_cts_change(&icom_port->uart_port,
683 delta_status & ICOM_CTS);
685 wake_up_interruptible(&icom_port->uart_port.info->
686 delta_msr_wait);
687 old_status = status;
689 spin_unlock(&icom_port->uart_port.lock);
692 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
694 unsigned short int count;
695 int i;
697 if (port_int_reg & (INT_XMIT_COMPLETED)) {
698 trace(icom_port, "XMIT_COMPLETE", 0);
700 /* clear buffer in use bit */
701 icom_port->statStg->xmit[0].flags &=
702 cpu_to_le16(~SA_FLAGS_READY_TO_XMIT);
704 count = (unsigned short int)
705 cpu_to_le16(icom_port->statStg->xmit[0].leLength);
706 icom_port->uart_port.icount.tx += count;
708 for (i=0; i<count &&
709 !uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
711 icom_port->uart_port.info->xmit.tail++;
712 icom_port->uart_port.info->xmit.tail &=
713 (UART_XMIT_SIZE - 1);
716 if (!icom_write(&icom_port->uart_port))
717 /* activate write queue */
718 uart_write_wakeup(&icom_port->uart_port);
719 } else
720 trace(icom_port, "XMIT_DISABLED", 0);
723 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
725 short int count, rcv_buff;
726 struct tty_struct *tty = icom_port->uart_port.info->tty;
727 unsigned short int status;
728 struct uart_icount *icount;
729 unsigned long offset;
730 unsigned char flag;
732 trace(icom_port, "RCV_COMPLETE", 0);
733 rcv_buff = icom_port->next_rcv;
735 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
736 while (status & SA_FL_RCV_DONE) {
737 int first = -1;
739 trace(icom_port, "FID_STATUS", status);
740 count = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].leLength);
742 count = tty_buffer_request_room(tty, count);
743 trace(icom_port, "RCV_COUNT", count);
745 trace(icom_port, "REAL_COUNT", count);
747 offset =
748 cpu_to_le32(icom_port->statStg->rcv[rcv_buff].leBuffer) -
749 icom_port->recv_buf_pci;
751 /* Block copy all but the last byte as this may have status */
752 if (count > 0) {
753 first = icom_port->recv_buf[offset];
754 tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1);
757 icount = &icom_port->uart_port.icount;
758 icount->rx += count;
760 /* Break detect logic */
761 if ((status & SA_FLAGS_FRAME_ERROR)
762 && first == 0) {
763 status &= ~SA_FLAGS_FRAME_ERROR;
764 status |= SA_FLAGS_BREAK_DET;
765 trace(icom_port, "BREAK_DET", 0);
768 flag = TTY_NORMAL;
770 if (status &
771 (SA_FLAGS_BREAK_DET | SA_FLAGS_PARITY_ERROR |
772 SA_FLAGS_FRAME_ERROR | SA_FLAGS_OVERRUN)) {
774 if (status & SA_FLAGS_BREAK_DET)
775 icount->brk++;
776 if (status & SA_FLAGS_PARITY_ERROR)
777 icount->parity++;
778 if (status & SA_FLAGS_FRAME_ERROR)
779 icount->frame++;
780 if (status & SA_FLAGS_OVERRUN)
781 icount->overrun++;
784 * Now check to see if character should be
785 * ignored, and mask off conditions which
786 * should be ignored.
788 if (status & icom_port->ignore_status_mask) {
789 trace(icom_port, "IGNORE_CHAR", 0);
790 goto ignore_char;
793 status &= icom_port->read_status_mask;
795 if (status & SA_FLAGS_BREAK_DET) {
796 flag = TTY_BREAK;
797 } else if (status & SA_FLAGS_PARITY_ERROR) {
798 trace(icom_port, "PARITY_ERROR", 0);
799 flag = TTY_PARITY;
800 } else if (status & SA_FLAGS_FRAME_ERROR)
801 flag = TTY_FRAME;
805 tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag);
807 if (status & SA_FLAGS_OVERRUN)
809 * Overrun is special, since it's
810 * reported immediately, and doesn't
811 * affect the current character
813 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
814 ignore_char:
815 icom_port->statStg->rcv[rcv_buff].flags = 0;
816 icom_port->statStg->rcv[rcv_buff].leLength = 0;
817 icom_port->statStg->rcv[rcv_buff].WorkingLength =
818 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
820 rcv_buff++;
821 if (rcv_buff == NUM_RBUFFS)
822 rcv_buff = 0;
824 status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags);
826 icom_port->next_rcv = rcv_buff;
827 tty_flip_buffer_push(tty);
830 static void process_interrupt(u16 port_int_reg,
831 struct icom_port *icom_port)
834 spin_lock(&icom_port->uart_port.lock);
835 trace(icom_port, "INTERRUPT", port_int_reg);
837 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED))
838 xmit_interrupt(port_int_reg, icom_port);
840 if (port_int_reg & INT_RCV_COMPLETED)
841 recv_interrupt(port_int_reg, icom_port);
843 spin_unlock(&icom_port->uart_port.lock);
846 static irqreturn_t icom_interrupt(int irq, void *dev_id)
848 void __iomem * int_reg;
849 u32 adapter_interrupts;
850 u16 port_int_reg;
851 struct icom_adapter *icom_adapter;
852 struct icom_port *icom_port;
854 /* find icom_port for this interrupt */
855 icom_adapter = (struct icom_adapter *) dev_id;
857 if ((icom_adapter->version | ADAPTER_V2) == ADAPTER_V2) {
858 int_reg = icom_adapter->base_addr + 0x8024;
860 adapter_interrupts = readl(int_reg);
862 if (adapter_interrupts & 0x00003FFF) {
863 /* port 2 interrupt, NOTE: for all ADAPTER_V2, port 2 will be active */
864 icom_port = &icom_adapter->port_info[2];
865 port_int_reg = (u16) adapter_interrupts;
866 process_interrupt(port_int_reg, icom_port);
867 check_modem_status(icom_port);
869 if (adapter_interrupts & 0x3FFF0000) {
870 /* port 3 interrupt */
871 icom_port = &icom_adapter->port_info[3];
872 if (icom_port->status == ICOM_PORT_ACTIVE) {
873 port_int_reg =
874 (u16) (adapter_interrupts >> 16);
875 process_interrupt(port_int_reg, icom_port);
876 check_modem_status(icom_port);
880 /* Clear out any pending interrupts */
881 writel(adapter_interrupts, int_reg);
883 int_reg = icom_adapter->base_addr + 0x8004;
884 } else {
885 int_reg = icom_adapter->base_addr + 0x4004;
888 adapter_interrupts = readl(int_reg);
890 if (adapter_interrupts & 0x00003FFF) {
891 /* port 0 interrupt, NOTE: for all adapters, port 0 will be active */
892 icom_port = &icom_adapter->port_info[0];
893 port_int_reg = (u16) adapter_interrupts;
894 process_interrupt(port_int_reg, icom_port);
895 check_modem_status(icom_port);
897 if (adapter_interrupts & 0x3FFF0000) {
898 /* port 1 interrupt */
899 icom_port = &icom_adapter->port_info[1];
900 if (icom_port->status == ICOM_PORT_ACTIVE) {
901 port_int_reg = (u16) (adapter_interrupts >> 16);
902 process_interrupt(port_int_reg, icom_port);
903 check_modem_status(icom_port);
907 /* Clear out any pending interrupts */
908 writel(adapter_interrupts, int_reg);
910 /* flush the write */
911 adapter_interrupts = readl(int_reg);
913 return IRQ_HANDLED;
917 * ------------------------------------------------------------------
918 * Begin serial-core API
919 * ------------------------------------------------------------------
921 static unsigned int icom_tx_empty(struct uart_port *port)
923 int ret;
924 unsigned long flags;
926 spin_lock_irqsave(&port->lock, flags);
927 if (cpu_to_le16(ICOM_PORT->statStg->xmit[0].flags) &
928 SA_FLAGS_READY_TO_XMIT)
929 ret = TIOCSER_TEMT;
930 else
931 ret = 0;
933 spin_unlock_irqrestore(&port->lock, flags);
934 return ret;
937 static void icom_set_mctrl(struct uart_port *port, unsigned int mctrl)
939 unsigned char local_osr;
941 trace(ICOM_PORT, "SET_MODEM", 0);
942 local_osr = readb(&ICOM_PORT->dram->osr);
944 if (mctrl & TIOCM_RTS) {
945 trace(ICOM_PORT, "RAISE_RTS", 0);
946 local_osr |= ICOM_RTS;
947 } else {
948 trace(ICOM_PORT, "LOWER_RTS", 0);
949 local_osr &= ~ICOM_RTS;
952 if (mctrl & TIOCM_DTR) {
953 trace(ICOM_PORT, "RAISE_DTR", 0);
954 local_osr |= ICOM_DTR;
955 } else {
956 trace(ICOM_PORT, "LOWER_DTR", 0);
957 local_osr &= ~ICOM_DTR;
960 writeb(local_osr, &ICOM_PORT->dram->osr);
963 static unsigned int icom_get_mctrl(struct uart_port *port)
965 unsigned char status;
966 unsigned int result;
968 trace(ICOM_PORT, "GET_MODEM", 0);
970 status = readb(&ICOM_PORT->dram->isr);
972 result = ((status & ICOM_DCD) ? TIOCM_CAR : 0)
973 | ((status & ICOM_RI) ? TIOCM_RNG : 0)
974 | ((status & ICOM_DSR) ? TIOCM_DSR : 0)
975 | ((status & ICOM_CTS) ? TIOCM_CTS : 0);
976 return result;
979 static void icom_stop_tx(struct uart_port *port)
981 unsigned char cmdReg;
983 trace(ICOM_PORT, "STOP", 0);
984 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
985 writeb(cmdReg | CMD_HOLD_XMIT, &ICOM_PORT->dram->CmdReg);
988 static void icom_start_tx(struct uart_port *port)
990 unsigned char cmdReg;
992 trace(ICOM_PORT, "START", 0);
993 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
994 if ((cmdReg & CMD_HOLD_XMIT) == CMD_HOLD_XMIT)
995 writeb(cmdReg & ~CMD_HOLD_XMIT,
996 &ICOM_PORT->dram->CmdReg);
998 icom_write(port);
1001 static void icom_send_xchar(struct uart_port *port, char ch)
1003 unsigned char xdata;
1004 int index;
1005 unsigned long flags;
1007 trace(ICOM_PORT, "SEND_XCHAR", ch);
1009 /* wait .1 sec to send char */
1010 for (index = 0; index < 10; index++) {
1011 spin_lock_irqsave(&port->lock, flags);
1012 xdata = readb(&ICOM_PORT->dram->xchar);
1013 if (xdata == 0x00) {
1014 trace(ICOM_PORT, "QUICK_WRITE", 0);
1015 writeb(ch, &ICOM_PORT->dram->xchar);
1017 /* flush write operation */
1018 xdata = readb(&ICOM_PORT->dram->xchar);
1019 spin_unlock_irqrestore(&port->lock, flags);
1020 break;
1022 spin_unlock_irqrestore(&port->lock, flags);
1023 msleep(10);
1027 static void icom_stop_rx(struct uart_port *port)
1029 unsigned char cmdReg;
1031 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1032 writeb(cmdReg & ~CMD_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1035 static void icom_enable_ms(struct uart_port *port)
1037 /* no-op */
1040 static void icom_break(struct uart_port *port, int break_state)
1042 unsigned char cmdReg;
1043 unsigned long flags;
1045 spin_lock_irqsave(&port->lock, flags);
1046 trace(ICOM_PORT, "BREAK", 0);
1047 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1048 if (break_state == -1) {
1049 writeb(cmdReg | CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1050 } else {
1051 writeb(cmdReg & ~CMD_SND_BREAK, &ICOM_PORT->dram->CmdReg);
1053 spin_unlock_irqrestore(&port->lock, flags);
1056 static int icom_open(struct uart_port *port)
1058 int retval;
1060 kobject_get(&ICOM_PORT->adapter->kobj);
1061 retval = startup(ICOM_PORT);
1063 if (retval) {
1064 kobject_put(&ICOM_PORT->adapter->kobj);
1065 trace(ICOM_PORT, "STARTUP_ERROR", 0);
1066 return retval;
1069 return 0;
1072 static void icom_close(struct uart_port *port)
1074 unsigned char cmdReg;
1076 trace(ICOM_PORT, "CLOSE", 0);
1078 /* stop receiver */
1079 cmdReg = readb(&ICOM_PORT->dram->CmdReg);
1080 writeb(cmdReg & (unsigned char) ~CMD_RCV_ENABLE,
1081 &ICOM_PORT->dram->CmdReg);
1083 shutdown(ICOM_PORT);
1085 kobject_put(&ICOM_PORT->adapter->kobj);
1088 static void icom_set_termios(struct uart_port *port,
1089 struct ktermios *termios,
1090 struct ktermios *old_termios)
1092 int baud;
1093 unsigned cflag, iflag;
1094 int bits;
1095 char new_config2;
1096 char new_config3 = 0;
1097 char tmp_byte;
1098 int index;
1099 int rcv_buff, xmit_buff;
1100 unsigned long offset;
1101 unsigned long flags;
1103 spin_lock_irqsave(&port->lock, flags);
1104 trace(ICOM_PORT, "CHANGE_SPEED", 0);
1106 cflag = termios->c_cflag;
1107 iflag = termios->c_iflag;
1109 new_config2 = ICOM_ACFG_DRIVE1;
1111 /* byte size and parity */
1112 switch (cflag & CSIZE) {
1113 case CS5: /* 5 bits/char */
1114 new_config2 |= ICOM_ACFG_5BPC;
1115 bits = 7;
1116 break;
1117 case CS6: /* 6 bits/char */
1118 new_config2 |= ICOM_ACFG_6BPC;
1119 bits = 8;
1120 break;
1121 case CS7: /* 7 bits/char */
1122 new_config2 |= ICOM_ACFG_7BPC;
1123 bits = 9;
1124 break;
1125 case CS8: /* 8 bits/char */
1126 new_config2 |= ICOM_ACFG_8BPC;
1127 bits = 10;
1128 break;
1129 default:
1130 bits = 10;
1131 break;
1133 if (cflag & CSTOPB) {
1134 /* 2 stop bits */
1135 new_config2 |= ICOM_ACFG_2STOP_BIT;
1136 bits++;
1138 if (cflag & PARENB) {
1139 /* parity bit enabled */
1140 new_config2 |= ICOM_ACFG_PARITY_ENAB;
1141 trace(ICOM_PORT, "PARENB", 0);
1142 bits++;
1144 if (cflag & PARODD) {
1145 /* odd parity */
1146 new_config2 |= ICOM_ACFG_PARITY_ODD;
1147 trace(ICOM_PORT, "PARODD", 0);
1150 /* Determine divisor based on baud rate */
1151 baud = uart_get_baud_rate(port, termios, old_termios,
1152 icom_acfg_baud[0],
1153 icom_acfg_baud[BAUD_TABLE_LIMIT]);
1154 if (!baud)
1155 baud = 9600; /* B0 transition handled in rs_set_termios */
1157 for (index = 0; index < BAUD_TABLE_LIMIT; index++) {
1158 if (icom_acfg_baud[index] == baud) {
1159 new_config3 = index;
1160 break;
1164 uart_update_timeout(port, cflag, baud);
1166 /* CTS flow control flag and modem status interrupts */
1167 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1168 if (cflag & CRTSCTS)
1169 tmp_byte |= HDLC_HDW_FLOW;
1170 else
1171 tmp_byte &= ~HDLC_HDW_FLOW;
1172 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1175 * Set up parity check flag
1177 ICOM_PORT->read_status_mask = SA_FLAGS_OVERRUN | SA_FL_RCV_DONE;
1178 if (iflag & INPCK)
1179 ICOM_PORT->read_status_mask |=
1180 SA_FLAGS_FRAME_ERROR | SA_FLAGS_PARITY_ERROR;
1182 if ((iflag & BRKINT) || (iflag & PARMRK))
1183 ICOM_PORT->read_status_mask |= SA_FLAGS_BREAK_DET;
1186 * Characters to ignore
1188 ICOM_PORT->ignore_status_mask = 0;
1189 if (iflag & IGNPAR)
1190 ICOM_PORT->ignore_status_mask |=
1191 SA_FLAGS_PARITY_ERROR | SA_FLAGS_FRAME_ERROR;
1192 if (iflag & IGNBRK) {
1193 ICOM_PORT->ignore_status_mask |= SA_FLAGS_BREAK_DET;
1195 * If we're ignore parity and break indicators, ignore
1196 * overruns too. (For real raw support).
1198 if (iflag & IGNPAR)
1199 ICOM_PORT->ignore_status_mask |= SA_FLAGS_OVERRUN;
1203 * !!! ignore all characters if CREAD is not set
1205 if ((cflag & CREAD) == 0)
1206 ICOM_PORT->ignore_status_mask |= SA_FL_RCV_DONE;
1208 /* Turn off Receiver to prepare for reset */
1209 writeb(CMD_RCV_DISABLE, &ICOM_PORT->dram->CmdReg);
1211 for (index = 0; index < 10; index++) {
1212 if (readb(&ICOM_PORT->dram->PrevCmdReg) == 0x00) {
1213 break;
1217 /* clear all current buffers of data */
1218 for (rcv_buff = 0; rcv_buff < NUM_RBUFFS; rcv_buff++) {
1219 ICOM_PORT->statStg->rcv[rcv_buff].flags = 0;
1220 ICOM_PORT->statStg->rcv[rcv_buff].leLength = 0;
1221 ICOM_PORT->statStg->rcv[rcv_buff].WorkingLength =
1222 (unsigned short int) cpu_to_le16(RCV_BUFF_SZ);
1225 for (xmit_buff = 0; xmit_buff < NUM_XBUFFS; xmit_buff++) {
1226 ICOM_PORT->statStg->xmit[xmit_buff].flags = 0;
1229 /* activate changes and start xmit and receiver here */
1230 /* Enable the receiver */
1231 writeb(new_config3, &(ICOM_PORT->dram->async_config3));
1232 writeb(new_config2, &(ICOM_PORT->dram->async_config2));
1233 tmp_byte = readb(&(ICOM_PORT->dram->HDLCConfigReg));
1234 tmp_byte |= HDLC_PPP_PURE_ASYNC | HDLC_FF_FILL;
1235 writeb(tmp_byte, &(ICOM_PORT->dram->HDLCConfigReg));
1236 writeb(0x04, &(ICOM_PORT->dram->FlagFillIdleTimer)); /* 0.5 seconds */
1237 writeb(0xFF, &(ICOM_PORT->dram->ier)); /* enable modem signal interrupts */
1239 /* reset processor */
1240 writeb(CMD_RESTART, &ICOM_PORT->dram->CmdReg);
1242 for (index = 0; index < 10; index++) {
1243 if (readb(&ICOM_PORT->dram->CmdReg) == 0x00) {
1244 break;
1248 /* Enable Transmitter and Reciever */
1249 offset =
1250 (unsigned long) &ICOM_PORT->statStg->rcv[0] -
1251 (unsigned long) ICOM_PORT->statStg;
1252 writel(ICOM_PORT->statStg_pci + offset,
1253 &ICOM_PORT->dram->RcvStatusAddr);
1254 ICOM_PORT->next_rcv = 0;
1255 ICOM_PORT->put_length = 0;
1256 *ICOM_PORT->xmitRestart = 0;
1257 writel(ICOM_PORT->xmitRestart_pci,
1258 &ICOM_PORT->dram->XmitStatusAddr);
1259 trace(ICOM_PORT, "XR_ENAB", 0);
1260 writeb(CMD_XMIT_RCV_ENABLE, &ICOM_PORT->dram->CmdReg);
1262 spin_unlock_irqrestore(&port->lock, flags);
1265 static const char *icom_type(struct uart_port *port)
1267 return "icom";
1270 static void icom_release_port(struct uart_port *port)
1274 static int icom_request_port(struct uart_port *port)
1276 return 0;
1279 static void icom_config_port(struct uart_port *port, int flags)
1281 port->type = PORT_ICOM;
1284 static struct uart_ops icom_ops = {
1285 .tx_empty = icom_tx_empty,
1286 .set_mctrl = icom_set_mctrl,
1287 .get_mctrl = icom_get_mctrl,
1288 .stop_tx = icom_stop_tx,
1289 .start_tx = icom_start_tx,
1290 .send_xchar = icom_send_xchar,
1291 .stop_rx = icom_stop_rx,
1292 .enable_ms = icom_enable_ms,
1293 .break_ctl = icom_break,
1294 .startup = icom_open,
1295 .shutdown = icom_close,
1296 .set_termios = icom_set_termios,
1297 .type = icom_type,
1298 .release_port = icom_release_port,
1299 .request_port = icom_request_port,
1300 .config_port = icom_config_port,
1303 #define ICOM_CONSOLE NULL
1305 static struct uart_driver icom_uart_driver = {
1306 .owner = THIS_MODULE,
1307 .driver_name = ICOM_DRIVER_NAME,
1308 .dev_name = "ttyA",
1309 .major = ICOM_MAJOR,
1310 .minor = ICOM_MINOR_START,
1311 .nr = NR_PORTS,
1312 .cons = ICOM_CONSOLE,
1315 static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
1317 u32 subsystem_id = icom_adapter->subsystem_id;
1318 int retval = 0;
1319 int i;
1320 struct icom_port *icom_port;
1322 if (icom_adapter->version == ADAPTER_V1) {
1323 icom_adapter->numb_ports = 2;
1325 for (i = 0; i < 2; i++) {
1326 icom_port = &icom_adapter->port_info[i];
1327 icom_port->port = i;
1328 icom_port->status = ICOM_PORT_ACTIVE;
1329 icom_port->imbed_modem = ICOM_UNKNOWN;
1331 } else {
1332 if (subsystem_id == PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL) {
1333 icom_adapter->numb_ports = 4;
1335 for (i = 0; i < 4; i++) {
1336 icom_port = &icom_adapter->port_info[i];
1338 icom_port->port = i;
1339 icom_port->status = ICOM_PORT_ACTIVE;
1340 icom_port->imbed_modem = ICOM_IMBED_MODEM;
1342 } else {
1343 icom_adapter->numb_ports = 4;
1345 icom_adapter->port_info[0].port = 0;
1346 icom_adapter->port_info[0].status = ICOM_PORT_ACTIVE;
1348 if (subsystem_id ==
1349 PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM) {
1350 icom_adapter->port_info[0].imbed_modem = ICOM_IMBED_MODEM;
1351 } else {
1352 icom_adapter->port_info[0].imbed_modem = ICOM_RVX;
1355 icom_adapter->port_info[1].status = ICOM_PORT_OFF;
1357 icom_adapter->port_info[2].port = 2;
1358 icom_adapter->port_info[2].status = ICOM_PORT_ACTIVE;
1359 icom_adapter->port_info[2].imbed_modem = ICOM_RVX;
1360 icom_adapter->port_info[3].status = ICOM_PORT_OFF;
1364 return retval;
1367 static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
1369 if (icom_adapter->version == ADAPTER_V1) {
1370 icom_port->global_reg = icom_adapter->base_addr + 0x4000;
1371 icom_port->int_reg = icom_adapter->base_addr +
1372 0x4004 + 2 - 2 * port_num;
1373 } else {
1374 icom_port->global_reg = icom_adapter->base_addr + 0x8000;
1375 if (icom_port->port < 2)
1376 icom_port->int_reg = icom_adapter->base_addr +
1377 0x8004 + 2 - 2 * icom_port->port;
1378 else
1379 icom_port->int_reg = icom_adapter->base_addr +
1380 0x8024 + 2 - 2 * (icom_port->port - 2);
1383 static int __init icom_load_ports(struct icom_adapter *icom_adapter)
1385 struct icom_port *icom_port;
1386 int port_num;
1387 int retval;
1389 for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
1391 icom_port = &icom_adapter->port_info[port_num];
1393 if (icom_port->status == ICOM_PORT_ACTIVE) {
1394 icom_port_active(icom_port, icom_adapter, port_num);
1395 icom_port->dram = icom_adapter->base_addr +
1396 0x2000 * icom_port->port;
1398 icom_port->adapter = icom_adapter;
1400 /* get port memory */
1401 if ((retval = get_port_memory(icom_port)) != 0) {
1402 dev_err(&icom_port->adapter->pci_dev->dev,
1403 "Memory allocation for port FAILED\n");
1407 return 0;
1410 static int __devinit icom_alloc_adapter(struct icom_adapter
1411 **icom_adapter_ref)
1413 int adapter_count = 0;
1414 struct icom_adapter *icom_adapter;
1415 struct icom_adapter *cur_adapter_entry;
1416 struct list_head *tmp;
1418 icom_adapter = (struct icom_adapter *)
1419 kzalloc(sizeof(struct icom_adapter), GFP_KERNEL);
1421 if (!icom_adapter) {
1422 return -ENOMEM;
1425 list_for_each(tmp, &icom_adapter_head) {
1426 cur_adapter_entry =
1427 list_entry(tmp, struct icom_adapter,
1428 icom_adapter_entry);
1429 if (cur_adapter_entry->index != adapter_count) {
1430 break;
1432 adapter_count++;
1435 icom_adapter->index = adapter_count;
1436 list_add_tail(&icom_adapter->icom_adapter_entry, tmp);
1438 *icom_adapter_ref = icom_adapter;
1439 return 0;
1442 static void icom_free_adapter(struct icom_adapter *icom_adapter)
1444 list_del(&icom_adapter->icom_adapter_entry);
1445 kfree(icom_adapter);
1448 static void icom_remove_adapter(struct icom_adapter *icom_adapter)
1450 struct icom_port *icom_port;
1451 int index;
1453 for (index = 0; index < icom_adapter->numb_ports; index++) {
1454 icom_port = &icom_adapter->port_info[index];
1456 if (icom_port->status == ICOM_PORT_ACTIVE) {
1457 dev_info(&icom_adapter->pci_dev->dev,
1458 "Device removed\n");
1460 uart_remove_one_port(&icom_uart_driver,
1461 &icom_port->uart_port);
1463 /* be sure that DTR and RTS are dropped */
1464 writeb(0x00, &icom_port->dram->osr);
1466 /* Wait 0.1 Sec for simple Init to complete */
1467 msleep(100);
1469 /* Stop proccessor */
1470 stop_processor(icom_port);
1472 free_port_memory(icom_port);
1476 free_irq(icom_adapter->irq_number, (void *) icom_adapter);
1477 iounmap(icom_adapter->base_addr);
1478 icom_free_adapter(icom_adapter);
1479 pci_release_regions(icom_adapter->pci_dev);
1482 static void icom_kobj_release(struct kobject *kobj)
1484 struct icom_adapter *icom_adapter;
1486 icom_adapter = to_icom_adapter(kobj);
1487 icom_remove_adapter(icom_adapter);
1490 static struct kobj_type icom_kobj_type = {
1491 .release = icom_kobj_release,
1494 static int __devinit icom_probe(struct pci_dev *dev,
1495 const struct pci_device_id *ent)
1497 int index;
1498 unsigned int command_reg;
1499 int retval;
1500 struct icom_adapter *icom_adapter;
1501 struct icom_port *icom_port;
1503 retval = pci_enable_device(dev);
1504 if (retval) {
1505 dev_err(&dev->dev, "Device enable FAILED\n");
1506 return retval;
1509 if ( (retval = pci_request_regions(dev, "icom"))) {
1510 dev_err(&dev->dev, "pci_request_regions FAILED\n");
1511 pci_disable_device(dev);
1512 return retval;
1515 pci_set_master(dev);
1517 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1518 dev_err(&dev->dev, "PCI Config read FAILED\n");
1519 return retval;
1522 pci_write_config_dword(dev, PCI_COMMAND,
1523 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1524 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1526 if (ent->driver_data == ADAPTER_V1) {
1527 pci_write_config_dword(dev, 0x44, 0x8300830A);
1528 } else {
1529 pci_write_config_dword(dev, 0x44, 0x42004200);
1530 pci_write_config_dword(dev, 0x48, 0x42004200);
1534 retval = icom_alloc_adapter(&icom_adapter);
1535 if (retval) {
1536 dev_err(&dev->dev, "icom_alloc_adapter FAILED\n");
1537 retval = -EIO;
1538 goto probe_exit0;
1541 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1542 icom_adapter->irq_number = dev->irq;
1543 icom_adapter->pci_dev = dev;
1544 icom_adapter->version = ent->driver_data;
1545 icom_adapter->subsystem_id = ent->subdevice;
1548 retval = icom_init_ports(icom_adapter);
1549 if (retval) {
1550 dev_err(&dev->dev, "Port configuration failed\n");
1551 goto probe_exit1;
1554 icom_adapter->base_addr = ioremap(icom_adapter->base_addr_pci,
1555 pci_resource_len(dev, 0));
1557 if (!icom_adapter->base_addr)
1558 goto probe_exit1;
1560 /* save off irq and request irq line */
1561 if ( (retval = request_irq(dev->irq, icom_interrupt,
1562 IRQF_DISABLED | IRQF_SHARED, ICOM_DRIVER_NAME,
1563 (void *) icom_adapter))) {
1564 goto probe_exit2;
1567 retval = icom_load_ports(icom_adapter);
1569 for (index = 0; index < icom_adapter->numb_ports; index++) {
1570 icom_port = &icom_adapter->port_info[index];
1572 if (icom_port->status == ICOM_PORT_ACTIVE) {
1573 icom_port->uart_port.irq = icom_port->adapter->irq_number;
1574 icom_port->uart_port.type = PORT_ICOM;
1575 icom_port->uart_port.iotype = UPIO_MEM;
1576 icom_port->uart_port.membase =
1577 (char *) icom_adapter->base_addr_pci;
1578 icom_port->uart_port.fifosize = 16;
1579 icom_port->uart_port.ops = &icom_ops;
1580 icom_port->uart_port.line =
1581 icom_port->port + icom_adapter->index * 4;
1582 if (uart_add_one_port (&icom_uart_driver, &icom_port->uart_port)) {
1583 icom_port->status = ICOM_PORT_OFF;
1584 dev_err(&dev->dev, "Device add failed\n");
1585 } else
1586 dev_info(&dev->dev, "Device added\n");
1590 kobject_init(&icom_adapter->kobj);
1591 icom_adapter->kobj.ktype = &icom_kobj_type;
1592 return 0;
1594 probe_exit2:
1595 iounmap(icom_adapter->base_addr);
1596 probe_exit1:
1597 icom_free_adapter(icom_adapter);
1599 probe_exit0:
1600 pci_release_regions(dev);
1601 pci_disable_device(dev);
1603 return retval;
1608 static void __devexit icom_remove(struct pci_dev *dev)
1610 struct icom_adapter *icom_adapter;
1611 struct list_head *tmp;
1613 list_for_each(tmp, &icom_adapter_head) {
1614 icom_adapter = list_entry(tmp, struct icom_adapter,
1615 icom_adapter_entry);
1616 if (icom_adapter->pci_dev == dev) {
1617 kobject_put(&icom_adapter->kobj);
1618 return;
1622 dev_err(&dev->dev, "Unable to find device to remove\n");
1625 static struct pci_driver icom_pci_driver = {
1626 .name = ICOM_DRIVER_NAME,
1627 .id_table = icom_pci_table,
1628 .probe = icom_probe,
1629 .remove = __devexit_p(icom_remove),
1632 static int __init icom_init(void)
1634 int ret;
1636 spin_lock_init(&icom_lock);
1638 ret = uart_register_driver(&icom_uart_driver);
1639 if (ret)
1640 return ret;
1642 ret = pci_register_driver(&icom_pci_driver);
1644 if (ret < 0)
1645 uart_unregister_driver(&icom_uart_driver);
1647 return ret;
1650 static void __exit icom_exit(void)
1652 pci_unregister_driver(&icom_pci_driver);
1653 uart_unregister_driver(&icom_uart_driver);
1656 module_init(icom_init);
1657 module_exit(icom_exit);
1659 #ifdef ICOM_TRACE
1660 static inline void trace(struct icom_port *icom_port, char *trace_pt,
1661 unsigned long trace_data)
1663 dev_info(&icom_port->adapter->pci_dev->dev, ":%d:%s - %lx\n",
1664 icom_port->port, trace_pt, trace_data);
1666 #endif
1668 MODULE_AUTHOR("Michael Anderson <mjanders@us.ibm.com>");
1669 MODULE_DESCRIPTION("IBM iSeries Serial IOA driver");
1670 MODULE_SUPPORTED_DEVICE
1671 ("IBM iSeries 2745, 2771, 2772, 2742, 2793 and 2805 Communications adapters");
1672 MODULE_LICENSE("GPL");