Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #6
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;
}
Beispiel #7
0
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #12
0
/* 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;
}
Beispiel #15
0
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);
}
Beispiel #16
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
/**
 * 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;
}
Beispiel #19
0
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;
}
Beispiel #20
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;
}
Beispiel #21
0
/*
 * 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;
}
Beispiel #22
0
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;
}
Beispiel #23
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) {
			/*
			 * 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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
0
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;
}
Beispiel #28
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;
}
Beispiel #29
0
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;
}