linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / input / serio / serio.c
index 4a1c3e3..2f76813 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
-#include <linux/mutex.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Serio abstraction core");
@@ -53,16 +52,15 @@ EXPORT_SYMBOL(serio_rescan);
 EXPORT_SYMBOL(serio_reconnect);
 
 /*
- * serio_mutex protects entire serio subsystem and is taken every time
+ * serio_sem protects entire serio subsystem and is taken every time
  * serio port or driver registrered or unregistered.
  */
-static DEFINE_MUTEX(serio_mutex);
+static DECLARE_MUTEX(serio_sem);
 
 static LIST_HEAD(serio_list);
 
 static struct bus_type serio_bus;
 
-static void serio_add_driver(struct serio_driver *drv);
 static void serio_add_port(struct serio *serio);
 static void serio_destroy_port(struct serio *serio);
 static void serio_reconnect_port(struct serio *serio);
@@ -72,9 +70,9 @@ static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
 {
        int retval;
 
-       mutex_lock(&serio->drv_mutex);
+       down(&serio->drv_sem);
        retval = drv->connect(serio, drv);
-       mutex_unlock(&serio->drv_mutex);
+       up(&serio->drv_sem);
 
        return retval;
 }
@@ -83,20 +81,20 @@ static int serio_reconnect_driver(struct serio *serio)
 {
        int retval = -1;
 
-       mutex_lock(&serio->drv_mutex);
+       down(&serio->drv_sem);
        if (serio->drv && serio->drv->reconnect)
                retval = serio->drv->reconnect(serio);
-       mutex_unlock(&serio->drv_mutex);
+       up(&serio->drv_sem);
 
        return retval;
 }
 
 static void serio_disconnect_driver(struct serio *serio)
 {
-       mutex_lock(&serio->drv_mutex);
+       down(&serio->drv_sem);
        if (serio->drv)
                serio->drv->disconnect(serio);
-       mutex_unlock(&serio->drv_mutex);
+       up(&serio->drv_sem);
 }
 
 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
@@ -141,14 +139,8 @@ static void serio_release_driver(struct serio *serio)
 
 static void serio_find_driver(struct serio *serio)
 {
-       int error;
-
        down_write(&serio_bus.subsys.rwsem);
-       error = device_attach(&serio->dev);
-       if (error < 0)
-               printk(KERN_WARNING
-                       "serio: device_attach() failed for %s (%s), error: %d\n",
-                       serio->phys, serio->name, error);
+       device_attach(&serio->dev);
        up_write(&serio_bus.subsys.rwsem);
 }
 
@@ -203,7 +195,6 @@ static void serio_queue_event(void *object, struct module *owner,
        if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
                if (!try_module_get(owner)) {
                        printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);
-                       kfree(event);
                        goto out;
                }
 
