diff options
author | Sakari Ailus <sakari.ailus@iki.fi> | 2012-01-24 19:05:34 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 07:46:27 -0400 |
commit | 77e7c4e624404c6edb5686b3d5f873c6008ed6b0 (patch) | |
tree | 1ba1d9903bb8eca6e3ca3439d3a5981274ea86ba | |
parent | 8227c92b69688403dee2adf5f399a49539ae5049 (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.c | 8 | ||||
-rw-r--r-- | drivers/media/video/v4l2-ctrls.c | 39 | ||||
-rw-r--r-- | drivers/media/video/vivi.c | 4 | ||||
-rw-r--r-- | include/media/v4l2-ctrls.h | 9 |
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) | |||
1177 | int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, | 1177 | int 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 | } |
1220 | EXPORT_SYMBOL(v4l2_ctrl_handler_free); | 1221 | EXPORT_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 | ||
1361 | unlock: | 1362 | unlock: |
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 | } |
1584 | EXPORT_SYMBOL(v4l2_ctrl_add_handler); | 1585 | EXPORT_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 | } |
1751 | EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); | 1752 | EXPORT_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 | } |
1789 | EXPORT_SYMBOL(v4l2_ctrl_handler_setup); | 1790 | EXPORT_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 | */ |
180 | struct v4l2_ctrl_handler { | 182 | struct 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 | */ |
456 | static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) | 459 | static 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 | */ |
465 | static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl) | 468 | static 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. |