#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/sched.h> /* HZ */
-#include <linux/mutex.h>
/*#include <asm/io.h>*/
EXPORT_SYMBOL(gameport_stop_polling);
/*
- * gameport_mutex protects entire gameport subsystem and is taken
+ * gameport_sem protects entire gameport subsystem and is taken
* every time gameport port or driver registrered or unregistered.
*/
-static DEFINE_MUTEX(gameport_mutex);
+static DECLARE_MUTEX(gameport_sem);
static LIST_HEAD(gameport_list);
static struct bus_type gameport_bus;
-static void gameport_add_driver(struct gameport_driver *drv);
static void gameport_add_port(struct gameport *gameport);
static void gameport_destroy_port(struct gameport *gameport);
static void gameport_reconnect_port(struct gameport *gameport);
static void gameport_find_driver(struct gameport *gameport)
{
- int error;
-
down_write(&gameport_bus.subsys.rwsem);
- error = device_attach(&gameport->dev);
- if (error < 0)
- printk(KERN_WARNING
- "gameport: device_attach() failed for %s (%s), error: %d\n",
- gameport->phys, gameport->name, error);
+ device_attach(&gameport->dev);
up_write(&gameport_bus.subsys.rwsem);
}
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;
}
spin_unlock_irqrestore(&gameport_event_lock, flags);
}
+
static struct gameport_event *gameport_get_event(void)
{
struct gameport_event *event;
static void gameport_handle_event(void)
{
struct gameport_event *event;
+ struct gameport_driver *gameport_drv;
- mutex_lock(&gameport_mutex);
+ down(&gameport_sem);
/*
* Note that we handle only one event here to give swsusp
break;
case GAMEPORT_REGISTER_DRIVER:
- gameport_add_driver(event->object);
+ gameport_drv = event->object;
+ driver_register(&gameport_drv->driver);
break;
default:
gameport_free_event(event);
}
- mutex_unlock(&gameport_mutex);
+ up(&gameport_sem);
}
/*
struct device_driver *drv;
int retval;
- retval = mutex_lock_interruptible(&gameport_mutex);
+ retval = down_interruptible(&gameport_sem);
if (retval)
return retval;
retval = -EINVAL;
}
- mutex_unlock(&gameport_mutex);
+ up(&gameport_sem);
return retval;
}
__module_get(THIS_MODULE);
- mutex_init(&gameport->drv_mutex);
+ init_MUTEX(&gameport->drv_sem);
device_initialize(&gameport->dev);
snprintf(gameport->dev.bus_id, sizeof(gameport->dev.bus_id),
"gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1);
if (gameport->parent)
gameport->dev.parent = &gameport->parent->dev;
- INIT_LIST_HEAD(&gameport->node);
spin_lock_init(&gameport->timer_lock);
init_timer(&gameport->poll_timer);
gameport->poll_timer.function = gameport_run_poll_handler;
*/
static void gameport_add_port(struct gameport *gameport)
{
- int error;
-
if (gameport->parent)
gameport->parent->child = gameport;
printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n",
gameport->name, gameport->phys, gameport->speed);
- error = device_add(&gameport->dev);
- if (error)
- printk(KERN_ERR
- "gameport: device_add() failed for %s (%s), error: %d\n",
- gameport->phys, gameport->name, error);
- else
- gameport->registered = 1;
+ device_add(&gameport->dev);
+ gameport->registered = 1;
}
/*
if (gameport->registered) {
device_del(&gameport->dev);
+ list_del_init(&gameport->node);
gameport->registered = 0;
}
- list_del_init(&gameport->node);
-
gameport_remove_pending_events(gameport);
put_device(&gameport->dev);
}
*/
void gameport_unregister_port(struct gameport *gameport)
{
- mutex_lock(&gameport_mutex);
+ down(&gameport_sem);
gameport_disconnect_port(gameport);
gameport_destroy_port(gameport);
- mutex_unlock(&gameport_mutex);
+ up(&gameport_sem);
}
}
static struct bus_type gameport_bus = {
- .name = "gameport",
- .probe = gameport_driver_probe,
- .remove = gameport_driver_remove,
+ .name = "gameport",
+ .probe = gameport_driver_probe,
+ .remove = gameport_driver_remove,
};
-static void gameport_add_driver(struct gameport_driver *drv)
-{
- int error;
-
- error = driver_register(&drv->driver);
- if (error)
- printk(KERN_ERR
- "gameport: driver_register() failed for %s, error: %d\n",
- drv->driver.name, error);
-}
-
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
{
drv->driver.bus = &gameport_bus;
{
struct gameport *gameport;
- mutex_lock(&gameport_mutex);
+ down(&gameport_sem);
drv->ignore = 1; /* so gameport_find_driver ignores it */
start_over:
}
driver_unregister(&drv->driver);
- mutex_unlock(&gameport_mutex);
+ up(&gameport_sem);
}
static int gameport_bus_match(struct device *dev, struct device_driver *drv)
static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv)
{
- mutex_lock(&gameport->drv_mutex);
+ down(&gameport->drv_sem);
gameport->drv = drv;
- mutex_unlock(&gameport->drv_mutex);
+ up(&gameport->drv_sem);
}
int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode)
static int __init gameport_init(void)
{
- int error;
+ gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
+ if (IS_ERR(gameport_task)) {
+ printk(KERN_ERR "gameport: Failed to start kgameportd\n");
+ return PTR_ERR(gameport_task);
+ }
gameport_bus.dev_attrs = gameport_device_attrs;
gameport_bus.drv_attrs = gameport_driver_attrs;
gameport_bus.match = gameport_bus_match;
- error = bus_register(&gameport_bus);
- if (error) {
- printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error);
- return error;
- }
-
- gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
- if (IS_ERR(gameport_task)) {
- bus_unregister(&gameport_bus);
- error = PTR_ERR(gameport_task);
- printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error);
- return error;
- }
+ bus_register(&gameport_bus);
return 0;
}
kthread_stop(gameport_task);
}
-subsys_initcall(gameport_init);
+module_init(gameport_init);
module_exit(gameport_exit);