static int __init hvsi_init(void) { int i; hvsi_driver = alloc_tty_driver(hvsi_count); if (!hvsi_driver) return -ENOMEM; hvsi_driver->owner = THIS_MODULE; hvsi_driver->driver_name = "hvsi"; hvsi_driver->name = "hvsi"; hvsi_driver->major = HVSI_MAJOR; hvsi_driver->minor_start = HVSI_MINOR; hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM; hvsi_driver->init_termios = tty_std_termios; hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; hvsi_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(hvsi_driver, &hvsi_ops); for (i=0; i < hvsi_count; i++) { struct hvsi_struct *hp = &hvsi_ports[i]; int ret = 1; ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp); if (ret) printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", hp->virq, ret); } hvsi_wait = wait_for_state; /* irqs active now */ if (tty_register_driver(hvsi_driver)) panic("Couldn't register hvsi console driver\n"); printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count); return 0; }
static int __init acm_init(void) { int retval; acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); if (!acm_tty_driver) return -ENOMEM; acm_tty_driver->owner = THIS_MODULE, acm_tty_driver->driver_name = "acm", acm_tty_driver->name = "ttyACM", acm_tty_driver->major = ACM_TTY_MAJOR, acm_tty_driver->minor_start = 0, acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, acm_tty_driver->subtype = SERIAL_TYPE_NORMAL, acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; acm_tty_driver->init_termios = tty_std_termios; acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; tty_set_operations(acm_tty_driver, &acm_ops); retval = tty_register_driver(acm_tty_driver); if (retval) { put_tty_driver(acm_tty_driver); return retval; } retval = usb_register(&acm_driver); if (retval) { tty_unregister_driver(acm_tty_driver); put_tty_driver(acm_tty_driver); return retval; } printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n"); return 0; }
int kgdb_register_nmi_console(void) { int ret; if (!arch_kgdb_ops.enable_nmi) return 0; kgdb_nmi_tty_driver = alloc_tty_driver(1); if (!kgdb_nmi_tty_driver) { pr_err("%s: cannot allocate tty\n", __func__); return -ENOMEM; } kgdb_nmi_tty_driver->driver_name = "ttyNMI"; kgdb_nmi_tty_driver->name = "ttyNMI"; kgdb_nmi_tty_driver->num = 1; kgdb_nmi_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; kgdb_nmi_tty_driver->subtype = SERIAL_TYPE_NORMAL; kgdb_nmi_tty_driver->flags = TTY_DRIVER_REAL_RAW; kgdb_nmi_tty_driver->init_termios = tty_std_termios; tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios, KGDB_NMI_BAUD, KGDB_NMI_BAUD); tty_set_operations(kgdb_nmi_tty_driver, &kgdb_nmi_tty_ops); ret = tty_register_driver(kgdb_nmi_tty_driver); if (ret) { pr_err("%s: can't register tty driver: %d\n", __func__, ret); goto err_drv_reg; } register_console(&kgdb_nmi_console); arch_kgdb_ops.enable_nmi(1); return 0; err_drv_reg: put_tty_driver(kgdb_nmi_tty_driver); return ret; }
/*------------------------------------------------------------ 函数原型: static int tty_module_init(void) 描述: tty_module_init是NDISTTY模块的,模块初始化函数,是模块装 入的入口点。 输入: 无 输出: 无 返回值: 无 -------------------------------------------------------------*/ static int tty_module_init(void) { int result = 0; //printk("Enter - %s\n", __FUNCTION__); ndis_tty_driver = alloc_tty_driver(NDIS_TTY_MINOR); if (!ndis_tty_driver) { printk("%s - alloc_tty_driver failed!\n", __FUNCTION__); return -ENOMEM; } ndis_tty_driver->owner = THIS_MODULE; ndis_tty_driver->driver_name = "QMITTY"; ndis_tty_driver->name = "qmitty"; ndis_tty_driver->major = NDIS_TTY_MAJOR; ndis_tty_driver->minor_start = 0; ndis_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; ndis_tty_driver->subtype = SERIAL_TYPE_NORMAL; ndis_tty_driver->flags = TTY_DRIVER_REAL_RAW /*| TTY_DRIVER_DYNAMIC_DEV*/; ndis_tty_driver->init_termios = tty_std_termios; ndis_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL; ndis_tty_driver->init_termios.c_lflag = ISIG; ndis_tty_driver->init_termios.c_oflag = 0; tty_set_operations(ndis_tty_driver, &ndis_tty_ops); //printk("%s - tty struct init successful !\n", __FUNCTION__); result = tty_register_driver(ndis_tty_driver); if (result) { printk(KERN_ALERT "%s - tty_register_driver failed!\n", __FUNCTION__); return (-1); } printk(KERN_ALERT "Registered the ndis_tty_driver !!\n"); return 0; }
int shell_init(void ) //clean warning { printk("Enter ecall init\n"); shell_tty_drv = alloc_tty_driver(ES_TTY_MINORS); if (!shell_tty_drv) { printk("Cannot alloc shell tty driver\n"); return -1; } shell_tty_drv->owner = THIS_MODULE; shell_tty_drv->driver_name = "es_serial"; shell_tty_drv->name = "es_tty"; shell_tty_drv->major = ES_TTY_MAJOR; shell_tty_drv->minor_start = 0; shell_tty_drv->type = TTY_DRIVER_TYPE_SERIAL; shell_tty_drv->subtype = SERIAL_TYPE_NORMAL; shell_tty_drv->flags = TTY_DRIVER_REAL_RAW; shell_tty_drv->init_termios = tty_std_termios; shell_tty_drv->init_termios.c_cflag = B921600 | CS8 | CREAD | HUPCL | CLOCAL; tty_set_operations(shell_tty_drv, &shell_ops); tty_port_init(&shell_tty_port); shell_tty_port.ops = &shell_port_ops; tty_port_link_device(&shell_tty_port, shell_tty_drv, 0); if (tty_register_driver(shell_tty_drv)) { printk("Error registering shell tty driver\n"); put_tty_driver(shell_tty_drv); return -1; } printk("Finish ecall init\n"); return 0; }
static int __init tiny_init(void) { int retval; int i; /* allocate the tty driver */ tiny_tty_driver = alloc_tty_driver(TINY_TTY_MINORS); if (!tiny_tty_driver) return -ENOMEM; /* initialize the tty driver */ tiny_tty_driver->owner = THIS_MODULE; tiny_tty_driver->driver_name = "tiny_tty"; tiny_tty_driver->name = "ttty"; tiny_tty_driver->major = TINY_TTY_MAJOR, tiny_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, tiny_tty_driver->subtype = SERIAL_TYPE_NORMAL, tiny_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV, tiny_tty_driver->init_termios = tty_std_termios; tiny_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; tty_set_operations(tiny_tty_driver, &serial_ops); /* register the tty driver */ retval = tty_register_driver(tiny_tty_driver); if (retval) { printk(KERN_ERR "failed to register tiny tty driver"); put_tty_driver(tiny_tty_driver); return retval; } for (i = 0; i < TINY_TTY_MINORS; ++i) tty_register_device(tiny_tty_driver, i, NULL); printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION); return retval; }
static int __init cwc_init(void) { int result; printk(KERN_INFO "%s", __FUNCTION__); cpwatcher_driver = alloc_tty_driver(1); if (!cpwatcher_driver) return -ENOMEM; cpwatcher_driver->owner = THIS_MODULE; cpwatcher_driver->driver_name = "cpwatcher"; cpwatcher_driver->name = "cwc"; cpwatcher_driver->major = 154; cpwatcher_driver->minor_start = 0; cpwatcher_driver->type = TTY_DRIVER_TYPE_SERIAL; cpwatcher_driver->subtype = SERIAL_TYPE_NORMAL; cpwatcher_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; cpwatcher_driver->init_termios = tty_std_termios; cpwatcher_driver->init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; tty_set_operations(cpwatcher_driver, &cpwatcher_ops); result = tty_register_driver(cpwatcher_driver); if (result) { printk(KERN_ERR "failed to register cp watcher driver"); put_tty_driver(cpwatcher_driver); return result; } tty_register_device(cpwatcher_driver, 0, NULL); return 0; }
static int __init smd_tty_init(void) { int ret; smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); if (smd_tty_driver == 0) return -ENOMEM; smd_tty_driver->owner = THIS_MODULE; smd_tty_driver->driver_name = "smd_tty_driver"; smd_tty_driver->name = "smd"; smd_tty_driver->major = 0; smd_tty_driver->minor_start = 0; smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; smd_tty_driver->init_termios = tty_std_termios; smd_tty_driver->init_termios.c_iflag = 0; smd_tty_driver->init_termios.c_oflag = 0; smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; smd_tty_driver->init_termios.c_lflag = 0; smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(smd_tty_driver, &smd_tty_ops); ret = tty_register_driver(smd_tty_driver); if (ret) return ret; tty_register_device(smd_tty_driver, 0, 0); tty_register_device(smd_tty_driver, 7, 0); tty_register_device(smd_tty_driver, 21, 0); tty_register_device(smd_tty_driver, 27, 0); tty_register_device(smd_tty_driver, 36, 0); return 0; }
static int __init nfcon_init(void) { int res; stderr_id = nf_get_id("NF_STDERR"); if (!stderr_id) return -ENODEV; nfcon_tty_driver = alloc_tty_driver(1); if (!nfcon_tty_driver) return -ENOMEM; tty_port_init(&nfcon_tty_port); nfcon_tty_driver->driver_name = "nfcon"; nfcon_tty_driver->name = "nfcon"; nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY; nfcon_tty_driver->init_termios = tty_std_termios; nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops); tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0); res = tty_register_driver(nfcon_tty_driver); if (res) { pr_err("failed to register nfcon tty driver\n"); put_tty_driver(nfcon_tty_driver); tty_port_destroy(&nfcon_tty_port); return res; } if (!(nf_console.flags & CON_ENABLED)) register_console(&nf_console); return 0; }
static int __init lge_dm_tty_init(void) { int ret = 0; struct device *tty_dev; struct dm_tty *lge_dm_tty_drv; pr_info(DM_TTY_MODULE_NAME ": %s\n", __func__); if(lge_dm_tty != NULL) { lge_dm_tty_drv = lge_dm_tty; } else { lge_dm_tty_drv = kzalloc(sizeof(struct dm_tty), GFP_KERNEL); if (lge_dm_tty_drv == NULL) { pr_info(DM_TTY_MODULE_NAME "%s:" "failed to allocate lge_dm_tty", __func__); return 0; } lge_dm_tty = lge_dm_tty_drv; } lge_dm_tty_drv->tty_drv = alloc_tty_driver(MAX_DM_TTY_DRV); if (!lge_dm_tty_drv->tty_drv) { pr_info(DM_TTY_MODULE_NAME ": %s - tty_drv is NULL", __func__); kfree(lge_dm_tty_drv); return 0; } lge_dm_tty_drv->tty_drv->name = "lge_dm_tty"; lge_dm_tty_drv->tty_drv->owner = THIS_MODULE; lge_dm_tty_drv->tty_drv->driver_name = "lge_dm_tty"; /* uses dynamically assigned dev_t values */ lge_dm_tty_drv->tty_drv->type = TTY_DRIVER_TYPE_SERIAL; lge_dm_tty_drv->tty_drv->subtype = SERIAL_TYPE_NORMAL; lge_dm_tty_drv->tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; /* initializing the tty driver */ lge_dm_tty_drv->tty_drv->init_termios = tty_std_termios; lge_dm_tty_drv->tty_drv->init_termios.c_iflag = IGNBRK | IGNPAR; lge_dm_tty_drv->tty_drv->init_termios.c_oflag = 0; lge_dm_tty_drv->tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; lge_dm_tty_drv->tty_drv->init_termios.c_lflag = 0; tty_set_operations(lge_dm_tty_drv->tty_drv, &lge_dm_tty_ops); ret = tty_register_driver(lge_dm_tty_drv->tty_drv); if (ret) { put_tty_driver(lge_dm_tty_drv->tty_drv); pr_info(DM_TTY_MODULE_NAME ": %s:" "tty_register_driver() ""failed\n", __func__); lge_dm_tty_drv->tty_drv = NULL; kfree(lge_dm_tty_drv); return 0; } tty_dev = tty_register_device(lge_dm_tty_drv->tty_drv, 0, NULL); if (IS_ERR(tty_dev)) { pr_info(DM_TTY_MODULE_NAME ": %s:" "tty_register_device() " "failed\n", __func__); tty_unregister_driver(lge_dm_tty_drv->tty_drv); put_tty_driver(lge_dm_tty_drv->tty_drv); kfree(lge_dm_tty_drv); return 0; } init_waitqueue_head(&lge_dm_tty_drv->waitq); lge_dm_tty_drv->tty_state = DM_TTY_REGISTERED; /* data initialization */ dm_modem_response = kzalloc(DM_TTY_TX_MAX_PACKET_SIZE, GFP_KERNEL); if (dm_modem_response == NULL) pr_info(DM_TTY_MODULE_NAME ": %s: dm_modem_response ""failed\n", __func__); dm_modem_request = kzalloc(DM_TTY_RX_MAX_PACKET_SIZE, GFP_KERNEL); if (dm_modem_request == NULL) pr_info(DM_TTY_MODULE_NAME ": %s: dm_modem_request ""failed\n", __func__); dm_modem_response_header_length = sizeof(struct dm_router_header); dm_modem_response_header = kzalloc(dm_modem_response_header_length, GFP_KERNEL); if (dm_modem_response_header == NULL) pr_info(DM_TTY_MODULE_NAME ": %s: dm_modem_response_header " "failed\n", __func__); dm_modem_request_header_length = sizeof(struct dm_router_header); dm_modem_request_header = kzalloc(dm_modem_request_header_length, GFP_KERNEL); if (dm_modem_request_header == NULL) pr_info(DM_TTY_MODULE_NAME ": %s: dm_modem_request_header " "failed\n", __func__); dm_modem_response_body_length = sizeof(struct dm_router_modem_response_body); dm_modem_response_body = kzalloc(dm_modem_response_body_length, GFP_KERNEL); if (dm_modem_response_body == NULL) pr_info(DM_TTY_MODULE_NAME ": %s: dm_modem_response_body " "failed\n", __func__); return 0; }
static int userial_init(void) { unsigned i; int status; gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS); if (!gs_tty_driver) return -ENOMEM; gs_tty_driver->driver_name = "g_serial"; gs_tty_driver->name = PREFIX; /* uses dynamically assigned dev_t values */ gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; gs_tty_driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on * MS-Windows. Otherwise, most of these flags shouldn't affect * anything unless we were to actually hook up to a serial line. */ gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; gs_tty_driver->init_termios.c_ispeed = 9600; gs_tty_driver->init_termios.c_ospeed = 9600; tty_set_operations(gs_tty_driver, &gs_tty_ops); for (i = 0; i < MAX_U_SERIAL_PORTS; i++) mutex_init(&ports[i].lock); gserial_wq = create_singlethread_workqueue("k_gserial"); if (!gserial_wq) { status = -ENOMEM; goto fail; } /* export the driver ... */ status = tty_register_driver(gs_tty_driver); if (status) { pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } for (i = 0; i < MAX_U_SERIAL_PORTS; i++) usb_debugfs_init(ports[i].port, i); pr_debug("%s: registered %d ttyGS* device%s\n", __func__, MAX_U_SERIAL_PORTS, (MAX_U_SERIAL_PORTS == 1) ? "" : "s"); return status; fail: put_tty_driver(gs_tty_driver); if (gserial_wq) destroy_workqueue(gserial_wq); gs_tty_driver = NULL; return status; }
/* rs_init inits the driver */ static int __init rs68328_init(void) { int flags, i; struct m68k_serial *info; serial_driver = alloc_tty_driver(NR_PORTS); if (!serial_driver) return -ENOMEM; show_serial_version(); /* Initialize the tty_driver structure */ /* SPARC: Not all of this is exactly right for us. */ serial_driver->name = "ttyS"; serial_driver->major = TTY_MAJOR; serial_driver->minor_start = 64; serial_driver->type = TTY_DRIVER_TYPE_SERIAL; serial_driver->subtype = SERIAL_TYPE_NORMAL; serial_driver->init_termios = tty_std_termios; serial_driver->init_termios.c_cflag = m68328_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL; serial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(serial_driver, &rs_ops); if (tty_register_driver(serial_driver)) { put_tty_driver(serial_driver); printk(KERN_ERR "Couldn't register serial driver\n"); return -ENOMEM; } local_irq_save(flags); for(i=0;i<NR_PORTS;i++) { info = &m68k_soft[i]; info->magic = SERIAL_MAGIC; info->port = (int) &uart_addr[i]; info->tty = NULL; info->irq = uart_irqs[i]; info->custom_divisor = 16; info->close_delay = 50; info->closing_wait = 3000; info->x_char = 0; info->event = 0; info->count = 0; info->blocked_open = 0; INIT_WORK(&info->tqueue, do_softint); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); info->line = i; info->is_cons = 1; /* Means shortcuts work */ printk("%s%d at 0x%08x (irq = %d)", serial_driver->name, info->line, info->port, info->irq); printk(" is a builtin MC68328 UART\n"); #ifdef CONFIG_M68VZ328 if (i > 0 ) PJSEL &= 0xCF; /* PSW enable second port output */ #endif if (request_irq(uart_irqs[i], rs_interrupt, IRQF_DISABLED, "M68328_UART", info)) panic("Unable to attach 68328 serial interrupt\n"); } local_irq_restore(flags); return 0; }
/* mcfrs_init inits the driver */ static int __init mcfrs_init(void) { struct mcf_serial *info; unsigned long flags; int i; /* Setup base handler, and timer table. */ #ifdef MCFPP_DCD0 init_timer(&mcfrs_timer_struct); mcfrs_timer_struct.function = mcfrs_timer; mcfrs_timer_struct.data = 0; mcfrs_timer_struct.expires = jiffies + HZ/25; add_timer(&mcfrs_timer_struct); mcfrs_ppstatus = mcf_getppdata() & (MCFPP_DCD0 | MCFPP_DCD1); #endif mcfrs_serial_driver = alloc_tty_driver(NR_PORTS); if (!mcfrs_serial_driver) return -ENOMEM; show_serial_version(); /* Initialize the tty_driver structure */ mcfrs_serial_driver->owner = THIS_MODULE; mcfrs_serial_driver->name = "ttyS"; mcfrs_serial_driver->driver_name = "mcfserial"; mcfrs_serial_driver->major = TTY_MAJOR; mcfrs_serial_driver->minor_start = 64; mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; mcfrs_serial_driver->subtype = SERIAL_TYPE_NORMAL; mcfrs_serial_driver->init_termios = tty_std_termios; mcfrs_serial_driver->init_termios.c_cflag = mcfrs_console_cbaud | CS8 | CREAD | HUPCL | CLOCAL; mcfrs_serial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(mcfrs_serial_driver, &mcfrs_ops); if (tty_register_driver(mcfrs_serial_driver)) { printk("MCFRS: Couldn't register serial driver\n"); put_tty_driver(mcfrs_serial_driver); return(-EBUSY); } local_irq_save(flags); /* * Configure all the attached serial ports. */ for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) { info->magic = SERIAL_MAGIC; info->line = i; info->port.tty = NULL; info->custom_divisor = 16; info->close_delay = 50; info->closing_wait = 3000; info->x_char = 0; info->event = 0; info->count = 0; info->blocked_open = 0; INIT_WORK(&info->tqueue, mcfrs_offintr); INIT_WORK(&info->tqueue_hangup, do_serial_hangup); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); info->imr = 0; mcfrs_setsignals(info, 0, 0); mcfrs_irqinit(info); printk("ttyS%d at 0x%04x (irq = %d)", info->line, (unsigned int) info->addr, info->irq); printk(" is a builtin ColdFire UART\n"); } local_irq_restore(flags); return 0; }
static int mcu_platform_probe(struct platform_device *pdev) { int ret, i; struct mcu_data *data; struct mcu *mcu; u8 *base; mcu = platform_get_drvdata(pdev); intel_mcu_tty_driver = alloc_tty_driver(INTEL_MCU_TTY_MINORS); if (!intel_mcu_tty_driver) { dev_err(&pdev->dev, "fail to alloc tty driver\n"); return -ENODEV; } intel_mcu_tty_driver->name = "ttymcu"; intel_mcu_tty_driver->major = INTEL_MCU_TTY_MAJOR; intel_mcu_tty_driver->minor_start = 0; intel_mcu_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; intel_mcu_tty_driver->subtype = SERIAL_TYPE_NORMAL; intel_mcu_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; intel_mcu_tty_driver->init_termios = tty_std_termios; intel_mcu_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; intel_mcu_tty_driver->init_termios.c_ispeed = 38400; intel_mcu_tty_driver->init_termios.c_ospeed = 38400; intel_mcu_tty_driver->init_termios.c_iflag = 0; intel_mcu_tty_driver->init_termios.c_oflag = 0; intel_mcu_tty_driver->init_termios.c_lflag = 0; tty_set_operations(intel_mcu_tty_driver, &intel_mcu_ops); ret = tty_register_driver(intel_mcu_tty_driver); if (ret) { dev_err(&pdev->dev, "fail to register tty driver\n"); goto tty_reg_fail; } base = (u8 *)mcu->ddr[1]; for (i = INTEL_MCU_TTY_MINORS - 1; i >= 0; i--) { data = kzalloc(sizeof(struct mcu_data), GFP_KERNEL); if (data == NULL) { dev_err(&pdev->dev, "fail to alloc mcu data\n"); goto data_alloc_fail; } data->index = i; tty_port_init(&data->port); data->dev = tty_port_register_device(&data->port, intel_mcu_tty_driver, i, &pdev->dev); mcu_table[i] = data; data->mcu = mcu; init_completion(&data->cmp); data->lbuf.addr = base; data->lbuf.length = BUF_IA_DDR_SIZE; lbuf_read_reset(&data->lbuf); base += BUF_IA_DDR_SIZE; } ret = sysfs_create_group(&pdev->dev.kobj, &intel_mcu_tty_attribute_group); if (ret) { pr_err("failed to create the mdbg sysfs attributes\n"); sysfs_remove_group(&pdev->dev.kobj, &intel_mcu_tty_attribute_group); goto data_alloc_fail; } intel_psh_ipc_bind(PSH_RECV_CH0, raw_data_handler, mcu_table[0]); intel_psh_ipc_bind(PSH_RECV_CH1, raw_data_handler, mcu_table[1]); intel_psh_ipc_bind(PSH_RECV_CH2, cmd_handler, mcu_table[2]); pr_info("MCU detected and ready to used!\n"); return 0; data_alloc_fail: for (i = 0; i < INTEL_MCU_TTY_MINORS; i++) kfree(mcu_table[i]); tty_reg_fail: put_tty_driver(intel_mcu_tty_driver); return ret; }
static int vs_add_dev(struct pdp_info *dev) { struct tty_driver *tty_driver; switch (dev->id) { case 1: tty_driver = &dev->vs_dev.tty_driver[0]; tty_driver->minor_start = CSD_MINOR_NUM; break; case 8: tty_driver = &dev->vs_dev.tty_driver[1]; tty_driver->minor_start = 1; break; case 5: tty_driver = &dev->vs_dev.tty_driver[2]; tty_driver->minor_start = 2; break; case 6: tty_driver = &dev->vs_dev.tty_driver[3]; tty_driver->minor_start = 3; break; case 25: tty_driver = &dev->vs_dev.tty_driver[4]; tty_driver->minor_start = 4; break; case 30: tty_driver = &dev->vs_dev.tty_driver[5]; tty_driver->minor_start = 5; break; #ifdef LOOP_BACK_TEST case 31: tty_driver = &dev->vs_dev.tty_driver[6]; tty_driver->minor_start = 6; break; #endif default: tty_driver = NULL; } if (!tty_driver) { printk("tty driver is NULL!\n"); return -1; } kref_init(&tty_driver->kref); tty_driver->magic = TTY_DRIVER_MAGIC; tty_driver->driver_name = "multipdp"; tty_driver->name = dev->vs_dev.tty_name; tty_driver->major = CSD_MAJOR_NUM; // tty_driver->minor_start = CSD_MINOR_NUM; tty_driver->num = 1; tty_driver->type = TTY_DRIVER_TYPE_SERIAL; tty_driver->subtype = SERIAL_TYPE_NORMAL; tty_driver->flags = TTY_DRIVER_REAL_RAW; tty_driver->ttys = dev->vs_dev.tty_table; // 2.6 kernel porting tty_driver->termios = dev->vs_dev.termios; tty_driver->termios_locked = dev->vs_dev.termios_locked; // tty_driver->init_termios = tty_std_termios; tty_set_operations(tty_driver, &multipdp_tty_ops); return tty_register_driver(tty_driver); }
static int __init smd_tty_init(void) { int ret; int n; int idx; smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); if (smd_tty_driver == 0) return -ENOMEM; smd_tty_driver->owner = THIS_MODULE; smd_tty_driver->driver_name = "smd_tty_driver"; smd_tty_driver->name = "smd"; smd_tty_driver->major = 0; smd_tty_driver->minor_start = 0; smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; smd_tty_driver->init_termios = tty_std_termios; smd_tty_driver->init_termios.c_iflag = 0; smd_tty_driver->init_termios.c_oflag = 0; smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; smd_tty_driver->init_termios.c_lflag = 0; smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(smd_tty_driver, &smd_tty_ops); ret = tty_register_driver(smd_tty_driver); if (ret) { put_tty_driver(smd_tty_driver); pr_err("%s: driver registration failed %d\n", __func__, ret); return ret; } for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; if (smd_configs[n].dev_name == NULL) smd_configs[n].dev_name = smd_configs[n].port_name; if (idx == DS_IDX) { int legacy_ds = 0; legacy_ds |= cpu_is_msm7x01() || cpu_is_msm7x25(); legacy_ds |= cpu_is_msm7x27() || cpu_is_msm7x30(); legacy_ds |= cpu_is_qsd8x50() || cpu_is_msm8x55(); legacy_ds |= (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm8930aa()) && (board_mfg_mode() == 8); legacy_ds |= cpu_is_msm8x60() && (socinfo_get_platform_subtype() == 0x0); #ifdef CONFIG_MACH_DUMMY legacy_ds = 1; #endif if (!legacy_ds) continue; } tty_register_device(smd_tty_driver, idx, 0); init_completion(&smd_tty[idx].ch_allocated); smd_tty[idx].driver.probe = smd_tty_dummy_probe; smd_tty[idx].driver.driver.name = smd_configs[n].dev_name; smd_tty[idx].driver.driver.owner = THIS_MODULE; spin_lock_init(&smd_tty[idx].reset_lock); smd_tty[idx].is_open = 0; setup_timer(&smd_tty[idx].buf_req_timer, buf_req_retry, (unsigned long)&smd_tty[idx]); init_waitqueue_head(&smd_tty[idx].ch_opened_wait_queue); ret = platform_driver_register(&smd_tty[idx].driver); if (ret) { pr_err("%s: init failed %d (%d)\n", __func__, idx, ret); smd_tty[idx].driver.probe = NULL; goto out; } smd_tty[idx].smd = &smd_configs[n]; } INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker); return 0; out: for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; if (smd_tty[idx].driver.probe) { platform_driver_unregister(&smd_tty[idx].driver); tty_unregister_device(smd_tty_driver, idx); } } tty_unregister_driver(smd_tty_driver); put_tty_driver(smd_tty_driver); return ret; }
static int __init tty0tty_init(void) { int retval; int i; if (pairs > 128) pairs = 128; if (pairs < 1) pairs = 1; tport = kmalloc(2 * pairs * sizeof(struct tty_port), GFP_KERNEL); tty0tty_table = kmalloc(2 * pairs * sizeof(struct tty0tty_serial *), GFP_KERNEL); for (i = 0; i < 2 * pairs; i++) { tty0tty_table[i] = NULL; } #ifdef SCULL_DEBUG printk(KERN_DEBUG "%s - \n", __FUNCTION__); #endif /* allocate the tty driver */ tty0tty_tty_driver = alloc_tty_driver(2 * pairs); if (!tty0tty_tty_driver) return -ENOMEM; /* initialize the tty driver */ tty0tty_tty_driver->owner = THIS_MODULE; tty0tty_tty_driver->driver_name = "tty0tty"; tty0tty_tty_driver->name = "tnt"; /* no more devfs subsystem */ tty0tty_tty_driver->major = TTY0TTY_MAJOR; tty0tty_tty_driver->minor_start = TTY0TTY_MINOR; tty0tty_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; tty0tty_tty_driver->subtype = SERIAL_TYPE_NORMAL; tty0tty_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; /* no more devfs subsystem */ tty0tty_tty_driver->init_termios = tty_std_termios; tty0tty_tty_driver->init_termios.c_iflag = 0; tty0tty_tty_driver->init_termios.c_oflag = 0; tty0tty_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; tty0tty_tty_driver->init_termios.c_lflag = 0; tty0tty_tty_driver->init_termios.c_ispeed = 38400; tty0tty_tty_driver->init_termios.c_ospeed = 38400; tty_set_operations(tty0tty_tty_driver, &serial_ops); for (i = 0; i < 2 * pairs; i++) { tty_port_init(&tport[i]); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) tty_port_link_device(&tport[i], tty0tty_tty_driver, i); #endif } retval = tty_register_driver(tty0tty_tty_driver); if (retval) { printk(KERN_ERR "failed to register tty0tty tty driver"); put_tty_driver(tty0tty_tty_driver); return retval; } printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n"); return retval; }
/** * ehv_bc_init - ePAPR hypervisor byte channel driver initialization * * This function is called when this module is loaded. */ static int __init ehv_bc_init(void) { struct device_node *np; unsigned int count = 0; /* Number of elements in bcs[] */ int ret; pr_info("ePAPR hypervisor byte channel driver\n"); /* Count the number of byte channels */ for_each_compatible_node(np, NULL, "epapr,hv-byte-channel") count++; if (!count) return -ENODEV; /* The array index of an element in bcs[] is the same as the tty index * for that element. If you know the address of an element in the * array, then you can use pointer math (e.g. "bc - bcs") to get its * tty index. */ bcs = kzalloc(count * sizeof(struct ehv_bc_data), GFP_KERNEL); if (!bcs) return -ENOMEM; ehv_bc_driver = alloc_tty_driver(count); if (!ehv_bc_driver) { ret = -ENOMEM; goto error; } ehv_bc_driver->driver_name = "ehv-bc"; ehv_bc_driver->name = ehv_bc_console.name; ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE; ehv_bc_driver->subtype = SYSTEM_TYPE_CONSOLE; ehv_bc_driver->init_termios = tty_std_termios; ehv_bc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(ehv_bc_driver, &ehv_bc_ops); ret = tty_register_driver(ehv_bc_driver); if (ret) { pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); goto error; } ret = platform_driver_register(&ehv_bc_tty_driver); if (ret) { pr_err("ehv-bc: could not register platform driver (ret=%i)\n", ret); goto error; } return 0; error: if (ehv_bc_driver) { tty_unregister_driver(ehv_bc_driver); put_tty_driver(ehv_bc_driver); } kfree(bcs); return ret; }
static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, unsigned int slot) { int res; int i; struct tty_driver *tty; char name[20]; struct ipoctal_channel *channel; struct ipack_region *region; void __iomem *addr; union scc2698_channel __iomem *chan_regs; union scc2698_block __iomem *block_regs; ipoctal->board_id = ipoctal->dev->id_device; region = &ipoctal->dev->region[IPACK_IO_SPACE]; addr = devm_ioremap_nocache(&ipoctal->dev->dev, region->start, region->size); if (!addr) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] IO space!\n", bus_nr, slot); return -EADDRNOTAVAIL; } /* Save the virtual address to access the registers easily */ chan_regs = (union scc2698_channel __iomem *) addr; block_regs = (union scc2698_block __iomem *) addr; region = &ipoctal->dev->region[IPACK_INT_SPACE]; ipoctal->int_space = devm_ioremap_nocache(&ipoctal->dev->dev, region->start, region->size); if (!ipoctal->int_space) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] INT space!\n", bus_nr, slot); return -EADDRNOTAVAIL; } region = &ipoctal->dev->region[IPACK_MEM8_SPACE]; ipoctal->mem8_space = devm_ioremap_nocache(&ipoctal->dev->dev, region->start, 0x8000); if (!ipoctal->mem8_space) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] MEM8 space!\n", bus_nr, slot); return -EADDRNOTAVAIL; } /* Disable RX and TX before touching anything */ for (i = 0; i < NR_CHANNELS ; i++) { struct ipoctal_channel *channel = &ipoctal->channel[i]; channel->regs = chan_regs + i; channel->block_regs = block_regs + (i >> 1); channel->board_id = ipoctal->board_id; if (i & 1) { channel->isr_tx_rdy_mask = ISR_TxRDY_B; channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B; } else { channel->isr_tx_rdy_mask = ISR_TxRDY_A; channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A; } iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); channel->rx_enable = 0; iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY, &channel->regs->w.mr); /* mr1 */ iowrite8(0, &channel->regs->w.mr); /* mr2 */ iowrite8(TX_CLK_9600 | RX_CLK_9600, &channel->regs->w.csr); } for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr); iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN, &block_regs[i].w.opcr); iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A | IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B, &block_regs[i].w.imr); } /* * IP-OCTAL has different addresses to copy its IRQ vector. * Depending of the carrier these addresses are accesible or not. * More info in the datasheet. */ ipoctal->dev->bus->ops->request_irq(ipoctal->dev, ipoctal_irq_handler, ipoctal); /* Dummy write */ iowrite8(1, ipoctal->mem8_space + 1); /* Register the TTY device */ /* Each IP-OCTAL channel is a TTY port */ tty = alloc_tty_driver(NR_CHANNELS); if (!tty) return -ENOMEM; /* Fill struct tty_driver with ipoctal data */ tty->owner = THIS_MODULE; tty->driver_name = KBUILD_MODNAME; sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); tty->name = name; tty->major = 0; tty->minor_start = 0; tty->type = TTY_DRIVER_TYPE_SERIAL; tty->subtype = SERIAL_TYPE_NORMAL; tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty->init_termios = tty_std_termios; tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; tty->init_termios.c_ispeed = 9600; tty->init_termios.c_ospeed = 9600; tty_set_operations(tty, &ipoctal_fops); res = tty_register_driver(tty); if (res) { dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); put_tty_driver(tty); return res; } /* Save struct tty_driver for use it when uninstalling the device */ ipoctal->tty_drv = tty; for (i = 0; i < NR_CHANNELS; i++) { struct device *tty_dev; channel = &ipoctal->channel[i]; tty_port_init(&channel->tty_port); tty_port_alloc_xmit_buf(&channel->tty_port); channel->tty_port.ops = &ipoctal_tty_port_ops; ipoctal_reset_stats(&channel->stats); channel->nb_bytes = 0; spin_lock_init(&channel->lock); channel->pointer_read = 0; channel->pointer_write = 0; tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); tty_port_destroy(&channel->tty_port); continue; } dev_set_drvdata(tty_dev, channel); } return 0; }
int micvcons_create(int num_bds) { micvcons_port_t *port; bd_info_t *bd_info; int bd, ret = 0; char wq_name[14]; struct device *dev; INIT_LIST_HEAD(&timer_list_head); if (micvcons_tty) goto exit; micvcons_tty = alloc_tty_driver(num_bds); if (!micvcons_tty) { ret = -ENOMEM; goto exit; } micvcons_tty->owner = THIS_MODULE; micvcons_tty->driver_name = MICVCONS_DEVICE_NAME; micvcons_tty->name = MICVCONS_DEVICE_NAME; micvcons_tty->major = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) micvcons_tty->minor_num = num_bds; #endif micvcons_tty->minor_start = 0; micvcons_tty->type = TTY_DRIVER_TYPE_SERIAL; micvcons_tty->subtype = SERIAL_TYPE_NORMAL; micvcons_tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; micvcons_tty->init_termios = tty_std_termios; micvcons_tty->init_termios.c_iflag = IGNCR; micvcons_tty->init_termios.c_oflag = 0; micvcons_tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; micvcons_tty->init_termios.c_lflag = 0; tty_set_operations(micvcons_tty, &micvcons_tty_ops); if ((ret = tty_register_driver(micvcons_tty)) != 0) { printk("Failed to register vcons tty driver\n"); put_tty_driver(micvcons_tty); micvcons_tty = NULL; goto exit; } for (bd = 0; bd < num_bds; bd++) { port = &mic_data.dd_ports[bd]; port->dp_bdinfo = mic_data.dd_bi[bd]; spin_lock_init(&port->dp_lock); mutex_init (&port->dp_mutex); bd_info = (bd_info_t *)port->dp_bdinfo; bd_info->bi_port = port; dev = tty_register_device(micvcons_tty, bd, NULL); if (IS_ERR(dev)) { printk("Failed to register vcons tty device\n"); micvcons_destroy(bd); ret = PTR_ERR(dev); goto exit; } snprintf(wq_name, sizeof(wq_name), "VCONS MIC %d", bd); port->dp_wq = create_singlethread_workqueue(wq_name); if (!port->dp_wq) { printk(KERN_ERR "%s: create_singlethread_workqueue\n", __func__); tty_unregister_device(micvcons_tty, bd); micvcons_destroy(bd); ret = -ENOMEM; goto exit; } INIT_WORK(&port->dp_wakeup_read_buf, micvcons_wakeup_readbuf); } vcons_timer.function = micvcons_timeout; vcons_timer.data = (unsigned long)(&timer_list_head); init_timer(&vcons_timer); exit: return ret; }
/* * The serial driver boot-time initialization code! */ static int __init amiga_serial_probe(struct platform_device *pdev) { unsigned long flags; struct serial_state * state; int error; serial_driver = alloc_tty_driver(NR_PORTS); if (!serial_driver) return -ENOMEM; show_serial_version(); /* Initialize the tty_driver structure */ serial_driver->driver_name = "amiserial"; serial_driver->name = "ttyS"; serial_driver->major = TTY_MAJOR; serial_driver->minor_start = 64; serial_driver->type = TTY_DRIVER_TYPE_SERIAL; serial_driver->subtype = SERIAL_TYPE_NORMAL; serial_driver->init_termios = tty_std_termios; serial_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; serial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(serial_driver, &serial_ops); error = tty_register_driver(serial_driver); if (error) goto fail_put_tty_driver; state = rs_table; state->port = (int)&custom.serdatr; /* Just to give it a value */ state->custom_divisor = 0; state->icount.cts = state->icount.dsr = state->icount.rng = state->icount.dcd = 0; state->icount.rx = state->icount.tx = 0; state->icount.frame = state->icount.parity = 0; state->icount.overrun = state->icount.brk = 0; tty_port_init(&state->tport); state->tport.ops = &amiga_port_ops; printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); /* Hardware set up */ state->baud_base = amiga_colorclock; state->xmit_fifo_size = 1; /* set ISRs, and then disable the rx interrupts */ error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); if (error) goto fail_unregister; error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, 0, "serial RX", state); if (error) goto fail_free_irq; local_irq_save(flags); /* turn off Rx and Tx interrupts */ custom.intena = IF_RBF | IF_TBE; mb(); /* clear any pending interrupt */ custom.intreq = IF_RBF | IF_TBE; mb(); local_irq_restore(flags); /* * set the appropriate directions for the modem control flags, * and clear RTS and DTR */ ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */ ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */ platform_set_drvdata(pdev, state); return 0; fail_free_irq: free_irq(IRQ_AMIGA_TBE, state); fail_unregister: tty_unregister_driver(serial_driver); fail_put_tty_driver: put_tty_driver(serial_driver); return error; }
int uart_register_driver(struct uart_driver *drv) { struct tty_driver *normal; int i, retval; BUG_ON(drv->state); drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL); if (!drv->state) goto out; normal = alloc_tty_driver(drv->nr); if (!normal) goto out_kfree; drv->tty_driver = normal; normal->driver_name = drv->driver_name; normal->name = drv->dev_name; normal->major = drv->major; normal->minor_start = drv->minor; normal->type = TTY_DRIVER_TYPE_SERIAL; normal->subtype = SERIAL_TYPE_NORMAL; normal->init_termios = tty_std_termios; normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600; normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; normal->driver_state = drv; tty_set_operations(normal, &uart_ops); for (i = 0; i < drv->nr; i++) { struct uart_state *state = drv->state + i; struct tty_port *port = &state->port; tty_port_init(port); port->ops = &uart_port_ops; port->close_delay = HZ / 2; port->closing_wait = 30 * HZ; } retval = tty_register_driver(normal); #ifdef CONFIG_IMC_UART2DM_HANDSHAKE if (!strcmp(drv->driver_name, "msm_serial_hs_imc")) { if (get_kernel_flag() & BIT(20)){ uart2_handshaking_mask = 1; printk(KERN_DEBUG MODULE_NAME " %s enable uart2 handshaking debug msg\n", __func__); } } #endif if (retval >= 0) return retval; put_tty_driver(normal); out_kfree: kfree(drv->state); out: return -ENOMEM; }
static int __init smd_tty_init(void) { int ret; int n; int idx; smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); if (smd_tty_driver == 0) return -ENOMEM; smd_tty_driver->owner = THIS_MODULE; smd_tty_driver->driver_name = "smd_tty_driver"; smd_tty_driver->name = "smd"; smd_tty_driver->major = 0; smd_tty_driver->minor_start = 0; smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; smd_tty_driver->init_termios = tty_std_termios; smd_tty_driver->init_termios.c_iflag = 0; smd_tty_driver->init_termios.c_oflag = 0; smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; smd_tty_driver->init_termios.c_lflag = 0; smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(smd_tty_driver, &smd_tty_ops); ret = tty_register_driver(smd_tty_driver); if (ret) { put_tty_driver(smd_tty_driver); pr_err("%s: driver registration failed %d\n", __func__, ret); return ret; } for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; if (smd_configs[n].dev_name == NULL) smd_configs[n].dev_name = smd_configs[n].port_name; if (idx == DS_IDX) { /* * DS port uses the kernel API starting with * 8660 Fusion. Only register the userspace * platform device for older targets. */ int legacy_ds = 0; legacy_ds |= cpu_is_msm7x01() || cpu_is_msm7x25(); legacy_ds |= cpu_is_msm7x27() || cpu_is_msm7x30(); legacy_ds |= cpu_is_qsd8x50() || cpu_is_msm8x55(); /* * use legacy mode for 8660 Standalone (subtype 0) */ legacy_ds |= cpu_is_msm8x60() && (socinfo_get_platform_subtype() == 0x0); if (!legacy_ds) continue; } tty_register_device(smd_tty_driver, idx, 0); init_completion(&smd_tty[idx].ch_allocated); /* register platform device */ smd_tty[idx].driver.probe = smd_tty_dummy_probe; smd_tty[idx].driver.driver.name = smd_configs[n].dev_name; smd_tty[idx].driver.driver.owner = THIS_MODULE; spin_lock_init(&smd_tty[idx].reset_lock); smd_tty[idx].is_open = 0; init_waitqueue_head(&smd_tty[idx].ch_opened_wait_queue); ret = platform_driver_register(&smd_tty[idx].driver); if (ret) { pr_err("%s: init failed %d (%d)\n", __func__, idx, ret); smd_tty[idx].driver.probe = NULL; goto out; } smd_tty[idx].smd = &smd_configs[n]; } INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker); return 0; out: /* unregister platform devices */ for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; if (smd_tty[idx].driver.probe) { platform_driver_unregister(&smd_tty[idx].driver); tty_unregister_device(smd_tty_driver, idx); } } tty_unregister_driver(smd_tty_driver); put_tty_driver(smd_tty_driver); return ret; }
static int multipdp_vs_read(struct pdp_info *dev, char *buf, size_t len) { int ret = 0; if (!dev) { return 0; } #ifndef NO_TTY_RX_BUFF if(len > 1500) { #else if(len > MAX_RX_BUFF_LEN) { #endif unsigned char *prx_buf = kzalloc(len, GFP_ATOMIC); if(prx_buf == NULL) return 0; memcpy(prx_buf, buf, len); ret = len; if(ret != len) return ret; if(dev->vs_dev.tty == NULL) printk(">>>>> TTY is NULL : (1)~ !!!! \n"); if (ret > 0 && dev->vs_dev.tty != NULL) { ret = multipdp_tty_insert_data(dev->vs_dev.tty, prx_buf, ret); if( ret > 0 ) tty_flip_buffer_push(dev->vs_dev.tty); } printk("RF cal data read.(1) len: %d ret: %d\n", len, ret); kfree(prx_buf); } else { /* pdp data length.. */ memcpy(pdp_rx_buf, buf, len); ret = len; if (ret != len) { return ret; } #ifdef LOOP_BACK_TEST if (dev->id == LOOP_BACK_CHANNEL) { // compare and resend , update stastic data //printk("receive loopback packet[%d]\n",loopback_res.nTransfered); //printk("read data : %x %x %x %x %x %x\n",pdp_rx_buf[0],pdp_rx_buf[1],pdp_rx_buf[2],pdp_rx_buf[3],pdp_rx_buf[4],pdp_rx_buf[5]); //printk("write data : %x %x %x %x %x %x\n",loopback_data[0],loopback_data[1],loopback_data[2],loopback_data[3],loopback_data[4],loopback_data[5]); if (loopback_ongoing) { if (strncmp(pdp_rx_buf, loopback_data, loopback_res.nPacketDataSize)){ //printk("receive packet is not identical to that sent\n"); } else { send_loop_back_packet(loopback_data, loopback_res.nPacketDataSize); } } else { //do nothing //printk("loopback channel has gotten data, but test is no ongoing\n"); } } else if (ret > 0 && dev->vs_dev.tty != NULL) { tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, ret); tty_flip_buffer_push(dev->vs_dev.tty); } #else if(dev->vs_dev.tty == NULL) printk(">>>>> TTY is NULL : (2)~ !!!! \n"); if (ret > 0 && dev->vs_dev.tty != NULL) { #if 1 ret = multipdp_tty_insert_data(dev->vs_dev.tty, pdp_rx_buf, ret); #else ret = tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, ret); #endif if( ret > 0 ) tty_flip_buffer_push(dev->vs_dev.tty); } //printk("RF cal data read.(2) len: %d ret: %d\n", len, ret); #endif } //printk("multipdp_vs_read : len = %d\n", ret); return ret; } //////////// #endif static int vs_read(struct pdp_info *dev, size_t len) { int retval = 0; u32 size; u32 copied_size; int insert_size = 0; if (dev) { /* pdp data length. */ if (len > MAX_PDP_DATA_LEN) { // RF cal data? DPRINTK(1, "CAL DATA\n"); size = dpram_read(dpram_filp, prx_buf, len); DPRINTK(1, "multipdp_thread request read size : %d readed size %d, count : %d\n",len ,size,count); #ifdef CONFIG_ENABLE_TTY_CIQ if ((dev->id == 26 && !fp_vsCIQ0) ||(dev->id == 9 && !fp_vsCIQ1)||(dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)){ #else if ((dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)){ #endif EPRINTK("vs_read : %s, discard data.\n", dev->vs_dev.tty->name); } else { while (size) { copied_size = (size > MAX_PDP_DATA_LEN) ? MAX_PDP_DATA_LEN : size; if (size > 0 && dev->vs_dev.tty != NULL) insert_size = tty_insert_flip_string(dev->vs_dev.tty, prx_buf+retval, copied_size); if (insert_size != copied_size) { EPRINTK("flip buffer full : %s, insert size : %d, real size : %d\n",dev->vs_dev.tty->name,copied_size,insert_size); return -1; } size = size - copied_size; retval += copied_size; } DPRINTK(1, "retval : %d\n",retval); tty_flip_buffer_push(dev->vs_dev.tty); count++; } } else { retval = dpram_read(dpram_filp, pdp_rx_buf, len); if (retval != len) return retval; if(retval > 0){ #ifdef CONFIG_ENABLE_TTY_CIQ if((dev->id == 26 && !fp_vsCIQ0) ||(dev->id == 9 && !fp_vsCIQ1) ||( dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { #else if((dev->id == 1 && !fp_vsCSD) || (dev->id == 5 && !fp_vsGPS) || (dev->id == 8 && !fp_vsEFS)|| (dev->id == 25 && !fp_vsSMD)) { #endif EPRINTK("vs_read : %s, discard data.\n", dev->vs_dev.tty->name); } else { insert_size = tty_insert_flip_string(dev->vs_dev.tty, pdp_rx_buf, retval); if (insert_size != retval) { EPRINTK("flip buffer full : %s, insert size : %d, real size : %d\n",dev->vs_dev.tty->name,retval,insert_size); return -1; } tty_flip_buffer_push(dev->vs_dev.tty); } } } } return 0; } static int vs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { return -ENOIOCTLCMD; } #if 0 static void vs_break_ctl(struct tty_struct *tty, int break_state) { } #endif static struct tty_operations multipdp_tty_ops = { .open = vs_open, .close = vs_close, .write = vs_write, .write_room = vs_write_room, .ioctl = vs_ioctl, .chars_in_buffer = vs_chars_in_buffer, /* TODO: add more operations */ }; static int vs_add_dev(struct pdp_info *dev) { struct tty_driver *tty_driver; tty_driver = get_tty_driver_by_id(dev); kref_init(&tty_driver->kref); tty_driver->magic = TTY_DRIVER_MAGIC; tty_driver->driver_name = "multipdp"; tty_driver->name = dev->vs_dev.tty_name; tty_driver->major = CSD_MAJOR_NUM; tty_driver->minor_start = get_minor_start_index(dev->id); tty_driver->num = 1; tty_driver->type = TTY_DRIVER_TYPE_SERIAL; tty_driver->subtype = SERIAL_TYPE_NORMAL; tty_driver->flags = TTY_DRIVER_REAL_RAW; // tty_driver->refcount = dev->vs_dev.refcount; tty_driver->ttys = dev->vs_dev.tty_table; // 2.6 kernel porting tty_driver->termios = dev->vs_dev.termios; tty_driver->termios_locked = dev->vs_dev.termios_locked; tty_set_operations(tty_driver, &multipdp_tty_ops); return tty_register_driver(tty_driver); } static void vs_del_dev(struct pdp_info *dev) { struct tty_driver *tty_driver = NULL; tty_driver = get_tty_driver_by_id(dev); tty_unregister_driver(tty_driver); return; } /* * PDP context and mux/demux functions */ static inline struct pdp_info * pdp_get_dev(u8 id) { int slot; for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { if (pdp_table[slot] && pdp_table[slot]->id == id) { return pdp_table[slot]; } } return NULL; } static inline struct pdp_info * pdp_get_serdev(const char *name) { int slot; struct pdp_info *dev; for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { dev = pdp_table[slot]; if (dev && dev->type == DEV_TYPE_SERIAL && strcmp(name, dev->vs_dev.tty_name) == 0) { return dev; } } return NULL; }
int gserial_setup(struct usb_gadget *g, unsigned count) { unsigned i; struct usb_cdc_line_coding coding; int status; if (count == 0 || count > N_PORTS) return -EINVAL; gs_tty_driver = alloc_tty_driver(count); if (!gs_tty_driver) return -ENOMEM; gs_tty_driver->owner = THIS_MODULE; gs_tty_driver->driver_name = "g_serial"; gs_tty_driver->name = PREFIX; gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; gs_tty_driver->init_termios = tty_std_termios; gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; gs_tty_driver->init_termios.c_ispeed = 9600; gs_tty_driver->init_termios.c_ospeed = 9600; coding.dwDTERate = cpu_to_le32(9600); coding.bCharFormat = 8; coding.bParityType = USB_CDC_NO_PARITY; coding.bDataBits = USB_CDC_1_STOP_BITS; tty_set_operations(gs_tty_driver, &gs_tty_ops); gserial_wq = create_singlethread_workqueue("k_gserial"); if (!gserial_wq) { status = -ENOMEM; goto fail; } for (i = 0; i < count; i++) { mutex_init(&ports[i].lock); status = gs_port_alloc(i, &coding); if (status) { count = i; goto fail; } } n_ports = count; status = tty_register_driver(gs_tty_driver); if (status) { put_tty_driver(gs_tty_driver); pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } for (i = 0; i < count; i++) { struct device *tty_dev; tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); if (IS_ERR(tty_dev)) pr_warning("%s: no classdev for port %d, err %ld\n", __func__, i, PTR_ERR(tty_dev)); } pr_debug("%s: registered %d ttyGS* device%s\n", __func__, count, (count == 1) ? "" : "s"); return status; fail: while (count--) kfree(ports[count].port); destroy_workqueue(gserial_wq); put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; }
int rpmsg_neo_tty(struct rpmsg_channel *rpmsg_chnl,rpmsg_neo_remove_t *remove_func ) { int err = 0; struct rpmsgtty_port *cport = &rpmsg_tty_port; *remove_func = rpmsg_neo_tty_remove; memset(cport, 0, sizeof(rpmsg_tty_port)); cport->rpmsg_chnl = rpmsg_chnl; cport->endpt = RPMSG_TTY_ENPT; cport->ept = rpmsg_create_ept(cport->rpmsg_chnl, rpmsg_tty_cb, cport, cport->endpt); if (!cport->ept) { pr_err("ERROR: %s %s %d Failed to create proxy service endpoint.\n", __FILE__, __FUNCTION__, __LINE__); err = -1; goto error0; } rpmsgtty_driver = tty_alloc_driver(1, TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_UNNUMBERED_NODE); if (IS_ERR(rpmsgtty_driver)) { pr_err("ERROR:%s %d Failed to alloc tty\n", __FUNCTION__, __LINE__); rpmsg_destroy_ept(cport->ept); return PTR_ERR(rpmsgtty_driver); } spin_lock_init(&cport->rx_lock); cport->port.low_latency = cport->port.flags | ASYNC_LOW_LATENCY; tty_port_init(&cport->port); cport->port.ops = &rpmsgtty_port_ops; rpmsgtty_driver->driver_name = "ttyrpmsg"; rpmsgtty_driver->name = "ttyrpmsg"; rpmsgtty_driver->major = TTYAUX_MAJOR; rpmsgtty_driver->minor_start = 4; rpmsgtty_driver->type = TTY_DRIVER_TYPE_CONSOLE; rpmsgtty_driver->init_termios = tty_std_termios; // rpmsgtty_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; rpmsgtty_driver->init_termios.c_cflag |= CLOCAL; tty_set_operations(rpmsgtty_driver, &imxrpmsgtty_ops); tty_port_link_device(&cport->port, rpmsgtty_driver, 0); err = tty_register_driver(rpmsgtty_driver); if (err < 0) { pr_err("Couldn't install rpmsg tty driver: err %d\n", err); goto error; } else { pr_info("Install rpmsg tty driver!\n"); } return 0; error: put_tty_driver(rpmsgtty_driver); tty_port_destroy(&cport->port); rpmsgtty_driver = NULL; rpmsg_destroy_ept(cport->ept); error0: return err; }
/** * gserial_setup - initialize TTY driver for one or more ports * @g: gadget to associate with these ports * @count: how many ports to support * Context: may sleep * * The TTY stack needs to know in advance how many devices it should * plan to manage. Use this call to set up the ports you will be * exporting through USB. Later, connect them to functions based * on what configuration is activated by the USB host; and disconnect * them as appropriate. * * An example would be a two-configuration device in which both * configurations expose port 0, but through different functions. * One configuration could even expose port 1 while the other * one doesn't. * * Returns negative errno or zero. */ int gserial_setup(struct usb_gadget *g, unsigned count) { unsigned i; struct usb_cdc_line_coding coding; int status; if (count == 0 || count > N_PORTS) return -EINVAL; gs_tty_driver = alloc_tty_driver(count); if (!gs_tty_driver) return -ENOMEM; gs_tty_driver->driver_name = "g_serial"; gs_tty_driver->name = PREFIX; /* uses dynamically assigned dev_t values */ gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; gs_tty_driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on * MS-Windows. Otherwise, most of these flags shouldn't affect * anything unless we were to actually hook up to a serial line. */ gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; gs_tty_driver->init_termios.c_ispeed = 9600; gs_tty_driver->init_termios.c_ospeed = 9600; coding.dwDTERate = cpu_to_le32(9600); coding.bCharFormat = 8; coding.bParityType = USB_CDC_NO_PARITY; coding.bDataBits = USB_CDC_1_STOP_BITS; tty_set_operations(gs_tty_driver, &gs_tty_ops); gserial_wq = create_singlethread_workqueue("k_gserial"); if (!gserial_wq) { status = -ENOMEM; goto fail; } /* make devices be openable */ for (i = 0; i < count; i++) { mutex_init(&ports[i].lock); status = gs_port_alloc(i, &coding); if (status) { count = i; goto fail; } } n_ports = count; /* export the driver ... */ status = tty_register_driver(gs_tty_driver); if (status) { pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } /* ... and sysfs class devices, so mdev/udev make /dev/ttyGS* */ for (i = 0; i < count; i++) { struct device *tty_dev; tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); if (IS_ERR(tty_dev)) pr_warning("%s: no classdev for port %d, err %ld\n", __func__, i, PTR_ERR(tty_dev)); } for (i = 0; i < count; i++) usb_debugfs_init(ports[i].port, i); pr_debug("%s: registered %d ttyGS* device%s\n", __func__, count, (count == 1) ? "" : "s"); return status; fail: while (count--) kfree(ports[count].port); if (gserial_wq) destroy_workqueue(gserial_wq); put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; }
static int __init smd_tty_init(void) { int ret; int n; int idx; struct tty_port *port; smd_tty_log_init(); smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS); if (smd_tty_driver == 0) { SMD_TTY_ERR("%s - Driver allocation failed", __func__); return -ENOMEM; } smd_tty_driver->owner = THIS_MODULE; smd_tty_driver->driver_name = "smd_tty_driver"; smd_tty_driver->name = "smd"; smd_tty_driver->major = 0; smd_tty_driver->minor_start = 0; smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; smd_tty_driver->subtype = SERIAL_TYPE_NORMAL; smd_tty_driver->init_termios = tty_std_termios; smd_tty_driver->init_termios.c_iflag = 0; smd_tty_driver->init_termios.c_oflag = 0; smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; smd_tty_driver->init_termios.c_lflag = 0; smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(smd_tty_driver, &smd_tty_ops); ret = tty_register_driver(smd_tty_driver); if (ret) { put_tty_driver(smd_tty_driver); SMD_TTY_ERR("%s: driver registration failed %d", __func__, ret); return ret; } for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; if (smd_configs[n].dev_name == NULL) smd_configs[n].dev_name = smd_configs[n].port_name; if (idx == DS_IDX) { /* * DS port uses the kernel API starting with * 8660 Fusion. Only register the userspace * platform device for older targets. */ int legacy_ds = 0; legacy_ds |= cpu_is_msm7x01() || cpu_is_msm7x25(); legacy_ds |= cpu_is_msm7x27() || cpu_is_msm7x30(); legacy_ds |= cpu_is_qsd8x50() || cpu_is_msm8x55(); /* * use legacy mode for 8660 Standalone (subtype 0) */ legacy_ds |= cpu_is_msm8x60() && (socinfo_get_platform_subtype() == 0x0); #ifdef CONFIG_MSM_SMD_TTY_DS_LEGACY legacy_ds |= cpu_is_msm8974(); #endif if (!legacy_ds) continue; } port = &smd_tty[idx].port; tty_port_init(port); port->ops = &smd_tty_port_ops; /* TODO: For kernel >= 3.7 use tty_port_register_device */ smd_tty[idx].device_ptr = tty_register_device(smd_tty_driver, idx, 0); if (device_create_file(smd_tty[idx].device_ptr, &dev_attr_open_timeout)) SMD_TTY_ERR( "%s: Unable to create device attributes for %s", __func__, smd_configs[n].port_name); init_completion(&smd_tty[idx].ch_allocated); /* register platform device */ smd_tty[idx].driver.probe = smd_tty_dummy_probe; #ifdef CONFIG_MSM_SMD_TTY_DS_LEGACY if (idx == DS_IDX) { /* register platform device for DS */ smd_tty[idx].driver.probe = smd_tty_ds_probe; smd_tty[idx].is_dsmodem_ready = 0; } #endif smd_tty[idx].driver.driver.name = smd_configs[n].dev_name; smd_tty[idx].driver.driver.owner = THIS_MODULE; spin_lock_init(&smd_tty[idx].reset_lock); spin_lock_init(&smd_tty[idx].ra_lock); smd_tty[idx].is_open = 0; setup_timer(&smd_tty[idx].buf_req_timer, buf_req_retry, (unsigned long)&smd_tty[idx]); init_waitqueue_head(&smd_tty[idx].ch_opened_wait_queue); ret = platform_driver_register(&smd_tty[idx].driver); if (ret) { SMD_TTY_ERR( "%s: init failed %d (%d)", __func__, idx, ret); smd_tty[idx].driver.probe = NULL; goto out; } smd_tty[idx].smd = &smd_configs[n]; } INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker); return 0; out: /* unregister platform devices */ for (n = 0; n < ARRAY_SIZE(smd_configs); ++n) { idx = smd_configs[n].tty_dev_index; if (smd_tty[idx].driver.probe) { platform_driver_unregister(&smd_tty[idx].driver); tty_unregister_device(smd_tty_driver, idx); } } tty_unregister_driver(smd_tty_driver); put_tty_driver(smd_tty_driver); return ret; }
static void __init unix98_pty_init(void) { ptm_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX, TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM | TTY_DRIVER_DYNAMIC_ALLOC); if (IS_ERR(ptm_driver)) panic("Couldn't allocate Unix98 ptm driver"); pts_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX, TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM | TTY_DRIVER_DYNAMIC_ALLOC); if (IS_ERR(pts_driver)) panic("Couldn't allocate Unix98 pts driver"); ptm_driver->driver_name = "pty_master"; ptm_driver->name = "ptm"; ptm_driver->major = UNIX98_PTY_MASTER_MAJOR; ptm_driver->minor_start = 0; ptm_driver->type = TTY_DRIVER_TYPE_PTY; ptm_driver->subtype = PTY_TYPE_MASTER; ptm_driver->init_termios = tty_std_termios; ptm_driver->init_termios.c_iflag = 0; ptm_driver->init_termios.c_oflag = 0; ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; ptm_driver->init_termios.c_lflag = 0; ptm_driver->init_termios.c_ispeed = 38400; ptm_driver->init_termios.c_ospeed = 38400; ptm_driver->other = pts_driver; tty_set_operations(ptm_driver, &ptm_unix98_ops); pts_driver->driver_name = "pty_slave"; pts_driver->name = "pts"; pts_driver->major = UNIX98_PTY_SLAVE_MAJOR; pts_driver->minor_start = 0; pts_driver->type = TTY_DRIVER_TYPE_PTY; pts_driver->subtype = PTY_TYPE_SLAVE; pts_driver->init_termios = tty_std_termios; pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; pts_driver->init_termios.c_ispeed = 38400; pts_driver->init_termios.c_ospeed = 38400; pts_driver->other = ptm_driver; tty_set_operations(pts_driver, &pty_unix98_ops); if (tty_register_driver(ptm_driver)) panic("Couldn't register Unix98 ptm driver"); if (tty_register_driver(pts_driver)) panic("Couldn't register Unix98 pts driver"); /* Now create the /dev/ptmx special device */ tty_default_fops(&ptmx_fops); ptmx_fops.open = ptmx_open; cdev_init(&ptmx_cdev, &ptmx_fops); if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) panic("Couldn't register /dev/ptmx driver"); device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); }
static int __init hsic_tty_init(void) { int ret; int n; unsigned port_num; pr_debug("%s\n", __func__); hsic_tty_driver = alloc_tty_driver(MAX_HSIC_TTYS); if (hsic_tty_driver == 0) return -ENOMEM; hsic_tty_driver->owner = THIS_MODULE; hsic_tty_driver->driver_name = "hsic_tty_driver"; hsic_tty_driver->name = "hsic"; hsic_tty_driver->major = 0; hsic_tty_driver->minor_start = 0; hsic_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; hsic_tty_driver->subtype = SERIAL_TYPE_NORMAL; hsic_tty_driver->init_termios = tty_std_termios; hsic_tty_driver->init_termios.c_iflag = 0; hsic_tty_driver->init_termios.c_oflag = 0; hsic_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; hsic_tty_driver->init_termios.c_lflag = 0; hsic_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(hsic_tty_driver, &hsic_tty_ops); ret = tty_register_driver(hsic_tty_driver); if (ret) { put_tty_driver(hsic_tty_driver); pr_err("%s: driver registration failed %d\n", __func__, ret); return ret; } port_num = hsic_tty_data_setup(1, HSIC_TTY_SERIAL); if (port_num < 0) { pr_err("%s: hsic_tty_data_setup failed\n", __func__); goto out; } ret = hsic_tty_ctrl_setup(1, HSIC_TTY_SERIAL); if (ret < 0) { pr_err("%s: hsic_tty_ctrl_setup failed\n", __func__); goto out; } hsic_tty.client_port_num = port_num; #ifdef CONFIG_MODEM_SUPPORT spin_lock_init(&hsic_tty.lock); spin_lock_init(&hsic_tty.reset_lock); hsic_tty.connect = hsic_tty_connect; hsic_tty.get_dtr = hsic_tty_get_dtr; hsic_tty.get_rts = hsic_tty_get_rts; hsic_tty.send_carrier_detect = hsic_tty_send_carrier_detect; hsic_tty.send_ring_indicator = hsic_tty_send_ring_indicator; hsic_tty.send_modem_ctrl_bits = hsic_tty_send_modem_ctrl_bits; hsic_tty.disconnect = hsic_tty_disconnect; hsic_tty.send_break = hsic_tty_send_break;; #endif hsic_tty.tty = NULL; ret = hsic_tty_ctrl_connect(&hsic_tty, port_num); if (ret) { pr_err("%s: hsic_tty_ctrl_connect failed: err:%d\n", __func__, ret); goto out; } ret = hsic_tty_data_connect(&hsic_tty, port_num); if (ret) { pr_err("%s: hsic_tty_data_connect failed: err:%d\n", __func__, ret); hsic_tty_ctrl_disconnect(&hsic_tty, port_num); goto out; } for (n = 0; n < MAX_HSIC_TTYS; ++n) { pr_info("%s: %d\n", __func__, n); tty_register_device(hsic_tty_driver, n, 0); } return 0; out: tty_unregister_driver(hsic_tty_driver); put_tty_driver(hsic_tty_driver); return ret; }