diff options
Diffstat (limited to 'drivers/input/joystick/turbografx.c')
-rw-r--r-- | drivers/input/joystick/turbografx.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 316c4bebfed2..28100d461cb7 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -84,6 +84,7 @@ static struct tgfx { char phys[7][32]; int sticks; int used; + struct semaphore sem; } *tgfx_base[3]; /* @@ -123,22 +124,33 @@ static void tgfx_timer(unsigned long private) static int tgfx_open(struct input_dev *dev) { struct tgfx *tgfx = dev->private; + int err; + + err = down_interruptible(&tgfx->sem); + if (err) + return err; + if (!tgfx->used++) { parport_claim(tgfx->pd); parport_write_control(tgfx->pd->port, 0x04); mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME); } + + up(&tgfx->sem); return 0; } static void tgfx_close(struct input_dev *dev) { struct tgfx *tgfx = dev->private; + + down(&tgfx->sem); if (!--tgfx->used) { - del_timer(&tgfx->timer); + del_timer_sync(&tgfx->timer); parport_write_control(tgfx->pd->port, 0x00); parport_release(tgfx->pd); } + up(&tgfx->sem); } /* @@ -166,11 +178,12 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs) return NULL; } - if (!(tgfx = kmalloc(sizeof(struct tgfx), GFP_KERNEL))) { + if (!(tgfx = kcalloc(1, sizeof(struct tgfx), GFP_KERNEL))) { parport_put_port(pp); return NULL; } - memset(tgfx, 0, sizeof(struct tgfx)); + + init_MUTEX(&tgfx->sem); tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); |