wait_queue_head_t wait;
struct list_head client_list;
struct list_head node;
+ bool dead;
};
struct serio_raw_client {
goto out;
}
- if (!serio_raw->serio) {
+ if (serio_raw->dead) {
retval = -ENODEV;
goto out;
}
misc_deregister(&serio_raw->dev);
list_del_init(&serio_raw->node);
+
+ put_device(&serio_raw->serio->dev);
kfree(serio_raw);
}
char uninitialized_var(c);
ssize_t retval = 0;
- if (!serio_raw->serio)
+ if (serio_raw->dead)
return -ENODEV;
if (serio_raw->head == serio_raw->tail && (file->f_flags & O_NONBLOCK))
return -EAGAIN;
retval = wait_event_interruptible(serio_raw->wait,
- serio_raw->head != serio_raw->tail ||
- !serio_raw->serio);
+ serio_raw->head != serio_raw->tail || serio_raw->dead);
if (retval)
return retval;
- if (!serio_raw->serio)
+ if (serio_raw->dead)
return -ENODEV;
while (retval < count && serio_raw_fetch_byte(serio_raw, &c)) {
if (retval)
return retval;
- if (!serio_raw->serio) {
+ if (serio_raw->dead) {
retval = -ENODEV;
goto out;
}
snprintf(serio_raw->name, sizeof(serio_raw->name),
"serio_raw%d", serio_raw_no++);
kref_init(&serio_raw->kref);
- serio_raw->serio = serio;
INIT_LIST_HEAD(&serio_raw->client_list);
init_waitqueue_head(&serio_raw->wait);
+ serio_raw->serio = serio;
+ get_device(&serio->dev);
+
serio_set_drvdata(serio, serio_raw);
err = serio_open(serio, drv);
list_del_init(&serio_raw->node);
out_free:
serio_set_drvdata(serio, NULL);
+ put_device(&serio->dev);
kfree(serio_raw);
out:
mutex_unlock(&serio_raw_mutex);
serio_close(serio);
serio_set_drvdata(serio, NULL);
- serio_raw->serio = NULL;
+ serio_raw->dead = true;
wake_up_interruptible(&serio_raw->wait);
kref_put(&serio_raw->kref, serio_raw_cleanup);