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

Input: gameport - 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
79580057 70f256fd

+13 -26
+13 -26
drivers/input/gameport/gameport.c
··· 190 190 * Basic gameport -> driver core mappings 191 191 */ 192 192 193 - static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) 193 + static int gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) 194 194 { 195 195 int error; 196 - 197 - down_write(&gameport_bus.subsys.rwsem); 198 196 199 197 gameport->dev.driver = &drv->driver; 200 198 if (drv->connect(gameport, drv)) { 201 199 gameport->dev.driver = NULL; 202 - goto out; 200 + return -ENODEV; 203 201 } 204 202 205 203 error = device_bind_driver(&gameport->dev); ··· 209 211 drv->description, error); 210 212 drv->disconnect(gameport); 211 213 gameport->dev.driver = NULL; 212 - goto out; 214 + return error; 213 215 } 214 216 215 - out: 216 - up_write(&gameport_bus.subsys.rwsem); 217 - } 218 - 219 - static void gameport_release_driver(struct gameport *gameport) 220 - { 221 - down_write(&gameport_bus.subsys.rwsem); 222 - device_release_driver(&gameport->dev); 223 - up_write(&gameport_bus.subsys.rwsem); 217 + return 0; 224 218 } 225 219 226 220 static void gameport_find_driver(struct gameport *gameport) 227 221 { 228 222 int error; 229 223 230 - down_write(&gameport_bus.subsys.rwsem); 231 224 error = device_attach(&gameport->dev); 232 225 if (error < 0) 233 226 printk(KERN_WARNING 234 227 "gameport: device_attach() failed for %s (%s), error: %d\n", 235 228 gameport->phys, gameport->name, error); 236 - up_write(&gameport_bus.subsys.rwsem); 237 229 } 238 230 239 231 ··· 471 483 { 472 484 struct gameport *gameport = to_gameport_port(dev); 473 485 struct device_driver *drv; 474 - int retval; 486 + int error; 475 487 476 - retval = mutex_lock_interruptible(&gameport_mutex); 477 - if (retval) 478 - return retval; 488 + error = mutex_lock_interruptible(&gameport_mutex); 489 + if (error) 490 + return error; 479 491 480 - retval = count; 481 492 if (!strncmp(buf, "none", count)) { 482 493 gameport_disconnect_port(gameport); 483 494 } else if (!strncmp(buf, "reconnect", count)) { ··· 486 499 gameport_find_driver(gameport); 487 500 } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { 488 501 gameport_disconnect_port(gameport); 489 - gameport_bind_driver(gameport, to_gameport_driver(drv)); 502 + error = gameport_bind_driver(gameport, to_gameport_driver(drv)); 490 503 put_driver(drv); 491 504 } else { 492 - retval = -EINVAL; 505 + error = -EINVAL; 493 506 } 494 507 495 508 mutex_unlock(&gameport_mutex); 496 509 497 - return retval; 510 + return error ? error : count; 498 511 } 499 512 500 513 static struct device_attribute gameport_device_attrs[] = { ··· 642 655 do { 643 656 parent = s->parent; 644 657 645 - gameport_release_driver(s); 658 + device_release_driver(&s->dev); 646 659 gameport_destroy_port(s); 647 660 } while ((s = parent) != gameport); 648 661 } ··· 650 663 /* 651 664 * Ok, no children left, now disconnect this port 652 665 */ 653 - gameport_release_driver(gameport); 666 + device_release_driver(&gameport->dev); 654 667 } 655 668 656 669 void gameport_rescan(struct gameport *gameport)