Em 19-11-2010 21:43, David HÃrdeman escreveu: > The use of the saa7134_card_ir->users seems racy, so protect the count with > a spinlock. Also use proper data types as arguments to __saa7134_ir_start() > and __saa7134_ir_stop() to remove some unnecessary casts. Hmm... instead of using a spinlock, the better seems to use an atomic_t. > > Signed-off-by: David HÃrdeman <david@xxxxxxxxxxx> > --- > drivers/media/video/saa7134/saa7134-input.c | 54 ++++++++++++++++----------- > drivers/media/video/saa7134/saa7134.h | 1 + > 2 files changed, 33 insertions(+), 22 deletions(-) > > diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c > index 98678d9..8b80efb 100644 > --- a/drivers/media/video/saa7134/saa7134-input.c > +++ b/drivers/media/video/saa7134/saa7134-input.c > @@ -402,17 +402,12 @@ static void ir_raw_decode_timer_end(unsigned long data) > ir->active = false; > } > > -static int __saa7134_ir_start(void *priv) > +static void __saa7134_ir_start(struct saa7134_dev *dev) > { > - struct saa7134_dev *dev = priv; > - struct saa7134_card_ir *ir; > - > - if (!dev || !dev->remote) > - return -EINVAL; > + struct saa7134_card_ir *ir = dev->remote; > > - ir = dev->remote; > if (ir->running) > - return 0; > + return; > > ir->running = true; > ir->active = false; > @@ -427,19 +422,12 @@ static int __saa7134_ir_start(void *priv) > setup_timer(&ir->timer, ir_raw_decode_timer_end, > (unsigned long)dev); > } > - > - return 0; > } > > -static void __saa7134_ir_stop(void *priv) > +static void __saa7134_ir_stop(struct saa7134_dev *dev) > { > - struct saa7134_dev *dev = priv; > - struct saa7134_card_ir *ir; > - > - if (!dev || !dev->remote) > - return; > + struct saa7134_card_ir *ir = dev->remote; > > - ir = dev->remote; > if (!ir->running) > return; > > @@ -448,39 +436,60 @@ static void __saa7134_ir_stop(void *priv) > > ir->active = false; > ir->running = false; > - > - return; > } > > int saa7134_ir_start(struct saa7134_dev *dev) > { > + if (!dev || !dev->remote) > + return -EINVAL; > + > + spin_lock(&dev->remote->lock); > if (dev->remote->users) > - return __saa7134_ir_start(dev); > + __saa7134_ir_start(dev); > + spin_unlock(&dev->remote->lock); > > return 0; > } > > void saa7134_ir_stop(struct saa7134_dev *dev) > { > + if (!dev || !dev->remote) > + return; > + > + spin_lock(&dev->remote->lock); > if (dev->remote->users) > __saa7134_ir_stop(dev); > + spin_unlock(&dev->remote->lock); > } > > static int saa7134_ir_open(struct rc_dev *rc) > { > struct saa7134_dev *dev = rc->priv; > > + if (!dev || !dev->remote) > + return -EINVAL; > + > + spin_lock(&dev->remote->lock); > + if (dev->remote->users == 0) > + __saa7134_ir_start(dev); > dev->remote->users++; > - return __saa7134_ir_start(dev); > + spin_unlock(&dev->remote->lock); > + > + return 0; > } > > static void saa7134_ir_close(struct rc_dev *rc) > { > struct saa7134_dev *dev = rc->priv; > > + if (!dev || !dev->remote) > + return; > + > + spin_lock(&dev->remote->lock); > dev->remote->users--; > - if (!dev->remote->users) > + if (dev->remote->users == 0) > __saa7134_ir_stop(dev); > + spin_unlock(&dev->remote->lock); > } > > int saa7134_input_init1(struct saa7134_dev *dev) > @@ -744,6 +753,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) > ir->mask_keyup = mask_keyup; > ir->polling = polling; > ir->raw_decode = raw_decode; > + spin_lock_init(&ir->lock); > > /* init input device */ > snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", > diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h > index babfbe7..7c836c3 100644 > --- a/drivers/media/video/saa7134/saa7134.h > +++ b/drivers/media/video/saa7134/saa7134.h > @@ -125,6 +125,7 @@ struct saa7134_card_ir { > char name[32]; > char phys[32]; > unsigned users; > + spinlock_t lock; > > u32 polling; > u32 last_gpio; > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html