/*- * Scan event list for the other events for the same serio port,+ * Scan event list for the other events for the same serio port, * starting with the most recent one. If event is the same we * do not need add new one. If event is of different type we * need to add this event and should not look further because * we need to preseve sequence of distinct events.- */+ */ list_for_each_entry_reverse(event, &serio_event_list, node) { if (event->object == object) { if (event->type == event_type)@@ -614,6 +622,19 @@ void serio_unregister_port(struct serio }

/*+ * Safely unregisters child port if one is present.+ */+void serio_unregister_child_port(struct serio *serio)+{+ down(&serio_sem);+ if (serio->child) {+ serio_disconnect_port(serio->child);+ serio_destroy_port(serio->child);+ }+ up(&serio_sem);+}++/* * Submits register request to kseriod for subsequent execution. * Can be used when it is not obvious whether the serio_sem is * taken or not and when delayed execution is feasible.@@ -669,8 +690,18 @@ static int serio_driver_probe(struct dev { struct serio *serio = to_serio_port(dev); struct serio_driver *drv = to_serio_driver(dev->driver);+ int result;++ /* make sure parent is not about to change */+ if (serio->parent)+ down(&serio->parent->drv_sem);++ result = drv->connect(serio, drv);++ if (serio->parent)+ up(&serio->parent->drv_sem);