X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Finput%2Fserio%2Fserio.c;fp=drivers%2Finput%2Fserio%2Fserio.c;h=2f76813c3a645c7d3d6a9e797df4525f19c6ac3d;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=4a1c3e36546f92aa60b82a5e462a33edd819b0be;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 4a1c3e365..2f76813c3 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -34,7 +34,6 @@ #include #include #include -#include MODULE_AUTHOR("Vojtech Pavlik "); 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);