Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: serio - do not touch bus's rwsem

The subsystem rwsem is not used by the driver core at all, so there is
no point in trying to access it.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Dmitry Torokhov and committed by
Greg Kroah-Hartman
70f256fd 75f1115c

+15 -26
+15 -26
drivers/input/serio/serio.c
··· 115 115 * Basic serio -> driver core mappings 116 116 */ 117 117 118 - static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) 118 + static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) 119 119 { 120 120 int error; 121 121 122 - down_write(&serio_bus.subsys.rwsem); 123 - 124 122 if (serio_match_port(drv->id_table, serio)) { 123 + 125 124 serio->dev.driver = &drv->driver; 126 125 if (serio_connect_driver(serio, drv)) { 127 126 serio->dev.driver = NULL; 128 - goto out; 127 + return -ENODEV; 129 128 } 129 + 130 130 error = device_bind_driver(&serio->dev); 131 131 if (error) { 132 132 printk(KERN_WARNING ··· 136 136 drv->description, error); 137 137 serio_disconnect_driver(serio); 138 138 serio->dev.driver = NULL; 139 - goto out; 139 + return error; 140 140 } 141 141 } 142 - out: 143 - up_write(&serio_bus.subsys.rwsem); 144 - } 145 - 146 - static void serio_release_driver(struct serio *serio) 147 - { 148 - down_write(&serio_bus.subsys.rwsem); 149 - device_release_driver(&serio->dev); 150 - up_write(&serio_bus.subsys.rwsem); 142 + return 0; 151 143 } 152 144 153 145 static void serio_find_driver(struct serio *serio) 154 146 { 155 147 int error; 156 148 157 - down_write(&serio_bus.subsys.rwsem); 158 149 error = device_attach(&serio->dev); 159 150 if (error < 0) 160 151 printk(KERN_WARNING 161 152 "serio: device_attach() failed for %s (%s), error: %d\n", 162 153 serio->phys, serio->name, error); 163 - up_write(&serio_bus.subsys.rwsem); 164 154 } 165 155 166 156 ··· 460 470 { 461 471 struct serio *serio = to_serio_port(dev); 462 472 struct device_driver *drv; 463 - int retval; 473 + int error; 464 474 465 - retval = mutex_lock_interruptible(&serio_mutex); 466 - if (retval) 467 - return retval; 475 + error = mutex_lock_interruptible(&serio_mutex); 476 + if (error) 477 + return error; 468 478 469 - retval = count; 470 479 if (!strncmp(buf, "none", count)) { 471 480 serio_disconnect_port(serio); 472 481 } else if (!strncmp(buf, "reconnect", count)) { ··· 475 486 serio_find_driver(serio); 476 487 } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { 477 488 serio_disconnect_port(serio); 478 - serio_bind_driver(serio, to_serio_driver(drv)); 489 + error = serio_bind_driver(serio, to_serio_driver(drv)); 479 490 put_driver(drv); 480 491 } else { 481 - retval = -EINVAL; 492 + error = -EINVAL; 482 493 } 483 494 484 495 mutex_unlock(&serio_mutex); 485 496 486 - return retval; 497 + return error ? error : count; 487 498 } 488 499 489 500 static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf) ··· 654 665 do { 655 666 parent = s->parent; 656 667 657 - serio_release_driver(s); 668 + device_release_driver(&s->dev); 658 669 serio_destroy_port(s); 659 670 } while ((s = parent) != serio); 660 671 } ··· 662 673 /* 663 674 * Ok, no children left, now disconnect this port 664 675 */ 665 - serio_release_driver(serio); 676 + device_release_driver(&serio->dev); 666 677 } 667 678 668 679 void serio_rescan(struct serio *serio)