Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Andy Walls and committed by
Mauro Carvalho Chehab
8abdd00d 2c6a37bb

+17 -2
+1
drivers/media/video/cx18/cx18-driver.c
··· 421 421 mutex_init(&cx->serialize_lock); 422 422 mutex_init(&cx->i2c_bus_lock[0]); 423 423 mutex_init(&cx->i2c_bus_lock[1]); 424 + mutex_init(&cx->gpio_lock); 424 425 425 426 spin_lock_init(&cx->lock); 426 427 spin_lock_init(&cx->dma_reg_lock);
+1
drivers/media/video/cx18/cx18-driver.h
··· 427 427 /* gpio */ 428 428 u32 gpio_dir; 429 429 u32 gpio_val; 430 + struct mutex gpio_lock; 430 431 431 432 /* v4l2 and User settings */ 432 433
+13 -2
drivers/media/video/cx18/cx18-gpio.c
··· 69 69 /* Assuming that the masks are a subset of the bits in gpio_dir */ 70 70 71 71 /* Assert */ 72 + mutex_lock(&cx->gpio_lock); 72 73 cx->gpio_val = 73 74 (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); 74 75 gpio_write(cx); ··· 80 79 (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); 81 80 gpio_write(cx); 82 81 schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); 82 + mutex_unlock(&cx->gpio_lock); 83 83 } 84 84 85 85 void cx18_gpio_init(struct cx18 *cx) 86 86 { 87 + mutex_lock(&cx->gpio_lock); 87 88 cx->gpio_dir = cx->card->gpio_init.direction; 88 89 cx->gpio_val = cx->card->gpio_init.initial_value; 89 90 ··· 94 91 cx->gpio_val |= 1 << cx->card->xceive_pin; 95 92 } 96 93 97 - if (cx->gpio_dir == 0) 94 + if (cx->gpio_dir == 0) { 95 + mutex_unlock(&cx->gpio_lock); 98 96 return; 97 + } 99 98 100 99 CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", 101 100 read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), 102 101 read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); 103 102 104 103 gpio_write(cx); 104 + mutex_unlock(&cx->gpio_lock); 105 105 } 106 106 107 107 /* Xceive tuner reset function */ ··· 118 112 return 0; 119 113 CX18_DEBUG_INFO("Resetting tuner\n"); 120 114 115 + mutex_lock(&cx->gpio_lock); 121 116 cx->gpio_val &= ~(1 << cx->card->xceive_pin); 122 - 123 117 gpio_write(cx); 118 + mutex_unlock(&cx->gpio_lock); 124 119 schedule_timeout_interruptible(msecs_to_jiffies(1)); 125 120 121 + mutex_lock(&cx->gpio_lock); 126 122 cx->gpio_val |= 1 << cx->card->xceive_pin; 127 123 gpio_write(cx); 124 + mutex_unlock(&cx->gpio_lock); 128 125 schedule_timeout_interruptible(msecs_to_jiffies(1)); 129 126 return 0; 130 127 } ··· 160 151 return -EINVAL; 161 152 } 162 153 if (mask) { 154 + mutex_lock(&cx->gpio_lock); 163 155 cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); 164 156 gpio_write(cx); 157 + mutex_unlock(&cx->gpio_lock); 165 158 } 166 159 return 0; 167 160 }
+2
drivers/media/video/cx18/cx18-ioctl.c
··· 716 716 cx18_get_audio_input(cx, cx->audio_input, &audin); 717 717 CX18_INFO("Video Input: %s\n", vidin.name); 718 718 CX18_INFO("Audio Input: %s\n", audin.name); 719 + mutex_lock(&cx->gpio_lock); 719 720 CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", 720 721 cx->gpio_dir, cx->gpio_val); 722 + mutex_unlock(&cx->gpio_lock); 721 723 CX18_INFO("Tuner: %s\n", 722 724 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); 723 725 cx2341x_log_status(&cx->params, cx->name);