From: Andy Walls Date: Sun, 13 Jul 2008 22:05:25 +0000 (-0300) Subject: V4L/DVB (8331): cx18: Add locking for struct cx18 GPIO state variables X-Git-Tag: v2.6.27-rc1~966^2~53 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8abdd00dcc6a58cab3afe6a23a0ce819dc08049a;p=linux-2.6 V4L/DVB (8331): cx18: Add locking for struct cx18 GPIO state variables cx18: Add locking for struct cx18 GPIO state variables in anticpation of adding IR microcontroller reset support for use by external IR modules. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index e73de62522..22434aadde 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -421,6 +421,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->serialize_lock); mutex_init(&cx->i2c_bus_lock[0]); mutex_init(&cx->i2c_bus_lock[1]); + mutex_init(&cx->gpio_lock); spin_lock_init(&cx->lock); spin_lock_init(&cx->dma_reg_lock); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index b78d0e38d5..45e31b0473 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -427,6 +427,7 @@ struct cx18 { /* gpio */ u32 gpio_dir; u32 gpio_val; + struct mutex gpio_lock; /* v4l2 and User settings */ diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 089bad6d85..d753a40973 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -69,6 +69,7 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) /* Assuming that the masks are a subset of the bits in gpio_dir */ /* Assert */ + mutex_lock(&cx->gpio_lock); cx->gpio_val = (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); gpio_write(cx); @@ -79,10 +80,12 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); gpio_write(cx); schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); + mutex_unlock(&cx->gpio_lock); } void cx18_gpio_init(struct cx18 *cx) { + mutex_lock(&cx->gpio_lock); cx->gpio_dir = cx->card->gpio_init.direction; cx->gpio_val = cx->card->gpio_init.initial_value; @@ -91,14 +94,17 @@ void cx18_gpio_init(struct cx18 *cx) cx->gpio_val |= 1 << cx->card->xceive_pin; } - if (cx->gpio_dir == 0) + if (cx->gpio_dir == 0) { + mutex_unlock(&cx->gpio_lock); return; + } CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); gpio_write(cx); + mutex_unlock(&cx->gpio_lock); } /* Xceive tuner reset function */ @@ -112,13 +118,16 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) return 0; CX18_DEBUG_INFO("Resetting tuner\n"); + mutex_lock(&cx->gpio_lock); cx->gpio_val &= ~(1 << cx->card->xceive_pin); - gpio_write(cx); + mutex_unlock(&cx->gpio_lock); schedule_timeout_interruptible(msecs_to_jiffies(1)); + mutex_lock(&cx->gpio_lock); cx->gpio_val |= 1 << cx->card->xceive_pin; gpio_write(cx); + mutex_unlock(&cx->gpio_lock); schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; } @@ -151,8 +160,10 @@ int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) return -EINVAL; } if (mask) { + mutex_lock(&cx->gpio_lock); cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); gpio_write(cx); + mutex_unlock(&cx->gpio_lock); } return 0; } diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 6eaf77b99e..146a4b8564 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -716,8 +716,10 @@ static int cx18_log_status(struct file *file, void *fh) cx18_get_audio_input(cx, cx->audio_input, &audin); CX18_INFO("Video Input: %s\n", vidin.name); CX18_INFO("Audio Input: %s\n", audin.name); + mutex_lock(&cx->gpio_lock); CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", cx->gpio_dir, cx->gpio_val); + mutex_unlock(&cx->gpio_lock); CX18_INFO("Tuner: %s\n", test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&cx->params, cx->name);