diff options
author | Anton Vorontsov <cbouatmailru@gmail.com> | 2008-10-18 20:28:24 +0400 |
---|---|---|
committer | Anton Vorontsov <cbouatmailru@gmail.com> | 2008-10-18 20:28:24 +0400 |
commit | ed8c3174dd227031d1f3b9fa4fbb512f8f623434 (patch) | |
tree | bac4953f8899d6600f4716c0bcde1e25e34c2591 /drivers/input | |
parent | 8aef7e8f8de2d900da892085edbf14ea35fe6881 (diff) | |
parent | 0cfd81031a26717fe14380d18275f8e217571615 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/power/Makefile
Diffstat (limited to 'drivers/input')
67 files changed, 2597 insertions, 891 deletions
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 078e4eed089..2880eaae157 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport) enum gameport_event_type { GAMEPORT_REGISTER_PORT, GAMEPORT_REGISTER_DRIVER, + GAMEPORT_ATTACH_DRIVER, }; struct gameport_event { @@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list); static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); static struct task_struct *gameport_task; -static void gameport_queue_event(void *object, struct module *owner, - enum gameport_event_type event_type) +static int gameport_queue_event(void *object, struct module *owner, + enum gameport_event_type event_type) { unsigned long flags; struct gameport_event *event; + int retval = 0; spin_lock_irqsave(&gameport_event_lock, flags); @@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner, } } - if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) { - if (!try_module_get(owner)) { - printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type); - kfree(event); - goto out; - } - - event->type = event_type; - event->object = object; - event->owner = owner; + event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); + if (!event) { + printk(KERN_ERR + "gameport: Not enough memory to queue event %d\n", + event_type); + retval = -ENOMEM; + goto out; + } - list_add_tail(&event->node, &gameport_event_list); - wake_up(&gameport_wait); - } else { - printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type); + if (!try_module_get(owner)) { + printk(KERN_WARNING + "gameport: Can't get module reference, dropping event %d\n", + event_type); + kfree(event); + retval = -EINVAL; + goto out; } + + event->type = event_type; + event->object = object; + event->owner = owner; + + list_add_tail(&event->node, &gameport_event_list); + wake_up(&gameport_wait); + out: spin_unlock_irqrestore(&gameport_event_lock, flags); + return retval; } static void gameport_free_event(struct gameport_event *event) @@ -378,9 +390,10 @@ static void gameport_handle_event(void) } /* - * Remove all events that have been submitted for a given gameport port. + * Remove all events that have been submitted for a given object, + * be it a gameport port or a driver. */ -static void gameport_remove_pending_events(struct gameport *gameport) +static void gameport_remove_pending_events(void *object) { struct list_head *node, *next; struct gameport_event *event; @@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport) list_for_each_safe(node, next, &gameport_event_list) { event = list_entry(node, struct gameport_event, node); - if (event->object == gameport) { + if (event->object == object) { list_del_init(node); gameport_free_event(event); } @@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv) drv->driver.name, error); } -void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) +int __gameport_register_driver(struct gameport_driver *drv, struct module *owner, + const char *mod_name) { + int error; + drv->driver.bus = &gameport_bus; - gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER); + drv->driver.owner = owner; + drv->driver.mod_name = mod_name; + + /* + * Temporarily disable automatic binding because probing + * takes long time and we are better off doing it in kgameportd + */ + drv->ignore = 1; + + error = driver_register(&drv->driver); + if (error) { + printk(KERN_ERR + "gameport: driver_register() failed for %s, error: %d\n", + drv->driver.name, error); + return error; + } + + /* + * Reset ignore flag and let kgameportd bind the driver to free ports + */ + drv->ignore = 0; + error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER); + if (error) { + driver_unregister(&drv->driver); + return error; + } + + return 0; } void gameport_unregister_driver(struct gameport_driver *drv) @@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv) struct gameport *gameport; mutex_lock(&gameport_mutex); + drv->ignore = 1; /* so gameport_find_driver ignores it */ + gameport_remove_pending_events(drv); start_over: list_for_each_entry(gameport, &gameport_list, node) { @@ -729,6 +774,7 @@ start_over: } driver_unregister(&drv->driver); + mutex_unlock(&gameport_mutex); } diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 92498d470b1..6489f4010c4 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = { static int __init a3d_init(void) { - gameport_register_driver(&a3d_drv); - return 0; + return gameport_register_driver(&a3d_drv); } static void __exit a3d_exit(void) diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index d1ca8a14950..89c4c084d4a 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = { static int __init adi_init(void) { - gameport_register_driver(&adi_drv); - return 0; + return gameport_register_driver(&adi_drv); } static void __exit adi_exit(void) diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 708c5ae13b2..356b3a25efa 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = { static int __init analog_init(void) { analog_parse_options(); - gameport_register_driver(&analog_drv); - - return 0; + return gameport_register_driver(&analog_drv); } static void __exit analog_exit(void) diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 639b975a8ed..3497b87c3d0 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = { static int __init cobra_init(void) { - gameport_register_driver(&cobra_drv); - return 0; + return gameport_register_driver(&cobra_drv); } static void __exit cobra_exit(void) diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index cb6eef1f2d9..67c207f5b1a 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = { static int __init gf2k_init(void) { - gameport_register_driver(&gf2k_drv); - return 0; + return gameport_register_driver(&gf2k_drv); } static void __exit gf2k_exit(void) diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index 684e07cfccc..fc55899ba6c 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = { static int __init grip_init(void) { - gameport_register_driver(&grip_drv); - return 0; + return gameport_register_driver(&grip_drv); } static void __exit grip_exit(void) diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 8279481b16e..2d47baf4776 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = { static int __init grip_init(void) { - gameport_register_driver(&grip_drv); - return 0; + return gameport_register_driver(&grip_drv); } static void __exit grip_exit(void) diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 25ec3fad9f2..4058d4b272f 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = { static int __init guillemot_init(void) { - gameport_register_driver(&guillemot_drv); - return 0; + return gameport_register_driver(&guillemot_drv); } static void __exit guillemot_exit(void) diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c index 7839b7b6fa9..0de9a0943a9 100644 --- a/drivers/input/joystick/iforce/iforce-ff.c +++ b/drivers/input/joystick/iforce/iforce-ff.c @@ -197,13 +197,16 @@ static unsigned char find_button(struct iforce *iforce, signed short button) * Analyse the changes in an effect, and tell if we need to send an condition * parameter packet */ -static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) +static int need_condition_modifier(struct iforce *iforce, + struct ff_effect *old, + struct ff_effect *new) { int ret = 0; int i; if (new->type != FF_SPRING && new->type != FF_FRICTION) { - warn("bad effect type in need_condition_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); return 0; } @@ -222,10 +225,13 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) * Analyse the changes in an effect, and tell if we need to send a magnitude * parameter packet */ -static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect) +static int need_magnitude_modifier(struct iforce *iforce, + struct ff_effect *old, + struct ff_effect *effect) { if (effect->type != FF_CONSTANT) { - warn("bad effect type in need_envelope_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); return 0; } @@ -236,7 +242,8 @@ static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effe * Analyse the changes in an effect, and tell if we need to send an envelope * parameter packet */ -static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect) +static int need_envelope_modifier(struct iforce *iforce, struct ff_effect *old, + struct ff_effect *effect) { switch (effect->type) { case FF_CONSTANT: @@ -256,7 +263,8 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec break; default: - warn("bad effect type in need_envelope_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); } return 0; @@ -266,10 +274,12 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec * Analyse the changes in an effect, and tell if we need to send a periodic * parameter effect */ -static int need_period_modifier(struct ff_effect *old, struct ff_effect *new) +static int need_period_modifier(struct iforce *iforce, struct ff_effect *old, + struct ff_effect *new) { if (new->type != FF_PERIODIC) { - warn("bad effect type in need_period_modifier"); + dev_warn(&iforce->dev->dev, "bad effect type in %s\n", + __func__); return 0; } return (old->u.periodic.period != new->u.periodic.period @@ -355,7 +365,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru int param2_err = 1; int core_err = 0; - if (!old || need_period_modifier(old, effect)) { + if (!old || need_period_modifier(iforce, old, effect)) { param1_err = make_period_modifier(iforce, mod1_chunk, old != NULL, effect->u.periodic.magnitude, effect->u.periodic.offset, @@ -365,7 +375,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru set_bit(FF_MOD1_IS_USED, core_effect->flags); } - if (!old || need_envelope_modifier(old, effect)) { + if (!old || need_envelope_modifier(iforce, old, effect)) { param2_err = make_envelope_modifier(iforce, mod2_chunk, old !=NULL, effect->u.periodic.envelope.attack_length, @@ -425,7 +435,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru int param2_err = 1; int core_err = 0; - if (!old || need_magnitude_modifier(old, effect)) { + if (!old || need_magnitude_modifier(iforce, old, effect)) { param1_err = make_magnitude_modifier(iforce, mod1_chunk, old != NULL, effect->u.constant.level); @@ -434,7 +444,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru set_bit(FF_MOD1_IS_USED, core_effect->flags); } - if (!old || need_envelope_modifier(old, effect)) { + if (!old || need_envelope_modifier(iforce, old, effect)) { param2_err = make_envelope_modifier(iforce, mod2_chunk, old != NULL, effect->u.constant.envelope.attack_length, @@ -487,7 +497,7 @@ int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, str default: return -1; } - if (!old || need_condition_modifier(old, effect)) { + if (!old || need_condition_modifier(iforce, old, effect)) { param_err = make_condition_modifier(iforce, mod1_chunk, old != NULL, effect->u.condition[0].right_saturation, diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 61ee6e38739..baabf830264 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -218,7 +218,9 @@ static void iforce_release(struct input_dev *dev) /* Check: no effects should be present in memory */ for (i = 0; i < dev->ff->max_effects; i++) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) { - warn("iforce_release: Device still owns effects"); + dev_warn(&dev->dev, + "%s: Device still owns effects\n", + __func__); break; } } @@ -335,26 +337,26 @@ int iforce_init_device(struct iforce *iforce) if (!iforce_get_id_packet(iforce, "M")) input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet M"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n"); if (!iforce_get_id_packet(iforce, "P")) input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet P"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n"); if (!iforce_get_id_packet(iforce, "B")) iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet B"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n"); if (!iforce_get_id_packet(iforce, "N")) ff_effects = iforce->edata[1]; else - warn("Device does not respond to id packet N"); + dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n"); /* Check if the device can store more effects than the driver can really handle */ if (ff_effects > IFORCE_EFFECTS_MAX) { - warn("Limiting number of effects to %d (device reports %d)", + dev_warn(&iforce->dev->dev, "Limiting number of effects to %d (device reports %d)\n", IFORCE_EFFECTS_MAX, ff_effects); ff_effects = IFORCE_EFFECTS_MAX; } diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c index 015b50aa76f..a17b5001600 100644 --- a/drivers/input/joystick/iforce/iforce-packets.c +++ b/drivers/input/joystick/iforce/iforce-packets.c @@ -65,7 +65,8 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { - warn("not enough space in xmit buffer to send new packet"); + dev_warn(&iforce->dev->dev, + "not enough space in xmit buffer to send new packet\n"); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return -1; } @@ -148,7 +149,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) return 0; } } - warn("unused effect %04x updated !!!", addr); + dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr); return -1; } @@ -159,7 +160,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) static int being_used = 0; if (being_used) - warn("re-entrant call to iforce_process %d", being_used); + dev_warn(&iforce->dev->dev, + "re-entrant call to iforce_process %d\n", being_used); being_used++; #ifdef CONFIG_JOYSTICK_IFORCE_232 diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 851cc4087c2..f83185aeb51 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -64,7 +64,7 @@ void iforce_usb_xmit(struct iforce *iforce) if ( (n=usb_submit_urb(iforce-> |