Lines Matching +full:disable +full:- +full:dc
1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
3 * nozomi.c -- HSDPA driver Broadband Wireless Data Card - Globe Trotter
18 * --------------------------------------------------------------------------
25 * --------------------------------------------------------------------------
132 F32_2 = 2048, /* 512 bytes downlink + uplink * 2 -> 2048 */
133 F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */
157 CTRL_ERROR = -1,
167 PORT_ERROR = -1,
176 * else A-channels must always be used.
246 * else A-channels must always be used.
315 struct nozomi *dc; member
360 return tty ? ndevs[tty->index / MAX_PORT] : NULL; in get_dc_by_tty()
366 return ndev ? &ndev->port[tty->index % MAX_PORT] : NULL; in get_port_by_tty()
371 * -Optimize
372 * -Rewrite cleaner
397 if (size_bytes - i == 2) { in read_mem32()
416 * -Optimize
417 * -Rewrite cleaner
446 if (size_bytes - i == 2) { in write_mem32()
463 static void nozomi_setup_memory(struct nozomi *dc) in nozomi_setup_memory() argument
465 void __iomem *offset = dc->base_addr + dc->config_table.dl_start; in nozomi_setup_memory()
472 dc->port[PORT_MDM].dl_addr[CH_A] = offset; in nozomi_setup_memory()
473 dc->port[PORT_MDM].dl_addr[CH_B] = in nozomi_setup_memory()
474 (offset += dc->config_table.dl_mdm_len1); in nozomi_setup_memory()
475 dc->port[PORT_MDM].dl_size[CH_A] = in nozomi_setup_memory()
476 dc->config_table.dl_mdm_len1 - buff_offset; in nozomi_setup_memory()
477 dc->port[PORT_MDM].dl_size[CH_B] = in nozomi_setup_memory()
478 dc->config_table.dl_mdm_len2 - buff_offset; in nozomi_setup_memory()
481 dc->port[PORT_DIAG].dl_addr[CH_A] = in nozomi_setup_memory()
482 (offset += dc->config_table.dl_mdm_len2); in nozomi_setup_memory()
483 dc->port[PORT_DIAG].dl_size[CH_A] = in nozomi_setup_memory()
484 dc->config_table.dl_diag_len1 - buff_offset; in nozomi_setup_memory()
485 dc->port[PORT_DIAG].dl_addr[CH_B] = in nozomi_setup_memory()
486 (offset += dc->config_table.dl_diag_len1); in nozomi_setup_memory()
487 dc->port[PORT_DIAG].dl_size[CH_B] = in nozomi_setup_memory()
488 dc->config_table.dl_diag_len2 - buff_offset; in nozomi_setup_memory()
491 dc->port[PORT_APP1].dl_addr[CH_A] = in nozomi_setup_memory()
492 (offset += dc->config_table.dl_diag_len2); in nozomi_setup_memory()
493 dc->port[PORT_APP1].dl_size[CH_A] = in nozomi_setup_memory()
494 dc->config_table.dl_app1_len - buff_offset; in nozomi_setup_memory()
497 dc->port[PORT_APP2].dl_addr[CH_A] = in nozomi_setup_memory()
498 (offset += dc->config_table.dl_app1_len); in nozomi_setup_memory()
499 dc->port[PORT_APP2].dl_size[CH_A] = in nozomi_setup_memory()
500 dc->config_table.dl_app2_len - buff_offset; in nozomi_setup_memory()
503 dc->port[PORT_CTRL].dl_addr[CH_A] = in nozomi_setup_memory()
504 (offset += dc->config_table.dl_app2_len); in nozomi_setup_memory()
505 dc->port[PORT_CTRL].dl_size[CH_A] = in nozomi_setup_memory()
506 dc->config_table.dl_ctrl_len - buff_offset; in nozomi_setup_memory()
508 offset = dc->base_addr + dc->config_table.ul_start; in nozomi_setup_memory()
511 dc->port[PORT_MDM].ul_addr[CH_A] = offset; in nozomi_setup_memory()
512 dc->port[PORT_MDM].ul_size[CH_A] = in nozomi_setup_memory()
513 dc->config_table.ul_mdm_len1 - buff_offset; in nozomi_setup_memory()
514 dc->port[PORT_MDM].ul_addr[CH_B] = in nozomi_setup_memory()
515 (offset += dc->config_table.ul_mdm_len1); in nozomi_setup_memory()
516 dc->port[PORT_MDM].ul_size[CH_B] = in nozomi_setup_memory()
517 dc->config_table.ul_mdm_len2 - buff_offset; in nozomi_setup_memory()
520 dc->port[PORT_DIAG].ul_addr[CH_A] = in nozomi_setup_memory()
521 (offset += dc->config_table.ul_mdm_len2); in nozomi_setup_memory()
522 dc->port[PORT_DIAG].ul_size[CH_A] = in nozomi_setup_memory()
523 dc->config_table.ul_diag_len - buff_offset; in nozomi_setup_memory()
526 dc->port[PORT_APP1].ul_addr[CH_A] = in nozomi_setup_memory()
527 (offset += dc->config_table.ul_diag_len); in nozomi_setup_memory()
528 dc->port[PORT_APP1].ul_size[CH_A] = in nozomi_setup_memory()
529 dc->config_table.ul_app1_len - buff_offset; in nozomi_setup_memory()
532 dc->port[PORT_APP2].ul_addr[CH_A] = in nozomi_setup_memory()
533 (offset += dc->config_table.ul_app1_len); in nozomi_setup_memory()
534 dc->port[PORT_APP2].ul_size[CH_A] = in nozomi_setup_memory()
535 dc->config_table.ul_app2_len - buff_offset; in nozomi_setup_memory()
538 dc->port[PORT_CTRL].ul_addr[CH_A] = in nozomi_setup_memory()
539 (offset += dc->config_table.ul_app2_len); in nozomi_setup_memory()
540 dc->port[PORT_CTRL].ul_size[CH_A] = in nozomi_setup_memory()
541 dc->config_table.ul_ctrl_len - buff_offset; in nozomi_setup_memory()
546 static void dump_table(const struct nozomi *dc) in dump_table() argument
548 DBG3("signature: 0x%08X", dc->config_table.signature); in dump_table()
549 DBG3("version: 0x%04X", dc->config_table.version); in dump_table()
551 dc->config_table.product_information); in dump_table()
552 DBG3("toggle enabled: %d", dc->config_table.toggle.enabled); in dump_table()
553 DBG3("toggle up_mdm: %d", dc->config_table.toggle.mdm_ul); in dump_table()
554 DBG3("toggle dl_mdm: %d", dc->config_table.toggle.mdm_dl); in dump_table()
555 DBG3("toggle dl_dbg: %d", dc->config_table.toggle.diag_dl); in dump_table()
557 DBG3("dl_start: 0x%04X", dc->config_table.dl_start); in dump_table()
558 DBG3("dl_mdm_len0: 0x%04X, %d", dc->config_table.dl_mdm_len1, in dump_table()
559 dc->config_table.dl_mdm_len1); in dump_table()
560 DBG3("dl_mdm_len1: 0x%04X, %d", dc->config_table.dl_mdm_len2, in dump_table()
561 dc->config_table.dl_mdm_len2); in dump_table()
562 DBG3("dl_diag_len0: 0x%04X, %d", dc->config_table.dl_diag_len1, in dump_table()
563 dc->config_table.dl_diag_len1); in dump_table()
564 DBG3("dl_diag_len1: 0x%04X, %d", dc->config_table.dl_diag_len2, in dump_table()
565 dc->config_table.dl_diag_len2); in dump_table()
566 DBG3("dl_app1_len: 0x%04X, %d", dc->config_table.dl_app1_len, in dump_table()
567 dc->config_table.dl_app1_len); in dump_table()
568 DBG3("dl_app2_len: 0x%04X, %d", dc->config_table.dl_app2_len, in dump_table()
569 dc->config_table.dl_app2_len); in dump_table()
570 DBG3("dl_ctrl_len: 0x%04X, %d", dc->config_table.dl_ctrl_len, in dump_table()
571 dc->config_table.dl_ctrl_len); in dump_table()
572 DBG3("ul_start: 0x%04X, %d", dc->config_table.ul_start, in dump_table()
573 dc->config_table.ul_start); in dump_table()
574 DBG3("ul_mdm_len[0]: 0x%04X, %d", dc->config_table.ul_mdm_len1, in dump_table()
575 dc->config_table.ul_mdm_len1); in dump_table()
576 DBG3("ul_mdm_len[1]: 0x%04X, %d", dc->config_table.ul_mdm_len2, in dump_table()
577 dc->config_table.ul_mdm_len2); in dump_table()
578 DBG3("ul_diag_len: 0x%04X, %d", dc->config_table.ul_diag_len, in dump_table()
579 dc->config_table.ul_diag_len); in dump_table()
580 DBG3("ul_app1_len: 0x%04X, %d", dc->config_table.ul_app1_len, in dump_table()
581 dc->config_table.ul_app1_len); in dump_table()
582 DBG3("ul_app2_len: 0x%04X, %d", dc->config_table.ul_app2_len, in dump_table()
583 dc->config_table.ul_app2_len); in dump_table()
584 DBG3("ul_ctrl_len: 0x%04X, %d", dc->config_table.ul_ctrl_len, in dump_table()
585 dc->config_table.ul_ctrl_len); in dump_table()
588 static inline void dump_table(const struct nozomi *dc) { } in dump_table() argument
595 static int nozomi_read_config_table(struct nozomi *dc) in nozomi_read_config_table() argument
597 read_mem32((u32 *) &dc->config_table, dc->base_addr + 0, in nozomi_read_config_table()
600 if (dc->config_table.signature != NOZOMI_CONFIG_MAGIC) { in nozomi_read_config_table()
601 dev_err(&dc->pdev->dev, "ConfigTable Bad! 0x%08X != 0x%08X\n", in nozomi_read_config_table()
602 dc->config_table.signature, NOZOMI_CONFIG_MAGIC); in nozomi_read_config_table()
606 if ((dc->config_table.version == 0) in nozomi_read_config_table()
607 || (dc->config_table.toggle.enabled == TOGGLE_VALID)) { in nozomi_read_config_table()
611 nozomi_setup_memory(dc); in nozomi_read_config_table()
613 dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; in nozomi_read_config_table()
614 dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; in nozomi_read_config_table()
615 dc->port[PORT_DIAG].toggle_dl = dc->config_table.toggle.diag_dl; in nozomi_read_config_table()
617 dc->port[PORT_MDM].toggle_ul, in nozomi_read_config_table()
618 dc->port[PORT_MDM].toggle_dl, dc->port[PORT_DIAG].toggle_dl); in nozomi_read_config_table()
620 dump_table(dc); in nozomi_read_config_table()
623 memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); in nozomi_read_config_table()
624 memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); in nozomi_read_config_table()
628 dc->last_ier = dc->last_ier | CTRL_DL; in nozomi_read_config_table()
629 writew(dc->last_ier, dc->reg_ier); in nozomi_read_config_table()
631 dc->state = NOZOMI_STATE_ALLOCATED; in nozomi_read_config_table()
632 dev_info(&dc->pdev->dev, "Initialization OK!\n"); in nozomi_read_config_table()
636 if ((dc->config_table.version > 0) in nozomi_read_config_table()
637 && (dc->config_table.toggle.enabled != TOGGLE_VALID)) { in nozomi_read_config_table()
641 dev_info(&dc->pdev->dev, "Version of card: %d\n", in nozomi_read_config_table()
642 dc->config_table.version); in nozomi_read_config_table()
644 /* Here we should disable all I/O over F32. */ in nozomi_read_config_table()
645 nozomi_setup_memory(dc); in nozomi_read_config_table()
653 write_mem32(dc->port[PORT_MDM].ul_addr[CH_A], in nozomi_read_config_table()
655 write_mem32(dc->port[PORT_MDM].ul_addr[CH_B], in nozomi_read_config_table()
658 writew(MDM_UL | DIAG_DL | MDM_DL, dc->reg_fcr); in nozomi_read_config_table()
667 static void enable_transmit_ul(enum port_type port, struct nozomi *dc) in enable_transmit_ul() argument
672 dc->last_ier |= mask[port]; in enable_transmit_ul()
673 writew(dc->last_ier, dc->reg_ier); in enable_transmit_ul()
675 dev_err(&dc->pdev->dev, "Called with wrong port?\n"); in enable_transmit_ul()
679 /* Disable uplink interrupts */
680 static void disable_transmit_ul(enum port_type port, struct nozomi *dc) in disable_transmit_ul() argument
686 dc->last_ier &= mask[port]; in disable_transmit_ul()
687 writew(dc->last_ier, dc->reg_ier); in disable_transmit_ul()
689 dev_err(&dc->pdev->dev, "Called with wrong port?\n"); in disable_transmit_ul()
694 static void enable_transmit_dl(enum port_type port, struct nozomi *dc) in enable_transmit_dl() argument
699 dc->last_ier |= mask[port]; in enable_transmit_dl()
700 writew(dc->last_ier, dc->reg_ier); in enable_transmit_dl()
702 dev_err(&dc->pdev->dev, "Called with wrong port?\n"); in enable_transmit_dl()
706 /* Disable downlink interrupts */
707 static void disable_transmit_dl(enum port_type port, struct nozomi *dc) in disable_transmit_dl() argument
713 dc->last_ier &= mask[port]; in disable_transmit_dl()
714 writew(dc->last_ier, dc->reg_ier); in disable_transmit_dl()
716 dev_err(&dc->pdev->dev, "Called with wrong port?\n"); in disable_transmit_dl()
721 * Return 1 - send buffer to card and ack.
722 * Return 0 - don't ack, don't send buffer to card.
724 static int send_data(enum port_type index, struct nozomi *dc) in send_data() argument
727 struct port *port = &dc->port[index]; in send_data()
728 const u8 toggle = port->toggle_ul; in send_data()
729 void __iomem *addr = port->ul_addr[toggle]; in send_data()
730 const u32 ul_size = port->ul_size[toggle]; in send_data()
733 size = kfifo_out(&port->fifo_ul, dc->send_buf, in send_data()
737 DBG4("No more data to send, disable link:"); in send_data()
743 write_mem32(addr + 4, (u32 *) dc->send_buf, size); in send_data()
745 tty_port_tty_wakeup(&port->port); in send_data()
751 static int receive_data(enum port_type index, struct nozomi *dc) in receive_data() argument
756 struct port *port = &dc->port[index]; in receive_data()
757 void __iomem *addr = port->dl_addr[port->toggle_dl]; in receive_data()
758 struct tty_struct *tty = tty_port_tty_get(&port->port); in receive_data()
765 "disable interrupt"); in receive_data()
767 /* disable interrupt in downlink... */ in receive_data()
768 disable_transmit_dl(index, dc); in receive_data()
774 dev_err(&dc->pdev->dev, "size == 0?\n"); in receive_data()
783 tty_insert_flip_char(&port->port, buf[0], TTY_NORMAL); in receive_data()
786 size -= tty_insert_flip_string(&port->port, buf, size); in receive_data()
788 i = tty_insert_flip_string(&port->port, buf, in receive_data()
790 size -= i; in receive_data()
795 set_bit(index, &dc->flip); in receive_data()
812 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "MDM_DL2 "); in interrupt2str()
814 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "MDM_UL1 "); in interrupt2str()
816 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "MDM_UL2 "); in interrupt2str()
818 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "DIAG_DL1 "); in interrupt2str()
820 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "DIAG_DL2 "); in interrupt2str()
823 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "DIAG_UL "); in interrupt2str()
826 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP1_DL "); in interrupt2str()
828 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP2_DL "); in interrupt2str()
831 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP1_UL "); in interrupt2str()
833 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "APP2_UL "); in interrupt2str()
836 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "CTRL_DL "); in interrupt2str()
838 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "CTRL_UL "); in interrupt2str()
841 p += scnprintf(p, TMP_BUF_MAX - (p - buf), "RESET "); in interrupt2str()
849 * Return 1 - If ok, else 0
851 static int receive_flow_control(struct nozomi *dc) in receive_flow_control() argument
858 read_mem32((u32 *) &ctrl_dl, dc->port[PORT_CTRL].dl_addr[CH_A], 2); in receive_flow_control()
881 if (dc->state == NOZOMI_STATE_ALLOCATED) { in receive_flow_control()
886 dc->state = NOZOMI_STATE_READY; in receive_flow_control()
887 dev_info(&dc->pdev->dev, "Device READY!\n"); in receive_flow_control()
891 dev_err(&dc->pdev->dev, in receive_flow_control()
892 "ERROR: flow control received for non-existing port\n"); in receive_flow_control()
896 DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl), in receive_flow_control()
899 old_ctrl = dc->port[port].ctrl_dl; in receive_flow_control()
900 dc->port[port].ctrl_dl = ctrl_dl; in receive_flow_control()
903 DBG1("Disable interrupt (0x%04X) on port: %d", in receive_flow_control()
905 disable_transmit_ul(port, dc); in receive_flow_control()
909 if (kfifo_len(&dc->port[port].fifo_ul)) { in receive_flow_control()
913 kfifo_len(&dc->port[port].fifo_ul)); in receive_flow_control()
914 enable_transmit_ul(port, dc); in receive_flow_control()
926 dc->port[port].tty_icount.cts++; in receive_flow_control()
928 dc->port[port].tty_icount.dsr++; in receive_flow_control()
930 dc->port[port].tty_icount.rng++; in receive_flow_control()
932 dc->port[port].tty_icount.dcd++; in receive_flow_control()
934 wake_up_interruptible(&dc->port[port].tty_wait); in receive_flow_control()
938 dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts, in receive_flow_control()
939 dc->port[port].tty_icount.rng, dc->port[port].tty_icount.dsr); in receive_flow_control()
945 const struct nozomi *dc) in port2ctrl() argument
957 dev_err(&dc->pdev->dev, in port2ctrl()
959 "received for non-existing port\n"); in port2ctrl()
966 * Return 0 - If we have updated all flow control
967 * Return 1 - If we need to update more flow control, ack current enable more
969 static int send_flow_control(struct nozomi *dc) in send_flow_control() argument
975 if (dc->port[i].update_flow_control) { in send_flow_control()
980 dc->port[i].ctrl_ul.port = port2ctrl(i, dc); in send_flow_control()
981 ctrl = (u16 *)&dc->port[i].ctrl_ul; in send_flow_control()
982 write_mem32(dc->port[PORT_CTRL].ul_addr[0], \ in send_flow_control()
984 dc->port[i].update_flow_control = 0; in send_flow_control()
993 * Return 1 - ok
994 * Return 0 - toggle fields are out of sync
996 static int handle_data_dl(struct nozomi *dc, enum port_type port, u8 *toggle, in handle_data_dl() argument
1000 if (receive_data(port, dc)) { in handle_data_dl()
1001 writew(mask1, dc->reg_fcr); in handle_data_dl()
1006 if (receive_data(port, dc)) { in handle_data_dl()
1007 writew(mask2, dc->reg_fcr); in handle_data_dl()
1012 if (receive_data(port, dc)) { in handle_data_dl()
1013 writew(mask2, dc->reg_fcr); in handle_data_dl()
1018 if (receive_data(port, dc)) { in handle_data_dl()
1019 writew(mask1, dc->reg_fcr); in handle_data_dl()
1024 dev_err(&dc->pdev->dev, "port out of sync!, toggle:%d\n", in handle_data_dl()
1033 * Return 1 - ok
1034 * Return 0 - toggle field are out of sync
1036 static int handle_data_ul(struct nozomi *dc, enum port_type port, u16 read_iir) in handle_data_ul() argument
1038 u8 *toggle = &(dc->port[port].toggle_ul); in handle_data_ul()
1041 dc->last_ier &= ~MDM_UL; in handle_data_ul()
1042 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1043 if (send_data(port, dc)) { in handle_data_ul()
1044 writew(MDM_UL1, dc->reg_fcr); in handle_data_ul()
1045 dc->last_ier = dc->last_ier | MDM_UL; in handle_data_ul()
1046 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1051 dc->last_ier &= ~MDM_UL; in handle_data_ul()
1052 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1053 if (send_data(port, dc)) { in handle_data_ul()
1054 writew(MDM_UL2, dc->reg_fcr); in handle_data_ul()
1055 dc->last_ier = dc->last_ier | MDM_UL; in handle_data_ul()
1056 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1062 dc->last_ier &= ~MDM_UL; in handle_data_ul()
1063 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1064 if (send_data(port, dc)) { in handle_data_ul()
1065 writew(MDM_UL2, dc->reg_fcr); in handle_data_ul()
1066 dc->last_ier = dc->last_ier | MDM_UL; in handle_data_ul()
1067 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1072 dc->last_ier &= ~MDM_UL; in handle_data_ul()
1073 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1074 if (send_data(port, dc)) { in handle_data_ul()
1075 writew(MDM_UL1, dc->reg_fcr); in handle_data_ul()
1076 dc->last_ier = dc->last_ier | MDM_UL; in handle_data_ul()
1077 writew(dc->last_ier, dc->reg_ier); in handle_data_ul()
1082 writew(read_iir & MDM_UL, dc->reg_fcr); in handle_data_ul()
1083 dev_err(&dc->pdev->dev, "port out of sync!\n"); in handle_data_ul()
1091 struct nozomi *dc = dev_id; in interrupt_handler() local
1095 if (!dc) in interrupt_handler()
1098 spin_lock(&dc->spin_mutex); in interrupt_handler()
1099 read_iir = readw(dc->reg_iir); in interrupt_handler()
1102 if (read_iir == (u16)-1) in interrupt_handler()
1106 * (by masking with dc->last_ier) in interrupt_handler()
1108 read_iir &= dc->last_ier; in interrupt_handler()
1115 dc->last_ier); in interrupt_handler()
1118 if (unlikely(!nozomi_read_config_table(dc))) { in interrupt_handler()
1119 dc->last_ier = 0x0; in interrupt_handler()
1120 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1121 dev_err(&dc->pdev->dev, "Could not read status from " in interrupt_handler()
1122 "card, we should disable interface\n"); in interrupt_handler()
1124 writew(RESET, dc->reg_fcr); in interrupt_handler()
1131 dc->last_ier &= ~CTRL_UL; in interrupt_handler()
1132 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1133 if (send_flow_control(dc)) { in interrupt_handler()
1134 writew(CTRL_UL, dc->reg_fcr); in interrupt_handler()
1135 dc->last_ier = dc->last_ier | CTRL_UL; in interrupt_handler()
1136 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1140 receive_flow_control(dc); in interrupt_handler()
1141 writew(CTRL_DL, dc->reg_fcr); in interrupt_handler()
1144 if (!handle_data_dl(dc, PORT_MDM, in interrupt_handler()
1145 &(dc->port[PORT_MDM].toggle_dl), read_iir, in interrupt_handler()
1147 dev_err(&dc->pdev->dev, "MDM_DL out of sync!\n"); in interrupt_handler()
1152 if (!handle_data_ul(dc, PORT_MDM, read_iir)) { in interrupt_handler()
1153 dev_err(&dc->pdev->dev, "MDM_UL out of sync!\n"); in interrupt_handler()
1158 if (!handle_data_dl(dc, PORT_DIAG, in interrupt_handler()
1159 &(dc->port[PORT_DIAG].toggle_dl), read_iir, in interrupt_handler()
1161 dev_err(&dc->pdev->dev, "DIAG_DL out of sync!\n"); in interrupt_handler()
1166 dc->last_ier &= ~DIAG_UL; in interrupt_handler()
1167 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1168 if (send_data(PORT_DIAG, dc)) { in interrupt_handler()
1169 writew(DIAG_UL, dc->reg_fcr); in interrupt_handler()
1170 dc->last_ier = dc->last_ier | DIAG_UL; in interrupt_handler()
1171 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1175 if (receive_data(PORT_APP1, dc)) in interrupt_handler()
1176 writew(APP1_DL, dc->reg_fcr); in interrupt_handler()
1179 dc->last_ier &= ~APP1_UL; in interrupt_handler()
1180 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1181 if (send_data(PORT_APP1, dc)) { in interrupt_handler()
1182 writew(APP1_UL, dc->reg_fcr); in interrupt_handler()
1183 dc->last_ier = dc->last_ier | APP1_UL; in interrupt_handler()
1184 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1188 if (receive_data(PORT_APP2, dc)) in interrupt_handler()
1189 writew(APP2_DL, dc->reg_fcr); in interrupt_handler()
1192 dc->last_ier &= ~APP2_UL; in interrupt_handler()
1193 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1194 if (send_data(PORT_APP2, dc)) { in interrupt_handler()
1195 writew(APP2_UL, dc->reg_fcr); in interrupt_handler()
1196 dc->last_ier = dc->last_ier | APP2_UL; in interrupt_handler()
1197 writew(dc->last_ier, dc->reg_ier); in interrupt_handler()
1202 spin_unlock(&dc->spin_mutex); in interrupt_handler()
1205 if (test_and_clear_bit(a, &dc->flip)) in interrupt_handler()
1206 tty_flip_buffer_push(&dc->port[a].port); in interrupt_handler()
1210 spin_unlock(&dc->spin_mutex); in interrupt_handler()
1214 static void nozomi_get_card_type(struct nozomi *dc) in nozomi_get_card_type() argument
1220 size += pci_resource_len(dc->pdev, i); in nozomi_get_card_type()
1223 dc->card_type = size == 2048 ? F32_2 : F32_8; in nozomi_get_card_type()
1225 dev_info(&dc->pdev->dev, "Card type is: %d\n", dc->card_type); in nozomi_get_card_type()
1228 static void nozomi_setup_private_data(struct nozomi *dc) in nozomi_setup_private_data() argument
1230 void __iomem *offset = dc->base_addr + dc->card_type / 2; in nozomi_setup_private_data()
1233 dc->reg_fcr = (void __iomem *)(offset + R_FCR); in nozomi_setup_private_data()
1234 dc->reg_iir = (void __iomem *)(offset + R_IIR); in nozomi_setup_private_data()
1235 dc->reg_ier = (void __iomem *)(offset + R_IER); in nozomi_setup_private_data()
1236 dc->last_ier = 0; in nozomi_setup_private_data()
1237 dc->flip = 0; in nozomi_setup_private_data()
1239 dc->port[PORT_MDM].token_dl = MDM_DL; in nozomi_setup_private_data()
1240 dc->port[PORT_DIAG].token_dl = DIAG_DL; in nozomi_setup_private_data()
1241 dc->port[PORT_APP1].token_dl = APP1_DL; in nozomi_setup_private_data()
1242 dc->port[PORT_APP2].token_dl = APP2_DL; in nozomi_setup_private_data()
1245 init_waitqueue_head(&dc->port[i].tty_wait); in nozomi_setup_private_data()
1251 const struct nozomi *dc = dev_get_drvdata(dev); in card_type_show() local
1253 return sprintf(buf, "%d\n", dc->card_type); in card_type_show()
1260 const struct nozomi *dc = dev_get_drvdata(dev); in open_ttys_show() local
1262 return sprintf(buf, "%u\n", dc->open_ttys); in open_ttys_show()
1266 static void make_sysfs_files(struct nozomi *dc) in make_sysfs_files() argument
1268 if (device_create_file(&dc->pdev->dev, &dev_attr_card_type)) in make_sysfs_files()
1269 dev_err(&dc->pdev->dev, in make_sysfs_files()
1271 if (device_create_file(&dc->pdev->dev, &dev_attr_open_ttys)) in make_sysfs_files()
1272 dev_err(&dc->pdev->dev, in make_sysfs_files()
1276 static void remove_sysfs_files(struct nozomi *dc) in remove_sysfs_files() argument
1278 device_remove_file(&dc->pdev->dev, &dev_attr_card_type); in remove_sysfs_files()
1279 device_remove_file(&dc->pdev->dev, &dev_attr_open_ttys); in remove_sysfs_files()
1287 struct nozomi *dc = NULL; in nozomi_card_init() local
1296 dev_err(&pdev->dev, "no free tty range for this card left\n"); in nozomi_card_init()
1297 ret = -EIO; in nozomi_card_init()
1301 dc = kzalloc(sizeof(struct nozomi), GFP_KERNEL); in nozomi_card_init()
1302 if (unlikely(!dc)) { in nozomi_card_init()
1303 dev_err(&pdev->dev, "Could not allocate memory\n"); in nozomi_card_init()
1304 ret = -ENOMEM; in nozomi_card_init()
1308 dc->pdev = pdev; in nozomi_card_init()
1310 ret = pci_enable_device(dc->pdev); in nozomi_card_init()
1312 dev_err(&pdev->dev, "Failed to enable PCI Device\n"); in nozomi_card_init()
1316 ret = pci_request_regions(dc->pdev, NOZOMI_NAME); in nozomi_card_init()
1318 dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", in nozomi_card_init()
1324 nozomi_get_card_type(dc); in nozomi_card_init()
1326 dc->base_addr = pci_iomap(dc->pdev, 0, dc->card_type); in nozomi_card_init()
1327 if (!dc->base_addr) { in nozomi_card_init()
1328 dev_err(&pdev->dev, "Unable to map card MMIO\n"); in nozomi_card_init()
1329 ret = -ENODEV; in nozomi_card_init()
1333 dc->send_buf = kmalloc(SEND_BUF_MAX, GFP_KERNEL); in nozomi_card_init()
1334 if (!dc->send_buf) { in nozomi_card_init()
1335 dev_err(&pdev->dev, "Could not allocate send buffer?\n"); in nozomi_card_init()
1336 ret = -ENOMEM; in nozomi_card_init()
1341 if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_UL, in nozomi_card_init()
1343 dev_err(&pdev->dev, in nozomi_card_init()
1345 ret = -ENOMEM; in nozomi_card_init()
1350 spin_lock_init(&dc->spin_mutex); in nozomi_card_init()
1352 nozomi_setup_private_data(dc); in nozomi_card_init()
1354 /* Disable all interrupts */ in nozomi_card_init()
1355 dc->last_ier = 0; in nozomi_card_init()
1356 writew(dc->last_ier, dc->reg_ier); in nozomi_card_init()
1358 ret = request_irq(pdev->irq, &interrupt_handler, IRQF_SHARED, in nozomi_card_init()
1359 NOZOMI_NAME, dc); in nozomi_card_init()
1361 dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); in nozomi_card_init()
1365 DBG1("base_addr: %p", dc->base_addr); in nozomi_card_init()
1367 make_sysfs_files(dc); in nozomi_card_init()
1369 dc->index_start = ndev_idx * MAX_PORT; in nozomi_card_init()
1370 ndevs[ndev_idx] = dc; in nozomi_card_init()
1372 pci_set_drvdata(pdev, dc); in nozomi_card_init()
1375 dc->last_ier = RESET; in nozomi_card_init()
1376 iowrite16(dc->last_ier, dc->reg_ier); in nozomi_card_init()
1378 dc->state = NOZOMI_STATE_ENABLED; in nozomi_card_init()
1382 struct port *port = &dc->port[i]; in nozomi_card_init()
1383 port->dc = dc; in nozomi_card_init()
1384 tty_port_init(&port->port); in nozomi_card_init()
1385 port->port.ops = &noz_tty_port_ops; in nozomi_card_init()
1386 tty_dev = tty_port_register_device(&port->port, ntty_driver, in nozomi_card_init()
1387 dc->index_start + i, &pdev->dev); in nozomi_card_init()
1391 dev_err(&pdev->dev, "Could not allocate tty?\n"); in nozomi_card_init()
1392 tty_port_destroy(&port->port); in nozomi_card_init()
1400 for (i--; i >= 0; i--) { in nozomi_card_init()
1401 tty_unregister_device(ntty_driver, dc->index_start + i); in nozomi_card_init()
1402 tty_port_destroy(&dc->port[i].port); in nozomi_card_init()
1404 free_irq(pdev->irq, dc); in nozomi_card_init()
1408 for (i--; i >= PORT_MDM; i--) in nozomi_card_init()
1409 kfifo_free(&dc->port[i].fifo_ul); in nozomi_card_init()
1411 kfree(dc->send_buf); in nozomi_card_init()
1412 iounmap(dc->base_addr); in nozomi_card_init()
1418 kfree(dc); in nozomi_card_init()
1423 static void tty_exit(struct nozomi *dc) in tty_exit() argument
1428 tty_port_tty_hangup(&dc->port[i].port, false); in tty_exit()
1430 /* Racy below - surely should wait for scheduled work to be done or in tty_exit()
1432 while (dc->open_ttys) in tty_exit()
1435 tty_unregister_device(ntty_driver, dc->index_start + i); in tty_exit()
1436 tty_port_destroy(&dc->port[i].port); in tty_exit()
1445 struct nozomi *dc = pci_get_drvdata(pdev); in nozomi_card_exit() local
1447 /* Disable all interrupts */ in nozomi_card_exit()
1448 dc->last_ier = 0; in nozomi_card_exit()
1449 writew(dc->last_ier, dc->reg_ier); in nozomi_card_exit()
1451 tty_exit(dc); in nozomi_card_exit()
1461 /* Setup dc->reg addresses to we can use defines here */ in nozomi_card_exit()
1462 write_mem32(dc->port[PORT_CTRL].ul_addr[0], (u32 *)&ctrl, 2); in nozomi_card_exit()
1463 writew(CTRL_UL, dc->reg_fcr); /* push the token to the card. */ in nozomi_card_exit()
1465 remove_sysfs_files(dc); in nozomi_card_exit()
1467 free_irq(pdev->irq, dc); in nozomi_card_exit()
1470 kfifo_free(&dc->port[i].fifo_ul); in nozomi_card_exit()
1472 kfree(dc->send_buf); in nozomi_card_exit()
1474 iounmap(dc->base_addr); in nozomi_card_exit()
1480 ndevs[dc->index_start / MAX_PORT] = NULL; in nozomi_card_exit()
1482 kfree(dc); in nozomi_card_exit()
1489 port->ctrl_ul.RTS = rts; in set_rts()
1490 port->update_flow_control = 1; in set_rts()
1498 DBG1("SETTING DTR index: %d, dtr: %d", tty->index, dtr); in set_dtr()
1500 port->ctrl_ul.DTR = dtr; in set_dtr()
1501 port->update_flow_control = 1; in set_dtr()
1506 * ----------------------------------------------------------------------------
1508 * ----------------------------------------------------------------------------
1514 struct nozomi *dc = get_dc_by_tty(tty); in ntty_install() local
1516 if (!port || !dc || dc->state != NOZOMI_STATE_READY) in ntty_install()
1517 return -ENODEV; in ntty_install()
1520 tty->driver_data = port; in ntty_install()
1526 tty->driver_data = NULL; in ntty_cleanup()
1532 struct nozomi *dc = port->dc; in ntty_activate() local
1535 DBG1("open: %d", port->token_dl); in ntty_activate()
1536 spin_lock_irqsave(&dc->spin_mutex, flags); in ntty_activate()
1537 dc->last_ier = dc->last_ier | port->token_dl; in ntty_activate()
1538 writew(dc->last_ier, dc->reg_ier); in ntty_activate()
1539 dc->open_ttys++; in ntty_activate()
1540 spin_unlock_irqrestore(&dc->spin_mutex, flags); in ntty_activate()
1541 printk("noz: activated %d: %p\n", tty->index, tport); in ntty_activate()
1547 struct port *port = tty->driver_data; in ntty_open()
1548 return tty_port_open(&port->port, tty, filp); in ntty_open()
1554 struct nozomi *dc = port->dc; in ntty_shutdown() local
1557 DBG1("close: %d", port->token_dl); in ntty_shutdown()
1558 spin_lock_irqsave(&dc->spin_mutex, flags); in ntty_shutdown()
1559 dc->last_ier &= ~(port->token_dl); in ntty_shutdown()
1560 writew(dc->last_ier, dc->reg_ier); in ntty_shutdown()
1561 dc->open_ttys--; in ntty_shutdown()
1562 spin_unlock_irqrestore(&dc->spin_mutex, flags); in ntty_shutdown()
1568 struct port *port = tty->driver_data; in ntty_close()
1570 tty_port_close(&port->port, tty, filp); in ntty_close()
1575 struct port *port = tty->driver_data; in ntty_hangup()
1576 tty_port_hangup(&port->port); in ntty_hangup()
1586 struct nozomi *dc = get_dc_by_tty(tty); in ntty_write() local
1587 struct port *port = tty->driver_data; in ntty_write()
1591 if (!dc || !port) in ntty_write()
1592 return -ENODEV; in ntty_write()
1594 rval = kfifo_in(&port->fifo_ul, buffer, count); in ntty_write()
1596 spin_lock_irqsave(&dc->spin_mutex, flags); in ntty_write()
1598 if (port == &(dc->port[PORT_MDM])) { in ntty_write()
1599 if (port->ctrl_dl.CTS) { in ntty_write()
1601 enable_transmit_ul(tty->index % MAX_PORT, dc); in ntty_write()
1603 dev_err(&dc->pdev->dev, in ntty_write()
1607 enable_transmit_ul(tty->index % MAX_PORT, dc); in ntty_write()
1609 spin_unlock_irqrestore(&dc->spin_mutex, flags); in ntty_write()
1625 struct port *port = tty->driver_data; in ntty_write_room()
1627 const struct nozomi *dc = get_dc_by_tty(tty); in ntty_write_room() local
1629 if (dc) in ntty_write_room()
1630 room = kfifo_avail(&port->fifo_ul); in ntty_write_room()
1638 const struct port *port = tty->driver_data; in ntty_tiocmget()
1639 const struct ctrl_dl *ctrl_dl = &port->ctrl_dl; in ntty_tiocmget()
1640 const struct ctrl_ul *ctrl_ul = &port->ctrl_ul; in ntty_tiocmget()
1644 return (ctrl_ul->RTS ? TIOCM_RTS : 0) in ntty_tiocmget()
1645 | (ctrl_ul->DTR ? TIOCM_DTR : 0) in ntty_tiocmget()
1646 | (ctrl_dl->DCD ? TIOCM_CAR : 0) in ntty_tiocmget()
1647 | (ctrl_dl->RI ? TIOCM_RNG : 0) in ntty_tiocmget()
1648 | (ctrl_dl->DSR ? TIOCM_DSR : 0) in ntty_tiocmget()
1649 | (ctrl_dl->CTS ? TIOCM_CTS : 0); in ntty_tiocmget()
1656 struct nozomi *dc = get_dc_by_tty(tty); in ntty_tiocmset() local
1659 spin_lock_irqsave(&dc->spin_mutex, flags); in ntty_tiocmset()
1669 spin_unlock_irqrestore(&dc->spin_mutex, flags); in ntty_tiocmset()
1677 const struct async_icount cnow = port->tty_icount; in ntty_cflags_changed()
1680 ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) in ntty_cflags_changed()
1681 || ((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) in ntty_cflags_changed()
1682 || ((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd)) in ntty_cflags_changed()
1683 || ((flags & TIOCM_CTS) && (cnow.cts != cprev->cts)); in ntty_cflags_changed()
1693 struct port *port = tty->driver_data; in ntty_tiocgicount()
1694 const struct async_icount cnow = port->tty_icount; in ntty_tiocgicount()
1696 icount->cts = cnow.cts; in ntty_tiocgicount()
1697 icount->dsr = cnow.dsr; in ntty_tiocgicount()
1698 icount->rng = cnow.rng; in ntty_tiocgicount()
1699 icount->dcd = cnow.dcd; in ntty_tiocgicount()
1700 icount->rx = cnow.rx; in ntty_tiocgicount()
1701 icount->tx = cnow.tx; in ntty_tiocgicount()
1702 icount->frame = cnow.frame; in ntty_tiocgicount()
1703 icount->overrun = cnow.overrun; in ntty_tiocgicount()
1704 icount->parity = cnow.parity; in ntty_tiocgicount()
1705 icount->brk = cnow.brk; in ntty_tiocgicount()
1706 icount->buf_overrun = cnow.buf_overrun; in ntty_tiocgicount()
1713 struct port *port = tty->driver_data; in ntty_ioctl()
1714 int rval = -ENOIOCTLCMD; in ntty_ioctl()
1718 struct async_icount cprev = port->tty_icount; in ntty_ioctl()
1720 rval = wait_event_interruptible(port->tty_wait, in ntty_ioctl()
1738 struct nozomi *dc = get_dc_by_tty(tty); in ntty_unthrottle() local
1741 spin_lock_irqsave(&dc->spin_mutex, flags); in ntty_unthrottle()
1742 enable_transmit_dl(tty->index % MAX_PORT, dc); in ntty_unthrottle()
1745 spin_unlock_irqrestore(&dc->spin_mutex, flags); in ntty_unthrottle()
1754 struct nozomi *dc = get_dc_by_tty(tty); in ntty_throttle() local
1757 spin_lock_irqsave(&dc->spin_mutex, flags); in ntty_throttle()
1759 spin_unlock_irqrestore(&dc->spin_mutex, flags); in ntty_throttle()
1765 struct port *port = tty->driver_data; in ntty_chars_in_buffer()
1766 struct nozomi *dc = get_dc_by_tty(tty); in ntty_chars_in_buffer() local
1768 if (unlikely(!dc || !port)) in ntty_chars_in_buffer()
1771 return kfifo_len(&port->fifo_ul); in ntty_chars_in_buffer()
1813 ntty_driver->driver_name = NOZOMI_NAME_TTY; in nozomi_init()
1814 ntty_driver->name = "noz"; in nozomi_init()
1815 ntty_driver->major = 0; in nozomi_init()
1816 ntty_driver->type = TTY_DRIVER_TYPE_SERIAL; in nozomi_init()
1817 ntty_driver->subtype = SERIAL_TYPE_NORMAL; in nozomi_init()
1818 ntty_driver->init_termios = tty_std_termios; in nozomi_init()
1819 ntty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | \ in nozomi_init()
1821 ntty_driver->init_termios.c_ispeed = 115200; in nozomi_init()
1822 ntty_driver->init_termios.c_ospeed = 115200; in nozomi_init()