@@ -279,8 +270,9 @@ static struct serio_event *serio_get_event(void)
 static void serio_handle_event(void)
 {
        struct serio_event *event;
+       struct serio_driver *serio_drv;
 
-       mutex_lock(&serio_mutex);
+       down(&serio_sem);
 
        /*
         * Note that we handle only one event here to give swsusp
@@ -310,7 +302,8 @@ static void serio_handle_event(void)
                                break;
 
                        case SERIO_REGISTER_DRIVER:
-                               serio_add_driver(event->object);
+                               serio_drv = event->object;
+                               driver_register(&serio_drv->driver);
                                break;
 
                        default:
@@ -321,7 +314,7 @@ static void serio_handle_event(void)
                serio_free_event(event);
        }
 
-       mutex_unlock(&serio_mutex);
+       up(&serio_sem);
 }
 
 /*
@@ -456,7 +449,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
        struct device_driver *drv;
        int retval;
 
-       retval = mutex_lock_interruptible(&serio_mutex);
+       retval = down_interruptible(&serio_sem);
        if (retval)
                return retval;
 
@@ -476,7 +469,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
                retval = -EINVAL;
        }
 
-       mutex_unlock(&serio_mutex);
+       up(&serio_sem);
 
        return retval;
 }
@@ -521,8 +514,6 @@ static void serio_release_port(struct device *dev)
        module_put(THIS_MODULE);
 }
 
-static struct lock_class_key serio_lock_key;
-
 /*
  * Prepare serio port for registration.
  */
@@ -532,21 +523,15 @@ static void serio_init_port(struct serio *serio)
 
        __module_get(THIS_MODULE);
 
-       INIT_LIST_HEAD(&serio->node);
        spin_lock_init(&serio->lock);
-       mutex_init(&serio->drv_mutex);
+       init_MUTEX(&serio->drv_sem);
        device_initialize(&serio->dev);
        snprintf(serio->dev.bus_id, sizeof(serio->dev.bus_id),
                 "serio%ld", (long)atomic_inc_return(&serio_no) - 1);
        serio->dev.bus = &serio_bus;
        serio->dev.release = serio_release_port;
-       if (serio->parent) {
+       if (serio->parent)
                serio->dev.parent = &serio->parent->dev;
-               serio->depth = serio->parent->depth + 1;
-       } else
-               serio->depth = 0;
-       lockdep_set_class_and_subclass(&serio->lock, &serio_lock_key,
-                                      serio->depth);
 }
 
 /*
@@ -555,8 +540,6 @@ static void serio_init_port(struct serio *serio)
  */
 static void serio_add_port(struct serio *serio)
 {
-       int error;
-
        if (serio->parent) {
                serio_pause_rx(serio->parent);
                serio->parent->child = serio;
@@ -566,19 +549,9 @@ static void serio_add_port(struct serio *serio)
        list_add_tail(&serio->node, &serio_list);
        if (serio->start)
                serio->start(serio);
-       error = device_add(&serio->dev);
-       if (error)
-               printk(KERN_ERR
-                       "serio: device_add() failed for %s (%s), error: %d\n",
-                       serio->phys, serio->name, error);
-       else {
-               serio->registered = 1;
-               error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
-               if (error)
-                       printk(KERN_ERR
-                               "serio: sysfs_create_group() failed for %s (%s), error: %d\n",
-                               serio->phys, serio->name, error);
-       }
+       device_add(&serio->dev);
+       sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
+       serio->registered = 1;
 }
 
 /*
@@ -608,10 +581,10 @@ static void serio_destroy_port(struct serio *serio)
        if (serio->registered) {
                sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
                device_del(&serio->dev);
+               list_del_init(&serio->node);
                serio->registered = 0;
        }
 
-       list_del_init(&serio->node);
        serio_remove_pending_events(serio);
        put_device(&serio->dev);
 }
@@ -688,10 +661,10 @@ void __serio_register_port(struct serio *serio, struct module *owner)
  */
 void serio_unregister_port(struct serio *serio)
 {
-       mutex_lock(&serio_mutex);
+       down(&serio_sem);
        serio_disconnect_port(serio);
        serio_destroy_port(serio);
-       mutex_unlock(&serio_mutex);
+       up(&serio_sem);
 }
 
 /*
@@ -699,17 +672,17 @@ void serio_unregister_port(struct serio *serio)
  */
 void serio_unregister_child_port(struct serio *serio)
 {
-       mutex_lock(&serio_mutex);
+       down(&serio_sem);
        if (serio->child) {
                serio_disconnect_port(serio->child);
                serio_destroy_port(serio->child);
        }
-       mutex_unlock(&serio_mutex);
+       up(&serio_sem);
 }
 
 /*
  * Submits register request to kseriod for subsequent execution.
- * Can be used when it is not obvious whether the serio_mutex is
+ * Can be used when it is not obvious whether the serio_sem is
  * taken or not and when delayed execution is feasible.
  */
 void __serio_unregister_port_delayed(struct serio *serio, struct module *owner)
@@ -781,17 +754,6 @@ static struct bus_type serio_bus = {
        .remove = serio_driver_remove,
 };
 
-static void serio_add_driver(struct serio_driver *drv)
-{
-       int error;
-
-       error = driver_register(&drv->driver);
-       if (error)
-               printk(KERN_ERR
-                       "serio: driver_register() failed for %s, error: %d\n",
-                       drv->driver.name, error);
-}
-
 void __serio_register_driver(struct serio_driver *drv, struct module *owner)
 {
        drv->driver.bus = &serio_bus;
@@ -803,7 +765,7 @@ void serio_unregister_driver(struct serio_driver *drv)
 {
        struct serio *serio;
 
-       mutex_lock(&serio_mutex);
+       down(&serio_sem);
        drv->manual_bind = 1;   /* so serio_find_driver ignores it */
 
 start_over:
@@ -817,7 +779,7 @@ start_over:
        }
 
        driver_unregister(&drv->driver);
-       mutex_unlock(&serio_mutex);
+       up(&serio_sem);
 }
 
 static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
@@ -896,7 +858,7 @@ static int serio_resume(struct device *dev)
        return 0;
 }
 
-/* called from serio_driver->connect/disconnect methods under serio_mutex */
+/* called from serio_driver->connect/disconnect methods under serio_sem */
 int serio_open(struct serio *serio, struct serio_driver *drv)
 {
        serio_set_drv(serio, drv);
@@ -908,7 +870,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv)
        return 0;
 }
 
-/* called from serio_driver->connect/disconnect methods under serio_mutex */
+/* called from serio_driver->connect/disconnect methods under serio_sem */
 void serio_close(struct serio *serio)
 {
        if (serio->close)
@@ -939,26 +901,18 @@ irqreturn_t serio_interrupt(struct serio *serio,
 
 static int __init serio_init(void)
 {
-       int error;
+       serio_task = kthread_run(serio_thread, NULL, "kseriod");
+       if (IS_ERR(serio_task)) {
+               printk(KERN_ERR "serio: Failed to start kseriod\n");
+               return PTR_ERR(serio_task);
+       }
 
        serio_bus.dev_attrs = serio_device_attrs;
        serio_bus.drv_attrs = serio_driver_attrs;
        serio_bus.match = serio_bus_match;
        serio_bus.uevent = serio_uevent;
        serio_bus.resume = serio_resume;
-       error = bus_register(&serio_bus);
-       if (error) {
-               printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error);
-               return error;
-       }
-
-       serio_task = kthread_run(serio_thread, NULL, "kseriod");
-       if (IS_ERR(serio_task)) {
-               bus_unregister(&serio_bus);
-               error = PTR_ERR(serio_task);
-               printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error);
-               return error;
-       }
+       bus_register(&serio_bus);
 
        return 0;
 }
@@ -969,5 +923,5 @@ static void __exit serio_exit(void)
        kthread_stop(serio_task);
 }
 
-subsys_initcall(serio_init);
+module_init(serio_init);
 module_exit(serio_exit);