1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Generic gameport layer 4 * 5 * Copyright (c) 1999-2002 Vojtech Pavlik 6 * Copyright (c) 2005 Dmitry Torokhov 7 */ 8 9 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12 #include <linux/stddef.h> 13 #include <linux/module.h> 14 #include <linux/ioport.h> 15 #include <linux/init.h> 16 #include <linux/gameport.h> 17 #include <linux/slab.h> 18 #include <linux/delay.h> 19 #include <linux/workqueue.h> 20 #include <linux/sched.h> /* HZ */ 21 #include <linux/mutex.h> 22 #include <linux/timekeeping.h> 23 24 /*#include <asm/io.h>*/ 25 26 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 27 MODULE_DESCRIPTION("Generic gameport layer"); 28 MODULE_LICENSE("GPL"); 29 30 static bool use_ktime = true; 31 module_param(use_ktime, bool, 0400); 32 MODULE_PARM_DESC(use_ktime, "Use ktime for measuring I/O speed"); 33 34 /* 35 * gameport_mutex protects entire gameport subsystem and is taken 36 * every time gameport port or driver registrered or unregistered. 37 */ 38 static DEFINE_MUTEX(gameport_mutex); 39 40 static LIST_HEAD(gameport_list); 41 42 static struct bus_type gameport_bus; 43 44 static void gameport_add_port(struct gameport *gameport); 45 static void gameport_attach_driver(struct gameport_driver *drv); 46 static void gameport_reconnect_port(struct gameport *gameport); 47 static void gameport_disconnect_port(struct gameport *gameport); 48 49 #if defined(__i386__) 50 51 #include <linux/i8253.h> 52 53 #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) 54 #define GET_TIME(x) do { x = get_time_pit(); } while (0) 55 56 static unsigned int get_time_pit(void) 57 { 58 unsigned long flags; 59 unsigned int count; 60 61 raw_spin_lock_irqsave(&i8253_lock, flags); 62 outb_p(0x00, 0x43); 63 count = inb_p(0x40); 64 count |= inb_p(0x40) << 8; 65 raw_spin_unlock_irqrestore(&i8253_lock, flags); 66 67 return count; 68 } 69 70 #endif 71 72 73 74 /* 75 * gameport_measure_speed() measures the gameport i/o speed. 76 */ 77 78 static int gameport_measure_speed(struct gameport *gameport) 79 { 80 unsigned int i, t, tx; 81 u64 t1, t2, t3; 82 unsigned long flags; 83 84 if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) 85 return 0; 86 87 tx = ~0; 88 89 for (i = 0; i < 50; i++) { 90 local_irq_save(flags); 91 t1 = ktime_get_ns(); 92 for (t = 0; t < 50; t++) 93 gameport_read(gameport); 94 t2 = ktime_get_ns(); 95 t3 = ktime_get_ns(); 96 local_irq_restore(flags); 97 udelay(i * 10); 98 t = (t2 - t1) - (t3 - t2); 99 if (t < tx) 100 tx = t; 101 } 102 103 gameport_close(gameport); 104 t = 1000000 * 50; 105 if (tx) 106 t /= tx; 107 return t; 108 } 109 110 static int old_gameport_measure_speed(struct gameport *gameport) 111 { 112 #if defined(__i386__) 113 114 unsigned int i, t, t1, t2, t3, tx; 115 unsigned long flags; 116 117 if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) 118 return 0; 119 120 tx = 1 << 30; 121 122 for(i = 0; i < 50; i++) { 123 local_irq_save(flags); 124 GET_TIME(t1); 125 for (t = 0; t < 50; t++) gameport_read(gameport); 126 GET_TIME(t2); 127 GET_TIME(t3); 128 local_irq_restore(flags); 129 udelay(i * 10); 130 if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t; 131 } 132 133 gameport_close(gameport); 134 return 59659 / (tx < 1 ? 1 : tx); 135 136 #elif defined (__x86_64__) 137 138 unsigned int i, t; 139 unsigned long tx, t1, t2, flags; 140 141 if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) 142 return 0; 143 144 tx = 1 << 30; 145 146 for(i = 0; i < 50; i++) { 147 local_irq_save(flags); 148 t1 = rdtsc(); 149 for (t = 0; t < 50; t++) gameport_read(gameport); 150 t2 = rdtsc(); 151 local_irq_restore(flags); 152 udelay(i * 10); 153 if (t2 - t1 < tx) tx = t2 - t1; 154 } 155 156 gameport_close(gameport); 157 return (this_cpu_read(cpu_info.loops_per_jiffy) * 158 (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx); 159 160 #else 161 162 unsigned int j, t = 0; 163 164 if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) 165 return 0; 166 167 j = jiffies; while (j == jiffies); 168 j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); } 169 170 gameport_close(gameport); 171 return t * HZ / 1000; 172 173 #endif 174 } 175 176 void gameport_start_polling(struct gameport *gameport) 177 { 178 spin_lock(&gameport->timer_lock); 179 180 if (!gameport->poll_cnt++) { 181 BUG_ON(!gameport->poll_handler); 182 BUG_ON(!gameport->poll_interval); 183 mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval)); 184 } 185 186 spin_unlock(&gameport->timer_lock); 187 } 188 EXPORT_SYMBOL(gameport_start_polling); 189 190 void gameport_stop_polling(struct gameport *gameport) 191 { 192 spin_lock(&gameport->timer_lock); 193 194 if (!--gameport->poll_cnt) 195 del_timer(&gameport->poll_timer); 196 197 spin_unlock(&gameport->timer_lock); 198 } 199 EXPORT_SYMBOL(gameport_stop_polling); 200 201 static void gameport_run_poll_handler(struct timer_list *t) 202 { 203 struct gameport *gameport = from_timer(gameport, t, poll_timer); 204 205 gameport->poll_handler(gameport); 206 if (gameport->poll_cnt) 207 mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval)); 208 } 209 210 /* 211 * Basic gameport -> driver core mappings 212 */ 213 214 static int gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) 215 { 216 int error; 217 218 gameport->dev.driver = &drv->driver; 219 if (drv->connect(gameport, drv)) { 220 gameport->dev.driver = NULL; 221 return -ENODEV; 222 } 223 224 error = device_bind_driver(&gameport->dev); 225 if (error) { 226 dev_warn(&gameport->dev, 227 "device_bind_driver() failed for %s (%s) and %s, error: %d\n", 228 gameport->phys, gameport->name, 229 drv->description, error); 230 drv->disconnect(gameport); 231 gameport->dev.driver = NULL; 232 return error; 233 } 234 235 return 0; 236 } 237 238 static void gameport_find_driver(struct gameport *gameport) 239 { 240 int error; 241 242 error = device_attach(&gameport->dev); 243 if (error < 0) 244 dev_warn(&gameport->dev, 245 "device_attach() failed for %s (%s), error: %d\n", 246 gameport->phys, gameport->name, error); 247 } 248 249 250 /* 251 * Gameport event processing. 252 */ 253 254 enum gameport_event_type { 255 GAMEPORT_REGISTER_PORT, 256 GAMEPORT_ATTACH_DRIVER, 257 }; 258 259 struct gameport_event { 260 enum gameport_event_type type; 261 void *object; 262 struct module *owner; 263 struct list_head node; 264 }; 265 266 static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ 267 static LIST_HEAD(gameport_event_list); 268 269 static struct gameport_event *gameport_get_event(void) 270 { 271 struct gameport_event *event = NULL; 272 unsigned long flags; 273 274 spin_lock_irqsave(&gameport_event_lock, flags); 275 276 if (!list_empty(&gameport_event_list)) { 277 event = list_first_entry(&gameport_event_list, 278 struct gameport_event, node); 279 list_del_init(&event->node); 280 } 281 282 spin_unlock_irqrestore(&gameport_event_lock, flags); 283 return event; 284 } 285 286 static void gameport_free_event(struct gameport_event *event) 287 { 288 module_put(event->owner); 289 kfree(event); 290 } 291 292 static void gameport_remove_duplicate_events(struct gameport_event *event) 293 { 294 struct gameport_event *e, *next; 295 unsigned long flags; 296 297 spin_lock_irqsave(&gameport_event_lock, flags); 298 299 list_for_each_entry_safe(e, next, &gameport_event_list, node) { 300 if (event->object == e->object) { 301 /* 302 * If this event is of different type we should not 303 * look further - we only suppress duplicate events 304 * that were sent back-to-back. 305 */ 306 if (event->type != e->type) 307 break; 308 309 list_del_init(&e->node); 310 gameport_free_event(e); 311 } 312 } 313 314 spin_unlock_irqrestore(&gameport_event_lock, flags); 315 } 316 317 318 static void gameport_handle_events(struct work_struct *work) 319 { 320 struct gameport_event *event; 321 322 mutex_lock(&gameport_mutex); 323 324 /* 325 * Note that we handle only one event here to give swsusp 326 * a chance to freeze kgameportd thread. Gameport events 327 * should be pretty rare so we are not concerned about 328 * taking performance hit. 329 */ 330 if ((event = gameport_get_event())) { 331 332 switch (event->type) { 333 334 case GAMEPORT_REGISTER_PORT: 335 gameport_add_port(event->object); 336 break; 337 338 case GAMEPORT_ATTACH_DRIVER: 339 gameport_attach_driver(event->object); 340 break; 341 } 342 343 gameport_remove_duplicate_events(event); 344 gameport_free_event(event); 345 } 346 347 mutex_unlock(&gameport_mutex); 348 } 349 350 static DECLARE_WORK(gameport_event_work, gameport_handle_events); 351 352 static int gameport_queue_event(void *object, struct module *owner, 353 enum gameport_event_type event_type) 354 { 355 unsigned long flags; 356 struct gameport_event *event; 357 int retval = 0; 358 359 spin_lock_irqsave(&gameport_event_lock, flags); 360 361 /* 362 * Scan event list for the other events for the same gameport port, 363 * starting with the most recent one. If event is the same we 364 * do not need add new one. If event is of different type we 365 * need to add this event and should not look further because 366 * we need to preserve sequence of distinct events. 367 */ 368 list_for_each_entry_reverse(event, &gameport_event_list, node) { 369 if (event->object == object) { 370 if (event->type == event_type) 371 goto out; 372 break; 373 } 374 } 375 376 event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); 377 if (!event) { 378 pr_err("Not enough memory to queue event %d\n", event_type); 379 retval = -ENOMEM; 380 goto out; 381 } 382 383 if (!try_module_get(owner)) { 384 pr_warn("Can't get module reference, dropping event %d\n", 385 event_type); 386 kfree(event); 387 retval = -EINVAL; 388 goto out; 389 } 390 391 event->type = event_type; 392 event->object = object; 393 event->owner = owner; 394 395 list_add_tail(&event->node, &gameport_event_list); 396 queue_work(system_long_wq, &gameport_event_work); 397 398 out: 399 spin_unlock_irqrestore(&gameport_event_lock, flags); 400 return retval; 401 } 402 403 /* 404 * Remove all events that have been submitted for a given object, 405 * be it a gameport port or a driver. 406 */ 407 static void gameport_remove_pending_events(void *object) 408 { 409 struct gameport_event *event, *next; 410 unsigned long flags; 411 412 spin_lock_irqsave(&gameport_event_lock, flags); 413 414 list_for_each_entry_safe(event, next, &gameport_event_list, node) { 415 if (event->object == object) { 416 list_del_init(&event->node); 417 gameport_free_event(event); 418 } 419 } 420 421 spin_unlock_irqrestore(&gameport_event_lock, flags); 422 } 423 424 /* 425 * Destroy child gameport port (if any) that has not been fully registered yet. 426 * 427 * Note that we rely on the fact that port can have only one child and therefore 428 * only one child registration request can be pending. Additionally, children 429 * are registered by driver's connect() handler so there can't be a grandchild 430 * pending registration together with a child. 431 */ 432 static struct gameport *gameport_get_pending_child(struct gameport *parent) 433 { 434 struct gameport_event *event; 435 struct gameport *gameport, *child = NULL; 436 unsigned long flags; 437 438 spin_lock_irqsave(&gameport_event_lock, flags); 439 440 list_for_each_entry(event, &gameport_event_list, node) { 441 if (event->type == GAMEPORT_REGISTER_PORT) { 442 gameport = event->object; 443 if (gameport->parent == parent) { 444 child = gameport; 445 break; 446 } 447 } 448 } 449 450 spin_unlock_irqrestore(&gameport_event_lock, flags); 451 return child; 452 } 453 454 /* 455 * Gameport port operations 456 */ 457 458 static ssize_t gameport_description_show(struct device *dev, struct device_attribute *attr, char *buf) 459 { 460 struct gameport *gameport = to_gameport_port(dev); 461 462 return sprintf(buf, "%s\n", gameport->name); 463 } 464 static DEVICE_ATTR(description, S_IRUGO, gameport_description_show, NULL); 465 466 static ssize_t drvctl_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 467 { 468 struct gameport *gameport = to_gameport_port(dev); 469 struct device_driver *drv; 470 int error; 471 472 error = mutex_lock_interruptible(&gameport_mutex); 473 if (error) 474 return error; 475 476 if (!strncmp(buf, "none", count)) { 477 gameport_disconnect_port(gameport); 478 } else if (!strncmp(buf, "reconnect", count)) { 479 gameport_reconnect_port(gameport); 480 } else if (!strncmp(buf, "rescan", count)) { 481 gameport_disconnect_port(gameport); 482 gameport_find_driver(gameport); 483 } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { 484 gameport_disconnect_port(gameport); 485 error = gameport_bind_driver(gameport, to_gameport_driver(drv)); 486 } else { 487 error = -EINVAL; 488 } 489 490 mutex_unlock(&gameport_mutex); 491 492 return error ? error : count; 493 } 494 static DEVICE_ATTR_WO(drvctl); 495 496 static struct attribute *gameport_device_attrs[] = { 497 &dev_attr_description.attr, 498 &dev_attr_drvctl.attr, 499 NULL, 500 }; 501 ATTRIBUTE_GROUPS(gameport_device); 502 503 static void gameport_release_port(struct device *dev) 504 { 505 struct gameport *gameport = to_gameport_port(dev); 506 507 kfree(gameport); 508 module_put(THIS_MODULE); 509 } 510 511 void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) 512 { 513 va_list args; 514 515 va_start(args, fmt); 516 vsnprintf(gameport->phys, sizeof(gameport->phys), fmt, args); 517 va_end(args); 518 } 519 EXPORT_SYMBOL(gameport_set_phys); 520 521 /* 522 * Prepare gameport port for registration. 523 */ 524 static void gameport_init_port(struct gameport *gameport) 525 { 526 static atomic_t gameport_no = ATOMIC_INIT(-1); 527 528 __module_get(THIS_MODULE); 529 530 mutex_init(&gameport->drv_mutex); 531 device_initialize(&gameport->dev); 532 dev_set_name(&gameport->dev, "gameport%lu", 533 (unsigned long)atomic_inc_return(&gameport_no)); 534 gameport->dev.bus = &gameport_bus; 535 gameport->dev.release = gameport_release_port; 536 if (gameport->parent) 537 gameport->dev.parent = &gameport->parent->dev; 538 539 INIT_LIST_HEAD(&gameport->node); 540 spin_lock_init(&gameport->timer_lock); 541 timer_setup(&gameport->poll_timer, gameport_run_poll_handler, 0); 542 } 543 544 /* 545 * Complete gameport port registration. 546 * Driver core will attempt to find appropriate driver for the port. 547 */ 548 static void gameport_add_port(struct gameport *gameport) 549 { 550 int error; 551 552 if (gameport->parent) 553 gameport->parent->child = gameport; 554 555 gameport->speed = use_ktime ? 556 gameport_measure_speed(gameport) : 557 old_gameport_measure_speed(gameport); 558 559 list_add_tail(&gameport->node, &gameport_list); 560 561 if (gameport->io) 562 dev_info(&gameport->dev, "%s is %s, io %#x, speed %dkHz\n", 563 gameport->name, gameport->phys, gameport->io, gameport->speed); 564 else 565 dev_info(&gameport->dev, "%s is %s, speed %dkHz\n", 566 gameport->name, gameport->phys, gameport->speed); 567 568 error = device_add(&gameport->dev); 569 if (error) 570 dev_err(&gameport->dev, 571 "device_add() failed for %s (%s), error: %d\n", 572 gameport->phys, gameport->name, error); 573 } 574 575 /* 576 * gameport_destroy_port() completes deregistration process and removes 577 * port from the system 578 */ 579 static void gameport_destroy_port(struct gameport *gameport) 580 { 581 struct gameport *child; 582 583 child = gameport_get_pending_child(gameport); 584 if (child) { 585 gameport_remove_pending_events(child); 586 put_device(&child->dev); 587 } 588 589 if (gameport->parent) { 590 gameport->parent->child = NULL; 591 gameport->parent = NULL; 592 } 593 594 if (device_is_registered(&gameport->dev)) 595 device_del(&gameport->dev); 596 597 list_del_init(&gameport->node); 598 599 gameport_remove_pending_events(gameport); 600 put_device(&gameport->dev); 601 } 602 603 /* 604 * Reconnect gameport port and all its children (re-initialize attached devices) 605 */ 606 static void gameport_reconnect_port(struct gameport *gameport) 607 { 608 do { 609 if (!gameport->drv || !gameport->drv->reconnect || gameport->drv->reconnect(gameport)) { 610 gameport_disconnect_port(gameport); 611 gameport_find_driver(gameport); 612 /* Ok, old children are now gone, we are done */ 613 break; 614 } 615 gameport = gameport->child; 616 } while (gameport); 617 } 618 619 /* 620 * gameport_disconnect_port() unbinds a port from its driver. As a side effect 621 * all child ports are unbound and destroyed. 622 */ 623 static void gameport_disconnect_port(struct gameport *gameport) 624 { 625 struct gameport *s, *parent; 626 627 if (gameport->child) { 628 /* 629 * Children ports should be disconnected and destroyed 630 * first, staring with the leaf one, since we don't want 631 * to do recursion 632 */ 633 for (s = gameport; s->child; s = s->child) 634 /* empty */; 635 636 do { 637 parent = s->parent; 638 639 device_release_driver(&s->dev); 640 gameport_destroy_port(s); 641 } while ((s = parent) != gameport); 642 } 643 644 /* 645 * Ok, no children left, now disconnect this port 646 */ 647 device_release_driver(&gameport->dev); 648 } 649 650 /* 651 * Submits register request to kgameportd for subsequent execution. 652 * Note that port registration is always asynchronous. 653 */ 654 void __gameport_register_port(struct gameport *gameport, struct module *owner) 655 { 656 gameport_init_port(gameport); 657 gameport_queue_event(gameport, owner, GAMEPORT_REGISTER_PORT); 658 } 659 EXPORT_SYMBOL(__gameport_register_port); 660 661 /* 662 * Synchronously unregisters gameport port. 663 */ 664 void gameport_unregister_port(struct gameport *gameport) 665 { 666 mutex_lock(&gameport_mutex); 667 gameport_disconnect_port(gameport); 668 gameport_destroy_port(gameport); 669 mutex_unlock(&gameport_mutex); 670 } 671 EXPORT_SYMBOL(gameport_unregister_port); 672 673 674 /* 675 * Gameport driver operations 676 */ 677 678 static ssize_t description_show(struct device_driver *drv, char *buf) 679 { 680 struct gameport_driver *driver = to_gameport_driver(drv); 681 return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); 682 } 683 static DRIVER_ATTR_RO(description); 684 685 static struct attribute *gameport_driver_attrs[] = { 686 &driver_attr_description.attr, 687 NULL 688 }; 689 ATTRIBUTE_GROUPS(gameport_driver); 690 691 static int gameport_driver_probe(struct device *dev) 692 { 693 struct gameport *gameport = to_gameport_port(dev); 694 struct gameport_driver *drv = to_gameport_driver(dev->driver); 695 696 drv->connect(gameport, drv); 697 return gameport->drv ? 0 : -ENODEV; 698 } 699 700 static int gameport_driver_remove(struct device *dev) 701 { 702 struct gameport *gameport = to_gameport_port(dev); 703 struct gameport_driver *drv = to_gameport_driver(dev->driver); 704 705 drv->disconnect(gameport); 706 return 0; 707 } 708 709 static void gameport_attach_driver(struct gameport_driver *drv) 710 { 711 int error; 712 713 error = driver_attach(&drv->driver); 714 if (error) 715 pr_err("driver_attach() failed for %s, error: %d\n", 716 drv->driver.name, error); 717 } 718 719 int __gameport_register_driver(struct gameport_driver *drv, struct module *owner, 720 const char *mod_name) 721 { 722 int error; 723 724 drv->driver.bus = &gameport_bus; 725 drv->driver.owner = owner; 726 drv->driver.mod_name = mod_name; 727 728 /* 729 * Temporarily disable automatic binding because probing 730 * takes long time and we are better off doing it in kgameportd 731 */ 732 drv->ignore = true; 733 734 error = driver_register(&drv->driver); 735 if (error) { 736 pr_err("driver_register() failed for %s, error: %d\n", 737 drv->driver.name, error); 738 return error; 739 } 740 741 /* 742 * Reset ignore flag and let kgameportd bind the driver to free ports 743 */ 744 drv->ignore = false; 745 error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER); 746 if (error) { 747 driver_unregister(&drv->driver); 748 return error; 749 } 750 751 return 0; 752 } 753 EXPORT_SYMBOL(__gameport_register_driver); 754 755 void gameport_unregister_driver(struct gameport_driver *drv) 756 { 757 struct gameport *gameport; 758 759 mutex_lock(&gameport_mutex); 760 761 drv->ignore = true; /* so gameport_find_driver ignores it */ 762 gameport_remove_pending_events(drv); 763 764 start_over: 765 list_for_each_entry(gameport, &gameport_list, node) { 766 if (gameport->drv == drv) { 767 gameport_disconnect_port(gameport); 768 gameport_find_driver(gameport); 769 /* we could've deleted some ports, restart */ 770 goto start_over; 771 } 772 } 773 774 driver_unregister(&drv->driver); 775 776 mutex_unlock(&gameport_mutex); 777 } 778 EXPORT_SYMBOL(gameport_unregister_driver); 779 780 static int gameport_bus_match(struct device *dev, struct device_driver *drv) 781 { 782 struct gameport_driver *gameport_drv = to_gameport_driver(drv); 783 784 return !gameport_drv->ignore; 785 } 786 787 static struct bus_type gameport_bus = { 788 .name = "gameport", 789 .dev_groups = gameport_device_groups, 790 .drv_groups = gameport_driver_groups, 791 .match = gameport_bus_match, 792 .probe = gameport_driver_probe, 793 .remove = gameport_driver_remove, 794 }; 795 796 static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv) 797 { 798 mutex_lock(&gameport->drv_mutex); 799 gameport->drv = drv; 800 mutex_unlock(&gameport->drv_mutex); 801 } 802 803 int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) 804 { 805 if (gameport->open) { 806 if (gameport->open(gameport, mode)) { 807 return -1; 808 } 809 } else { 810 if (mode != GAMEPORT_MODE_RAW) 811 return -1; 812 } 813 814 gameport_set_drv(gameport, drv); 815 return 0; 816 } 817 EXPORT_SYMBOL(gameport_open); 818 819 void gameport_close(struct gameport *gameport) 820 { 821 del_timer_sync(&gameport->poll_timer); 822 gameport->poll_handler = NULL; 823 gameport->poll_interval = 0; 824 gameport_set_drv(gameport, NULL); 825 if (gameport->close) 826 gameport->close(gameport); 827 } 828 EXPORT_SYMBOL(gameport_close); 829 830 static int __init gameport_init(void) 831 { 832 int error; 833 834 error = bus_register(&gameport_bus); 835 if (error) { 836 pr_err("failed to register gameport bus, error: %d\n", error); 837 return error; 838 } 839 840 841 return 0; 842 } 843 844 static void __exit gameport_exit(void) 845 { 846 bus_unregister(&gameport_bus); 847 848 /* 849 * There should not be any outstanding events but work may 850 * still be scheduled so simply cancel it. 851 */ 852 cancel_work_sync(&gameport_event_work); 853 } 854 855 subsys_initcall(gameport_init); 856 module_exit(gameport_exit); 857