static void userial_cleanup(void)
{
	usb_debugfs_remove();
	destroy_workqueue(gserial_wq);
	tty_unregister_driver(gs_tty_driver);
	put_tty_driver(gs_tty_driver);
	gs_tty_driver = NULL;
}
/**
 * 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);

		cancel_work_sync(&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;

	usb_debugfs_remove();
	destroy_workqueue(gserial_wq);
	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__);
}