diff --git a/drivers/pps/generators/pps_gen.c b/drivers/pps/generators/pps_gen.c index 452cc12a96f2..474e17c36458 100644 --- a/drivers/pps/generators/pps_gen.c +++ b/drivers/pps/generators/pps_gen.c @@ -103,11 +103,14 @@ static long pps_gen_cdev_ioctl(struct file *file, dev_dbg(&pps_gen->dev, "PPS_GEN_FETCHEVENT\n"); ret = wait_event_interruptible(pps_gen->queue, - ev != pps_gen->last_ev); + ev != pps_gen->last_ev || + !READ_ONCE(pps_gen->info)); if (ret == -ERESTARTSYS) { dev_dbg(&pps_gen->dev, "pending signal caught\n"); return -EINTR; } + if (!READ_ONCE(pps_gen->info)) + return -ENODEV; spin_lock_irq(&pps_gen->lock); info.sequence = pps_gen->sequence; @@ -238,9 +241,12 @@ static void pps_gen_unregister_cdev(struct pps_gen_device *pps_gen) pps_gen->info->enable(pps_gen, false); pps_gen->enabled = false; } - pps_gen->info = NULL; + WRITE_ONCE(pps_gen->info, NULL); } + /* Wake up the readers in PPS_GEN_FETCHEVENT, they fail now as well */ + wake_up_interruptible_all(&pps_gen->queue); + put_device(&pps_gen->dev); }