Beispiel #1
0
static void __exit
mic_exit(void)
{
	/* Close endpoints related to reverse registration */
	acptboot_exit();

#ifdef USE_VCONSOLE
	micvcons_destroy(mic_data.dd_numdevs);
#endif

	pci_unregister_driver(&mic_lindata.dd_pcidriver);
	micpm_uninit();

	/* Uninit data structures for PM disconnect */
	micpm_disconn_uninit(mic_data.dd_numdevs + 1);

#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34))
	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "mic");
#endif
	micscif_kmem_cache_destroy();
	vmcore_exit();
	micveth_exit();
	micscif_destroy();
	ramoops_exit();

	device_destroy(mic_lindata.dd_class, mic_lindata.dd_dev + 1);
	device_destroy(mic_lindata.dd_class, mic_lindata.dd_dev);
	class_destroy(mic_lindata.dd_class);
	cdev_del(&mic_lindata.dd_cdev);
	unregister_chrdev_region(mic_lindata.dd_dev, MAX_DLDR_MINORS);
	unregister_pm_notifier(&mic_pm_notifer);
	return;
}
Beispiel #2
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;
}