aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@iki.fi>2012-01-24 19:05:34 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 07:46:27 -0400
commit77e7c4e624404c6edb5686b3d5f873c6008ed6b0 (patch)
tree1ba1d9903bb8eca6e3ca3439d3a5981274ea86ba
parent8227c92b69688403dee2adf5f399a49539ae5049 (diff)
[media] v4l: Allow changing control handler lock
Allow choosing the lock used by the control handler. This may be handy sometimes when a driver providing multiple subdevs does not want to use several locks to serialise its functions. Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/adp1653.c8
-rw-r--r--drivers/media/video/v4l2-ctrls.c39
-rw-r--r--drivers/media/video/vivi.c4
-rw-r--r--include/media/v4l2-ctrls.h9
4 files changed, 32 insertions, 28 deletions
diff --git a/drivers/media/video/adp1653.c b/drivers/media/video/adp1653.c
index 24afc99d26e4..57e87090388d 100644
--- a/drivers/media/video/adp1653.c
+++ b/drivers/media/video/adp1653.c
@@ -281,19 +281,19 @@ adp1653_init_device(struct adp1653_flash *flash)
281 return -EIO; 281 return -EIO;
282 } 282 }
283 283
284 mutex_lock(&flash->ctrls.lock); 284 mutex_lock(flash->ctrls.lock);
285 /* Reset faults before reading new ones. */ 285 /* Reset faults before reading new ones. */
286 flash->fault = 0; 286 flash->fault = 0;
287 rval = adp1653_get_fault(flash); 287 rval = adp1653_get_fault(flash);
288 mutex_unlock(&flash->ctrls.lock); 288 mutex_unlock(flash->ctrls.lock);
289 if (rval > 0) { 289 if (rval > 0) {
290 dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval); 290 dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
291 return -EIO; 291 return -EIO;
292 } 292 }
293 293
294 mutex_lock(&flash->ctrls.lock); 294 mutex_lock(flash->ctrls.lock);
295 rval = adp1653_update_hw(flash); 295 rval = adp1653_update_hw(flash);
296 mutex_unlock(&flash->ctrls.lock); 296 mutex_unlock(flash->ctrls.lock);
297 if (rval) { 297 if (rval) {
298 dev_err(&client->dev, 298 dev_err(&client->dev,
299 "adp1653_update_hw failed at %s\n", __func__); 299 "adp1653_update_hw failed at %s\n", __func__);
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index edb2a6a066ca..e5531ace5ee7 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -1177,7 +1177,8 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
1177int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, 1177int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
1178 unsigned nr_of_controls_hint) 1178 unsigned nr_of_controls_hint)
1179{ 1179{
1180 mutex_init(&hdl->lock); 1180 hdl->lock = &hdl->_lock;
1181 mutex_init(hdl->lock);
1181 INIT_LIST_HEAD(&hdl->ctrls); 1182 INIT_LIST_HEAD(&hdl->ctrls);
1182 INIT_LIST_HEAD(&hdl->ctrl_refs); 1183 INIT_LIST_HEAD(&hdl->ctrl_refs);
1183 hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; 1184 hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
@@ -1198,7 +1199,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1198 if (hdl == NULL || hdl->buckets == NULL) 1199 if (hdl == NULL || hdl->buckets == NULL)
1199 return; 1200 return;
1200 1201
1201 mutex_lock(&hdl->lock); 1202 mutex_lock(hdl->lock);
1202 /* Free all nodes */ 1203 /* Free all nodes */
1203 list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { 1204 list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
1204 list_del(&ref->node); 1205 list_del(&ref->node);
@@ -1215,7 +1216,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1215 hdl->buckets = NULL; 1216 hdl->buckets = NULL;
1216 hdl->cached = NULL; 1217 hdl->cached = NULL;
1217 hdl->error = 0; 1218 hdl->error = 0;
1218 mutex_unlock(&hdl->lock); 1219 mutex_unlock(hdl->lock);
1219} 1220}
1220EXPORT_SYMBOL(v4l2_ctrl_handler_free); 1221EXPORT_SYMBOL(v4l2_ctrl_handler_free);
1221 1222
@@ -1280,9 +1281,9 @@ static struct v4l2_ctrl_ref *find_ref_lock(
1280 struct v4l2_ctrl_ref *ref = NULL; 1281 struct v4l2_ctrl_ref *ref = NULL;
1281 1282
1282 if (hdl) { 1283 if (hdl) {
1283 mutex_lock(&hdl->lock); 1284 mutex_lock(hdl->lock);
1284 ref = find_ref(hdl, id); 1285 ref = find_ref(hdl, id);
1285 mutex_unlock(&hdl->lock); 1286 mutex_unlock(hdl->lock);
1286 } 1287 }
1287 return ref; 1288 return ref;
1288} 1289}
@@ -1329,7 +1330,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
1329 1330
1330 INIT_LIST_HEAD(&new_ref->node); 1331 INIT_LIST_HEAD(&new_ref->node);
1331 1332
1332 mutex_lock(&hdl->lock); 1333 mutex_lock(hdl->lock);
1333 1334
1334 /* Add immediately at the end of the list if the list is empty, or if 1335 /* Add immediately at the end of the list if the list is empty, or if
1335 the last element in the list has a lower ID. 1336 the last element in the list has a lower ID.
@@ -1359,7 +1360,7 @@ insert_in_hash:
1359 hdl->buckets[bucket] = new_ref; 1360 hdl->buckets[bucket] = new_ref;
1360 1361
1361unlock: 1362unlock:
1362 mutex_unlock(&hdl->lock); 1363 mutex_unlock(hdl->lock);
1363 return 0; 1364 return 0;
1364} 1365}
1365 1366
@@ -1445,9 +1446,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1445 kfree(ctrl); 1446 kfree(ctrl);
1446 return NULL; 1447 return NULL;
1447 } 1448 }
1448 mutex_lock(&hdl->lock); 1449 mutex_lock(hdl->lock);
1449 list_add_tail(&ctrl->node, &hdl->ctrls); 1450 list_add_tail(&ctrl->node, &hdl->ctrls);
1450 mutex_unlock(&hdl->lock); 1451 mutex_unlock(hdl->lock);
1451 return ctrl; 1452 return ctrl;
1452} 1453}
1453 1454
@@ -1564,7 +1565,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
1564 return 0; 1565 return 0;
1565 if (hdl->error) 1566 if (hdl->error)
1566 return hdl->error; 1567 return hdl->error;
1567 mutex_lock(&add->lock); 1568 mutex_lock(add->lock);
1568 list_for_each_entry(ref, &add->ctrl_refs, node) { 1569 list_for_each_entry(ref, &add->ctrl_refs, node) {
1569 struct v4l2_ctrl *ctrl = ref->ctrl; 1570 struct v4l2_ctrl *ctrl = ref->ctrl;
1570 1571
@@ -1578,7 +1579,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
1578 if (ret) 1579 if (ret)
1579 break; 1580 break;
1580 } 1581 }
1581 mutex_unlock(&add->lock); 1582 mutex_unlock(add->lock);
1582 return ret; 1583 return ret;
1583} 1584}
1584EXPORT_SYMBOL(v4l2_ctrl_add_handler); 1585EXPORT_SYMBOL(v4l2_ctrl_add_handler);
@@ -1742,11 +1743,11 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
1742 len = strlen(prefix); 1743 len = strlen(prefix);
1743 if (len && prefix[len - 1] != ' ') 1744 if (len && prefix[len - 1] != ' ')
1744 colon = ": "; 1745 colon = ": ";
1745 mutex_lock(&hdl->lock); 1746 mutex_lock(hdl->lock);
1746 list_for_each_entry(ctrl, &hdl->ctrls, node) 1747 list_for_each_entry(ctrl, &hdl->ctrls, node)
1747 if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) 1748 if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
1748 log_ctrl(ctrl, prefix, colon); 1749 log_ctrl(ctrl, prefix, colon);
1749 mutex_unlock(&hdl->lock); 1750 mutex_unlock(hdl->lock);
1750} 1751}
1751EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); 1752EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
1752 1753
@@ -1758,7 +1759,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
1758 1759
1759 if (hdl == NULL) 1760 if (hdl == NULL)
1760 return 0; 1761 return 0;
1761 mutex_lock(&hdl->lock); 1762 mutex_lock(hdl->lock);
1762 list_for_each_entry(ctrl, &hdl->ctrls, node) 1763 list_for_each_entry(ctrl, &hdl->ctrls, node)
1763 ctrl->done = false; 1764 ctrl->done = false;
1764 1765
@@ -1783,7 +1784,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
1783 if (ret) 1784 if (ret)
1784 break; 1785 break;
1785 } 1786 }
1786 mutex_unlock(&hdl->lock); 1787 mutex_unlock(hdl->lock);
1787 return ret; 1788 return ret;
1788} 1789}
1789EXPORT_SYMBOL(v4l2_ctrl_handler_setup); 1790EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
@@ -1798,7 +1799,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
1798 if (hdl == NULL) 1799 if (hdl == NULL)
1799 return -EINVAL; 1800 return -EINVAL;
1800 1801
1801 mutex_lock(&hdl->lock); 1802 mutex_lock(hdl->lock);
1802 1803
1803 /* Try to find it */ 1804 /* Try to find it */
1804 ref = find_ref(hdl, id); 1805 ref = find_ref(hdl, id);
@@ -1823,7 +1824,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
1823 break; 1824 break;
1824 } 1825 }
1825 } 1826 }
1826 mutex_unlock(&hdl->lock); 1827 mutex_unlock(hdl->lock);
1827 if (!ref) 1828 if (!ref)
1828 return -EINVAL; 1829 return -EINVAL;
1829 1830
@@ -2000,7 +2001,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
2000 belong to the same cluster. */ 2001 belong to the same cluster. */
2001 2002
2002 /* This has to be done with the handler lock taken. */ 2003 /* This has to be done with the handler lock taken. */
2003 mutex_lock(&hdl->lock); 2004 mutex_lock(hdl->lock);
2004 2005
2005 /* First zero the helper field in the master control references */ 2006 /* First zero the helper field in the master control references */
2006 for (i = 0; i < cs->count; i++) 2007 for (i = 0; i < cs->count; i++)
@@ -2022,7 +2023,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
2022 /* Point the mref helper to the current helper struct. */ 2023 /* Point the mref helper to the current helper struct. */
2023 mref->helper = h; 2024 mref->helper = h;
2024 } 2025 }
2025 mutex_unlock(&hdl->lock); 2026 mutex_unlock(hdl->lock);
2026 return 0; 2027 return 0;
2027} 2028}
2028 2029
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index d64d482f4f6b..6f2e354a242d 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -485,7 +485,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
485 gen_text(dev, vbuf, line++ * 16, 16, str); 485 gen_text(dev, vbuf, line++ * 16, 16, str);
486 486
487 gain = v4l2_ctrl_g_ctrl(dev->gain); 487 gain = v4l2_ctrl_g_ctrl(dev->gain);
488 mutex_lock(&dev->ctrl_handler.lock); 488 mutex_lock(dev->ctrl_handler.lock);
489 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", 489 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
490 dev->brightness->cur.val, 490 dev->brightness->cur.val,
491 dev->contrast->cur.val, 491 dev->contrast->cur.val,
@@ -509,7 +509,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
509 dev->int_menu->qmenu_int[dev->int_menu->cur.val], 509 dev->int_menu->qmenu_int[dev->int_menu->cur.val],
510 dev->int_menu->cur.val); 510 dev->int_menu->cur.val);
511 gen_text(dev, vbuf, line++ * 16, 16, str); 511 gen_text(dev, vbuf, line++ * 16, 16, str);
512 mutex_unlock(&dev->ctrl_handler.lock); 512 mutex_unlock(dev->ctrl_handler.lock);
513 if (dev->button_pressed) { 513 if (dev->button_pressed) {
514 dev->button_pressed--; 514 dev->button_pressed--;
515 snprintf(str, sizeof(str), " button pressed!"); 515 snprintf(str, sizeof(str), " button pressed!");
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index c6f6b4c2c5f2..dde6fbacc271 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -167,7 +167,9 @@ struct v4l2_ctrl_ref {
167/** struct v4l2_ctrl_handler - The control handler keeps track of all the 167/** struct v4l2_ctrl_handler - The control handler keeps track of all the
168 * controls: both the controls owned by the handler and those inherited 168 * controls: both the controls owned by the handler and those inherited
169 * from other handlers. 169 * from other handlers.
170 * @_lock: Default for "lock".
170 * @lock: Lock to control access to this handler and its controls. 171 * @lock: Lock to control access to this handler and its controls.
172 * May be replaced by the user right after init.
171 * @ctrls: The list of controls owned by this handler. 173 * @ctrls: The list of controls owned by this handler.
172 * @ctrl_refs: The list of control references. 174 * @ctrl_refs: The list of control references.
173 * @cached: The last found control reference. It is common that the same 175 * @cached: The last found control reference. It is common that the same
@@ -178,7 +180,8 @@ struct v4l2_ctrl_ref {
178 * @error: The error code of the first failed control addition. 180 * @error: The error code of the first failed control addition.
179 */ 181 */
180struct v4l2_ctrl_handler { 182struct v4l2_ctrl_handler {
181 struct mutex lock; 183 struct mutex _lock;
184 struct mutex *lock;
182 struct list_head ctrls; 185 struct list_head ctrls;
183 struct list_head ctrl_refs; 186 struct list_head ctrl_refs;
184 struct v4l2_ctrl_ref *cached; 187 struct v4l2_ctrl_ref *cached;
@@ -455,7 +458,7 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
455 */ 458 */
456static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) 459static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
457{ 460{
458 mutex_lock(&ctrl->handler->lock); 461 mutex_lock(ctrl->handler->lock);
459} 462}
460 463
461/** v4l2_ctrl_lock() - Helper function to unlock the handler 464/** v4l2_ctrl_lock() - Helper function to unlock the handler
@@ -464,7 +467,7 @@ static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
464 */ 467 */
465static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl) 468static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
466{ 469{
467 mutex_unlock(&ctrl->handler->lock); 470 mutex_unlock(ctrl->handler->lock);
468} 471}
469 472
470/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. 473/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.