+ kfree(serio);
+ module_put(THIS_MODULE);
+}
+
+static void serio_create_port(struct serio *serio)
+{
+ try_module_get(THIS_MODULE);
+
+ spin_lock_init(&serio->lock);
+ list_add_tail(&serio->node, &serio_list);
+ snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id), "serio%d", serio_no++);
+ serio->dev.bus = &serio_bus;
+ serio->dev.release = serio_release_port;
+ if (serio->parent)
+ serio->dev.parent = &serio->parent->dev;
+ device_register(&serio->dev);
+}
+
+/*
+ * serio_destroy_port() completes deregistration process and removes
+ * port from the system
+ */
+static void serio_destroy_port(struct serio *serio)
+{
+ struct serio_driver *drv = serio->drv;
+ unsigned long flags;
+
+ serio_remove_pending_events(serio);
+ list_del_init(&serio->node);
+
+ if (drv) {
+ drv->disconnect(serio);
+ down_write(&serio_bus.subsys.rwsem);
+ device_release_driver(&serio->dev);
+ up_write(&serio_bus.subsys.rwsem);
+ put_driver(&drv->driver);
+ }
+
+ if (serio->parent) {
+ spin_lock_irqsave(&serio->parent->lock, flags);
+ serio->parent->child = NULL;
+ spin_unlock_irqrestore(&serio->parent->lock, flags);
+ }
+
+ device_unregister(&serio->dev);
+}
+
+/*
+ * serio_connect_port() tries to bind the port and possible all its
+ * children to appropriate drivers. If driver passed in the function will not
+ * try otehr drivers when binding parent port.
+ */
+static void serio_connect_port(struct serio *serio, struct serio_driver *drv)
+{
+ WARN_ON(serio->drv);
+ WARN_ON(serio->child);
+
+ if (drv)
+ serio_bind_driver(serio, drv);
+ else if (!serio->manual_bind)
+ serio_find_driver(serio);
+
+ /* Ok, now bind children, if any */
+ while (serio->child) {
+ serio = serio->child;
+
+ WARN_ON(serio->drv);
+ WARN_ON(serio->child);
+
+ serio_create_port(serio);
+
+ if (!serio->manual_bind) {
+ /*
+ * With children we just _prefer_ passed in driver,
+ * but we will try other options in case preferred
+ * is not the one
+ */
+ if (!drv || !serio_bind_driver(serio, drv))
+ serio_find_driver(serio);