static void __exit citty_exit(void)
{
	struct citty_port *citty = NULL;
	int i;

	F_ENTER();

	/* unregister devices  */
	for (i = 0; i < CITTY_TTY_MINORS; ++i) {
		down(&sem_lock_tty[i]);
		citty = citty_table[i];
		if (citty) {
			citty_table[i] = NULL;
			kfree(citty);
		}
		up(&sem_lock_tty[i]);
		tty_port_destroy(&citty_port_table[i]);
		tty_unregister_device(citty_tty_driver, i);
		cci_free_buffer(&txCittyBuf[i]);
	}

	/* unregister driver */
	tty_unregister_driver(citty_tty_driver);
	put_tty_driver(citty_tty_driver);

	/* clean up for the cctdev stuff */
	cctdev_cleanup_module();

	F_LEAVE();
}
static void __exit citty_exit(void)
{
	struct citty_serial *citty;
	int i;

	F_ENTER();
	for (i = 0; i < CITTY_TTY_MINORS; ++i)
		tty_unregister_device(citty_tty_driver, i);

	tty_unregister_driver(citty_tty_driver);
	put_tty_driver(citty_tty_driver);

	/*  free the memory */
	for (i = 0; i < CITTY_TTY_MINORS; ++i)
	{
		down(&sem[i]);
		citty = citty_table[i];
		if (citty)
		{
			kfree(citty);
			citty_table[i] = NULL;

			//cci_free_buffer(&txCittyBuf[i]);

		}
		up(&sem[i]);
		cci_free_buffer(&txCittyBuf[i]); //Modified by Rovin to move here
	}

	/* clean up for the cctdev stuff */
	cctdev_cleanup_module();

	F_LEAVE();
}
int cctdev_init_module(void)
{
	int result, i;
	dev_t dev = 0;
	char name[256];

	F_ENTER();

	/*
	 * Get a range of minor numbers to work with, asking for a dynamic
	 * major unless directed otherwise at load time.
	 */
	if (cctdev_major) {
		dev = MKDEV(cctdev_major, cctdev_minor);
		result = register_chrdev_region(dev, cctdev_nr_devs, "cctdev");
	} else {
		result = alloc_chrdev_region(&dev, cctdev_minor, cctdev_nr_devs,
					     "cctdev");
		cctdev_major = MAJOR(dev);
	}

	if (result < 0) {
		printk(KERN_WARNING "cctdev: can't get major %d\n",
		       cctdev_major);
		return result;
	}

	/*
	 * allocate the devices -- we can't have them static, as the number
	 * can be specified at load time
	 */
	cctdev_devices =
	    kmalloc(cctdev_nr_devs * sizeof(struct cctdev_dev), GFP_KERNEL);
	if (!cctdev_devices) {
		result = -ENOMEM;
		goto fail;	/* Make this more graceful */
	}
	memset(cctdev_devices, 0, cctdev_nr_devs * sizeof(struct cctdev_dev));

	cctdev_class = class_create(THIS_MODULE, "cctdev");
	/* Initialize each device. */
	for (i = 0; i < cctdev_nr_devs; i++) {
		sprintf(name, "%s%d", "cctdev", i);
		sema_init(&cctdev_devices[i].sem, 1);
		cctdev_setup_cdev(&cctdev_devices[i], i);
		device_create(cctdev_class, NULL,
			      MKDEV(cctdev_major, cctdev_minor + i), NULL,
			      name);
	}

	/* At this point call the init function for any friend device */
	dev = MKDEV(cctdev_major, cctdev_minor + cctdev_nr_devs);

#ifdef cctdev_DEBUG		/* only when debugging */
	cctdev_create_proc();
#endif

	F_LEAVE();
	cctdev_ready = 1;
	return 0;		/* succeed */

fail:
	cctdev_cleanup_module();

	return result;
}