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_DESC "\n"); return 0; }
/** * gserial_cleanup - remove TTY-over-USB driver and devices * Context: may sleep * * This is called to free all resources allocated by @gserial_setup(). * Accordingly, it may need to wait until some open /dev/ files have * closed. * * The caller must have issued @gserial_disconnect() for any ports * that had previously been connected, so that there is never any * I/O pending when it's called. */ void gserial_cleanup(void) { unsigned i; struct gs_port *port; if (!gs_tty_driver) return; /* start sysfs and /dev/ttyGS* node removal */ for (i = 0; i < n_ports; i++) tty_unregister_device(gs_tty_driver, i); for (i = 0; i < n_ports; i++) { /* prevent new opens */ mutex_lock(&ports[i].lock); port = ports[i].port; ports[i].port = NULL; mutex_unlock(&ports[i].lock); tasklet_kill(&port->push); /* wait for old opens to finish */ wait_event(port->close_wait, gs_closed(port)); WARN_ON(port->port_usb != NULL); kfree(port); } n_ports = 0; tty_unregister_driver(gs_tty_driver); put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; pr_debug("%s: cleaned up ttyGS* support\n", __func__); }
static int scc_init_drivers(void) { int error; memset(&scc_driver, 0, sizeof(scc_driver)); scc_driver.magic = TTY_DRIVER_MAGIC; scc_driver.driver_name = "scc"; #ifdef CONFIG_DEVFS_FS scc_driver.name = "tts/%d"; #else scc_driver.name = "ttyS"; #endif scc_driver.major = TTY_MAJOR; scc_driver.minor_start = SCC_MINOR_BASE; scc_driver.num = 2; scc_driver.type = TTY_DRIVER_TYPE_SERIAL; scc_driver.subtype = SERIAL_TYPE_NORMAL; scc_driver.init_termios = tty_std_termios; scc_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; scc_driver.flags = TTY_DRIVER_REAL_RAW; scc_driver.refcount = &scc_refcount; scc_driver.table = scc_table; scc_driver.termios = scc_termios; scc_driver.termios_locked = scc_termios_locked; scc_driver.open = scc_open; scc_driver.close = gs_close; scc_driver.write = gs_write; scc_driver.put_char = gs_put_char; scc_driver.flush_chars = gs_flush_chars; scc_driver.write_room = gs_write_room; scc_driver.chars_in_buffer = gs_chars_in_buffer; scc_driver.flush_buffer = gs_flush_buffer; scc_driver.ioctl = scc_ioctl; scc_driver.throttle = scc_throttle; scc_driver.unthrottle = scc_unthrottle; scc_driver.set_termios = gs_set_termios; scc_driver.stop = gs_stop; scc_driver.start = gs_start; scc_driver.hangup = gs_hangup; scc_driver.break_ctl = scc_break_ctl; scc_callout_driver = scc_driver; #ifdef CONFIG_DEVFS_FS scc_callout_driver.name = "cua/%d"; #else scc_callout_driver.name = "cua"; #endif scc_callout_driver.major = TTYAUX_MAJOR; scc_callout_driver.subtype = SERIAL_TYPE_CALLOUT; if ((error = tty_register_driver(&scc_driver))) { printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n", error); return 1; } if ((error = tty_register_driver(&scc_callout_driver))) { tty_unregister_driver(&scc_driver); printk(KERN_ERR "scc: Couldn't register scc callout driver, error = %d\n", error); return 1; } return 0; }
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 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; }
static void __exit acm_exit(void) { usb_deregister(&acm_driver); tty_unregister_driver(acm_tty_driver); put_tty_driver(acm_tty_driver); }
/* * Initialize the serial port */ void __init tx3912_rs_init(void) { func_enter(); rs_dprintk(TX3912_UART_DEBUG_INIT, "Initializing serial...\n"); /* Allocate critical structures */ if(!(rs_tty = kmalloc(sizeof(struct tty_struct), GFP_KERNEL))) { return; } if(!(rs_port = kmalloc(sizeof(struct rs_port), GFP_KERNEL))) { kfree(rs_tty); return; } if(!(rs_termios = kmalloc(sizeof(struct termios), GFP_KERNEL))) { kfree(rs_port); kfree(rs_tty); return; } if(!(rs_termios_locked = kmalloc(sizeof(struct termios), GFP_KERNEL))) { kfree(rs_termios); kfree(rs_port); kfree(rs_tty); return; } /* Zero out the structures */ memset(rs_tty, 0, sizeof(struct tty_struct)); memset(rs_port, 0, sizeof(struct rs_port)); memset(rs_termios, 0, sizeof(struct termios)); memset(rs_termios_locked, 0, sizeof(struct termios)); memset(&rs_driver, 0, sizeof(rs_driver)); memset(&rs_callout_driver, 0, sizeof(rs_callout_driver)); /* Fill in hardware specific port structure */ rs_port->gs.callout_termios = tty_std_termios; rs_port->gs.normal_termios = tty_std_termios; rs_port->gs.magic = SERIAL_MAGIC; rs_port->gs.close_delay = HZ/2; rs_port->gs.closing_wait = 30 * HZ; rs_port->gs.rd = &rs_real_driver; #ifdef NEW_WRITE_LOCKING rs_port->gs.port_write_sem = MUTEX; #endif #ifdef DECLARE_WAITQUEUE init_waitqueue_head(&rs_port->gs.open_wait); init_waitqueue_head(&rs_port->gs.close_wait); #endif /* Fill in generic serial driver structures */ rs_driver.magic = TTY_DRIVER_MAGIC; rs_driver.driver_name = "serial"; rs_driver.name = "ttyS"; rs_driver.major = TTY_MAJOR; rs_driver.minor_start = 64; rs_driver.num = 1; rs_driver.type = TTY_DRIVER_TYPE_SERIAL; rs_driver.subtype = SERIAL_TYPE_NORMAL; rs_driver.init_termios = tty_std_termios; rs_driver.init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; rs_driver.refcount = &rs_refcount; rs_driver.table = rs_tty; rs_driver.termios = rs_termios; rs_driver.termios_locked = rs_termios_locked; rs_driver.open = rs_open; rs_driver.close = gs_close; rs_driver.write = gs_write; rs_driver.put_char = gs_put_char; rs_driver.flush_chars = gs_flush_chars; rs_driver.write_room = gs_write_room; rs_driver.chars_in_buffer = gs_chars_in_buffer; rs_driver.flush_buffer = gs_flush_buffer; rs_driver.ioctl = rs_ioctl; rs_driver.throttle = rs_throttle; rs_driver.unthrottle = rs_unthrottle; rs_driver.set_termios = gs_set_termios; rs_driver.stop = gs_stop; rs_driver.start = gs_start; rs_driver.hangup = gs_hangup; rs_callout_driver = rs_driver; rs_callout_driver.name = "cua"; rs_callout_driver.major = TTYAUX_MAJOR; rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT; /* Register serial and callout drivers */ if(tty_register_driver(&rs_driver)) { printk(KERN_ERR "Unable to register serial driver\n"); goto error; } if(tty_register_driver(&rs_callout_driver)) { tty_unregister_driver(&rs_driver); printk(KERN_ERR "Unable to register callout driver\n"); goto error; } /* Assign IRQs */ if(request_irq(2, rs_tx_interrupt, SA_SHIRQ, "uarta_tx", rs_port)) { printk(KERN_ERR "Cannot allocate IRQ for UARTA_TX.\n"); goto error; } if(request_irq(3, rs_rx_interrupt, SA_SHIRQ, "uarta_rx", rs_port)) { printk(KERN_ERR "Cannot allocate IRQ for UARTA_RX.\n"); goto error; } /* Enable the serial receive interrupt */ rs_enable_rx_interrupts(rs_port); #ifndef CONFIG_SERIAL_TX3912_CONSOLE /* Write the control registers */ outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_CTRL2); outl(0x00000000, TX3912_UARTA_DMA_CTRL1); outl(0x00000000, TX3912_UARTA_DMA_CTRL2); outl(inl(TX3912_UARTA_CTRL1) | TX3912_UART_CTRL1_ENUART, TX3912_UARTA_CTRL1); /* Loop until the UART is on */ while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON); #endif rs_initialized = 1; func_exit(); return; error: kfree(rs_termios_locked); kfree(rs_termios); kfree(rs_port); kfree(rs_tty); func_exit(); }
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 ipoctal_install_all(void) { int i, j, t; int res = 0; struct tty_driver *tty; char name[20] = ""; ipoctal_installed = (struct ipoctal*) kzalloc(num_lun * sizeof(struct ipoctal), GFP_KERNEL); if (ipoctal_installed == NULL) { printk(KERN_ERR PFX "Unable to allocate memory for ipoctal's !\n"); res = -ENOMEM; goto out_err; } for (i=0; i<num_lun;i++) { tty = alloc_tty_driver(NR_CHANNELS); if(!tty) return -ENOMEM; tty->owner = THIS_MODULE; tty->driver_name = "ipoctal"; sprintf(name, "ipoctal.%d.", lun[i]); 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->init_termios.c_iflag = tty_std_termios.c_iflag | IGNBRK; tty_set_operations(tty, &ipoctalFops); res = tty_register_driver(tty); if(res) { printk(KERN_ERR PFX "Can't register tty driver.\n"); put_tty_driver(tty); goto out_uninst; } for(j = 0; j < NR_CHANNELS;j++) { tty_register_device(tty, j, NULL); ipoctal_installed[i].tty[j] = NULL; spin_lock_init(&ipoctal_installed[i].lock[j]); mutex_init(&ipoctal_installed[i].lock_write[j]); ipoctal_installed[i].pointer_read[j] = 0; ipoctal_installed[i].pointer_write[j] = 0; ipoctal_installed[i].nb_bytes[j] = 0; } ipoctal_installed[i].tty_drv = tty; ipoctal_installed[i].index = i; res = ipoctal_inst_slot(&ipoctal_installed[i], carrier_number[i], slot[i], irq[i], carrier[i]); if (res) { printk(KERN_ERR PFX "Error during IP octal install !\n"); goto out_uninst; } } return 0; out_uninst : for (j=0; j < i;j++){ for (t = 0; t < NR_CHANNELS; t++) tty_unregister_device(ipoctal_installed[j].tty_drv, t); tty_unregister_driver(ipoctal_installed[j].tty_drv); ipoctal_uninst_slot(&ipoctal_installed[j]); } kfree(ipoctal_installed); ipoctal_installed = NULL; printk(KERN_ERR PFX "Unregistered all IP octal devices\n"); out_err : return res; }
static int __init lge_bypass_init(void) { int ret = 0; struct device *tty_dev = NULL; struct bypass_driver *bypass_drv = NULL; pr_info("%s\n", __func__); bypass_drv = kzalloc(sizeof(struct bypass_driver), GFP_KERNEL); if (!bypass_drv) { pr_err( "%s: memory alloc fail\n", __func__); return 0; } bypass_drv->tty_drv = alloc_tty_driver(BYPASS_MAX_DRV); if(!bypass_drv->tty_drv) { pr_err( "%s: tty alloc driver fail\n", __func__); kfree(bypass_drv); return 0; } bypass_drv->port = kzalloc(sizeof(struct tty_port), GFP_KERNEL); if(!bypass_drv->port) { pr_err( "%s: memory alloc port fail\n", __func__); kfree(bypass_drv->tty_drv); kfree(bypass_drv); return 0; } tty_port_init(bypass_drv->port); lge_bypass_drv = bypass_drv; bypass_drv->tty_drv->name = "lge_diag_bypass"; bypass_drv->tty_drv->owner = THIS_MODULE; bypass_drv->tty_drv->driver_name = "lge_diag_bypass"; bypass_drv->tty_drv->type = TTY_DRIVER_TYPE_SERIAL; bypass_drv->tty_drv->subtype = SERIAL_TYPE_NORMAL; bypass_drv->tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; bypass_drv->tty_drv->init_termios = tty_std_termios; bypass_drv->tty_drv->init_termios.c_iflag = IGNBRK | IGNPAR; bypass_drv->tty_drv->init_termios.c_oflag = 0; bypass_drv->tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; bypass_drv->tty_drv->init_termios.c_lflag = 0; tty_set_operations(bypass_drv->tty_drv, &lge_bypass_ops); #if defined(CONFIG_ARCH_MSM8916) || defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_ODIN) tty_port_link_device(bypass_drv->port, bypass_drv->tty_drv, 0); #endif ret = tty_register_driver(bypass_drv->tty_drv); if (ret) { pr_err("%s: fail to tty_register_driver\n", __func__); put_tty_driver(bypass_drv->tty_drv); #if defined(CONFIG_ARCH_MSM8916) || defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_ODIN) tty_port_destroy(bypass_drv->port); #endif bypass_drv->tty_drv = NULL; kfree(bypass_drv->port); kfree(bypass_drv); return 0; } tty_dev = tty_register_device(bypass_drv->tty_drv, 0, NULL); if (IS_ERR(tty_dev)) { pr_err("%s: fail to tty_register_device\n", __func__); tty_unregister_driver(bypass_drv->tty_drv); put_tty_driver(bypass_drv->tty_drv); #if defined(CONFIG_ARCH_MSM8916) || defined(CONFIG_ARCH_APQ8084) || defined(CONFIG_ARCH_ODIN) tty_port_destroy(bypass_drv->port); #endif kfree(bypass_drv->port); kfree(bypass_drv); return 0; } bypass_drv->enable = 0; pr_info( "%s: success\n", __func__); return 0; }
} static void __exit qcnmea_exit() { tty_unregister_driver(qcnmea_tty_driver); put_tty_driver(qcnmea_tty_driver);
static int __init mts_tty_init(void) { int ret = 0; struct device *tty_dev = NULL; struct mts_tty *mts_tty_drv = NULL; mts_tty_drv = kzalloc(sizeof(struct mts_tty), GFP_KERNEL); if (mts_tty_drv == NULL) { printk( "mts_tty_init: memory alloc fail %d - %d\n", 0, 0); return 0; } mts_tty_drv->mts_tty_port = kzalloc(sizeof(struct tty_port), GFP_KERNEL); if (mts_tty_drv->mts_tty_port == NULL) { printk( "mts_tty_init: memory alloc fail %d - %d\n", 0, 0); kfree(mts_tty_drv); return 0; } tty_port_init(mts_tty_drv->mts_tty_port); mts_tty = mts_tty_drv; mts_tty_drv->tty_drv = alloc_tty_driver(MAX_DIAG_MTS_DRV); if (!mts_tty_drv->tty_drv) { printk( "mts_tty_init: tty alloc driver fail %d - %d\n", 1, 0); kfree(mts_tty_drv->mts_tty_port); kfree(mts_tty_drv); return 0; } mts_tty_drv->tty_drv->name = "mts_tty"; mts_tty_drv->tty_drv->owner = THIS_MODULE; mts_tty_drv->tty_drv->driver_name = "mts_tty"; /* uses dynamically assigned dev_t values */ mts_tty_drv->tty_drv->type = TTY_DRIVER_TYPE_SERIAL; mts_tty_drv->tty_drv->subtype = SERIAL_TYPE_NORMAL; mts_tty_drv->tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_TERMIOS; /* initializing the mts driver */ mts_tty_drv->tty_drv->init_termios = tty_std_termios; mts_tty_drv->tty_drv->init_termios.c_iflag = IGNBRK | IGNPAR; mts_tty_drv->tty_drv->init_termios.c_oflag = 0; mts_tty_drv->tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; mts_tty_drv->tty_drv->init_termios.c_lflag = 0; tty_set_operations(mts_tty_drv->tty_drv, &mts_tty_ops); tty_port_link_device(mts_tty_drv->mts_tty_port, mts_tty_drv->tty_drv, 0); ret = tty_register_driver(mts_tty_drv->tty_drv); if (ret) { printk("fail to mts tty_register_driver\n"); put_tty_driver(mts_tty_drv->tty_drv); tty_port_destroy(mts_tty_drv->mts_tty_port); mts_tty_drv->tty_drv = NULL; kfree(mts_tty_drv->mts_tty_port); kfree(mts_tty_drv); return 0; } tty_dev = tty_register_device(mts_tty_drv->tty_drv, 0, NULL); if (IS_ERR(tty_dev)) { printk("fail to mts tty_register_device\n"); tty_unregister_driver(mts_tty_drv->tty_drv); put_tty_driver(mts_tty_drv->tty_drv); tty_port_destroy(mts_tty_drv->mts_tty_port); kfree(mts_tty_drv->mts_tty_port); kfree(mts_tty_drv); return 0; } /* mts_tty->pm_notify.notifier_call = mts_pm_notify; register_pm_notifier(&mts_tty->pm_notify); init_waitqueue_head(&mts_tty->waitq); */ mts_tty->run = 0; // mts_tty->pm_notify_info = 0; printk( "mts_tty_init success\n"); return 0; }
/** Module cleanup. * * Clears all master instances. */ void __exit ec_tty_cleanup_module(void) { tty_unregister_driver(tty_driver); put_tty_driver(tty_driver); printk(KERN_INFO PFX "Module unloading.\n"); }
static void __exit vcom_exit(void) { vcom_remove_ttys(vcom_tty_drv); tty_unregister_driver(vcom_tty_drv); put_tty_driver(vcom_tty_drv); }
/** * 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; }
/* * 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; }
/** * ehv_bc_exit - ePAPR hypervisor byte channel driver termination * * This function is called when this driver is unloaded. */ static void __exit ehv_bc_exit(void) { tty_unregister_driver(ehv_bc_driver); put_tty_driver(ehv_bc_driver); kfree(bcs); }
static void userial_cleanup(void) { tty_unregister_driver(gs_tty_driver); put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; }
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; }
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 __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 __exit tty3215_exit(void) { tty_unregister_driver(tty3215_driver); put_tty_driver(tty3215_driver); ccw_driver_unregister(&raw3215_ccw_driver); }
static void stty_driver_exit(struct stty_device *device) { struct tty_driver *driver = device->driver; tty_unregister_driver(driver); tty_port_destroy(device->port); }