Commit 8abdd00d authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

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: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 2c6a37bb
...@@ -421,6 +421,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) ...@@ -421,6 +421,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->serialize_lock); mutex_init(&cx->serialize_lock);
mutex_init(&cx->i2c_bus_lock[0]); mutex_init(&cx->i2c_bus_lock[0]);
mutex_init(&cx->i2c_bus_lock[1]); mutex_init(&cx->i2c_bus_lock[1]);
mutex_init(&cx->gpio_lock);
spin_lock_init(&cx->lock); spin_lock_init(&cx->lock);
spin_lock_init(&cx->dma_reg_lock); spin_lock_init(&cx->dma_reg_lock);
......
...@@ -427,6 +427,7 @@ struct cx18 { ...@@ -427,6 +427,7 @@ struct cx18 {
/* gpio */ /* gpio */
u32 gpio_dir; u32 gpio_dir;
u32 gpio_val; u32 gpio_val;
struct mutex gpio_lock;
/* v4l2 and User settings */ /* v4l2 and User settings */
......
...@@ -69,6 +69,7 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) ...@@ -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 */ /* Assuming that the masks are a subset of the bits in gpio_dir */
/* Assert */ /* Assert */
mutex_lock(&cx->gpio_lock);
cx->gpio_val = cx->gpio_val =
(cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
gpio_write(cx); gpio_write(cx);
...@@ -79,10 +80,12 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *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); (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
gpio_write(cx); gpio_write(cx);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
mutex_unlock(&cx->gpio_lock);
} }
void cx18_gpio_init(struct cx18 *cx) void cx18_gpio_init(struct cx18 *cx)
{ {
mutex_lock(&cx->gpio_lock);
cx->gpio_dir = cx->card->gpio_init.direction; cx->gpio_dir = cx->card->gpio_init.direction;
cx->gpio_val = cx->card->gpio_init.initial_value; cx->gpio_val = cx->card->gpio_init.initial_value;
...@@ -91,14 +94,17 @@ void cx18_gpio_init(struct cx18 *cx) ...@@ -91,14 +94,17 @@ void cx18_gpio_init(struct cx18 *cx)
cx->gpio_val |= 1 << cx->card->xceive_pin; cx->gpio_val |= 1 << cx->card->xceive_pin;
} }
if (cx->gpio_dir == 0) if (cx->gpio_dir == 0) {
mutex_unlock(&cx->gpio_lock);
return; return;
}
CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", 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_DIR1), read_reg(CX18_REG_GPIO_DIR2),
read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
gpio_write(cx); gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
} }
/* Xceive tuner reset function */ /* Xceive tuner reset function */
...@@ -112,13 +118,16 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) ...@@ -112,13 +118,16 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
return 0; return 0;
CX18_DEBUG_INFO("Resetting tuner\n"); CX18_DEBUG_INFO("Resetting tuner\n");
mutex_lock(&cx->gpio_lock);
cx->gpio_val &= ~(1 << cx->card->xceive_pin); cx->gpio_val &= ~(1 << cx->card->xceive_pin);
gpio_write(cx); gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
schedule_timeout_interruptible(msecs_to_jiffies(1)); schedule_timeout_interruptible(msecs_to_jiffies(1));
mutex_lock(&cx->gpio_lock);
cx->gpio_val |= 1 << cx->card->xceive_pin; cx->gpio_val |= 1 << cx->card->xceive_pin;
gpio_write(cx); gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
schedule_timeout_interruptible(msecs_to_jiffies(1)); schedule_timeout_interruptible(msecs_to_jiffies(1));
return 0; return 0;
} }
...@@ -151,8 +160,10 @@ int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) ...@@ -151,8 +160,10 @@ int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
return -EINVAL; return -EINVAL;
} }
if (mask) { if (mask) {
mutex_lock(&cx->gpio_lock);
cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
gpio_write(cx); gpio_write(cx);
mutex_unlock(&cx->gpio_lock);
} }
return 0; return 0;
} }
...@@ -716,8 +716,10 @@ static int cx18_log_status(struct file *file, void *fh) ...@@ -716,8 +716,10 @@ static int cx18_log_status(struct file *file, void *fh)
cx18_get_audio_input(cx, cx->audio_input, &audin); cx18_get_audio_input(cx, cx->audio_input, &audin);
CX18_INFO("Video Input: %s\n", vidin.name); CX18_INFO("Video Input: %s\n", vidin.name);
CX18_INFO("Audio Input: %s\n", audin.name); CX18_INFO("Audio Input: %s\n", audin.name);
mutex_lock(&cx->gpio_lock);
CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
cx->gpio_dir, cx->gpio_val); cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
CX18_INFO("Tuner: %s\n", CX18_INFO("Tuner: %s\n",
test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
cx2341x_log_status(&cx->params, cx->name); cx2341x_log_status(&cx->params, cx->name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment