Commit 77e7c4e6 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

[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: default avatarSakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 8227c92b
...@@ -281,19 +281,19 @@ adp1653_init_device(struct adp1653_flash *flash) ...@@ -281,19 +281,19 @@ adp1653_init_device(struct adp1653_flash *flash)
return -EIO; return -EIO;
} }
mutex_lock(&flash->ctrls.lock); mutex_lock(flash->ctrls.lock);
/* Reset faults before reading new ones. */ /* Reset faults before reading new ones. */
flash->fault = 0; flash->fault = 0;
rval = adp1653_get_fault(flash); rval = adp1653_get_fault(flash);
mutex_unlock(&flash->ctrls.lock); mutex_unlock(flash->ctrls.lock);
if (rval > 0) { if (rval > 0) {
dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval); dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
return -EIO; return -EIO;
} }
mutex_lock(&flash->ctrls.lock); mutex_lock(flash->ctrls.lock);
rval = adp1653_update_hw(flash); rval = adp1653_update_hw(flash);
mutex_unlock(&flash->ctrls.lock); mutex_unlock(flash->ctrls.lock);
if (rval) { if (rval) {
dev_err(&client->dev, dev_err(&client->dev,
"adp1653_update_hw failed at %s\n", __func__); "adp1653_update_hw failed at %s\n", __func__);
......
...@@ -1177,7 +1177,8 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err) ...@@ -1177,7 +1177,8 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl, int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
unsigned nr_of_controls_hint) unsigned nr_of_controls_hint)
{ {
mutex_init(&hdl->lock); hdl->lock = &hdl->_lock;
mutex_init(hdl->lock);
INIT_LIST_HEAD(&hdl->ctrls); INIT_LIST_HEAD(&hdl->ctrls);
INIT_LIST_HEAD(&hdl->ctrl_refs); INIT_LIST_HEAD(&hdl->ctrl_refs);
hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; 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,7 +1199,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
if (hdl == NULL || hdl->buckets == NULL) if (hdl == NULL || hdl->buckets == NULL)
return; return;
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
/* Free all nodes */ /* Free all nodes */
list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) { list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
list_del(&ref->node); list_del(&ref->node);
...@@ -1215,7 +1216,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl) ...@@ -1215,7 +1216,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
hdl->buckets = NULL; hdl->buckets = NULL;
hdl->cached = NULL; hdl->cached = NULL;
hdl->error = 0; hdl->error = 0;
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
} }
EXPORT_SYMBOL(v4l2_ctrl_handler_free); EXPORT_SYMBOL(v4l2_ctrl_handler_free);
...@@ -1280,9 +1281,9 @@ static struct v4l2_ctrl_ref *find_ref_lock( ...@@ -1280,9 +1281,9 @@ static struct v4l2_ctrl_ref *find_ref_lock(
struct v4l2_ctrl_ref *ref = NULL; struct v4l2_ctrl_ref *ref = NULL;
if (hdl) { if (hdl) {
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
ref = find_ref(hdl, id); ref = find_ref(hdl, id);
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
} }
return ref; return ref;
} }
...@@ -1329,7 +1330,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl, ...@@ -1329,7 +1330,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
INIT_LIST_HEAD(&new_ref->node); INIT_LIST_HEAD(&new_ref->node);
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
/* Add immediately at the end of the list if the list is empty, or if /* Add immediately at the end of the list if the list is empty, or if
the last element in the list has a lower ID. the last element in the list has a lower ID.
...@@ -1359,7 +1360,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl, ...@@ -1359,7 +1360,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
hdl->buckets[bucket] = new_ref; hdl->buckets[bucket] = new_ref;
unlock: unlock:
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
return 0; return 0;
} }
...@@ -1445,9 +1446,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, ...@@ -1445,9 +1446,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
kfree(ctrl); kfree(ctrl);
return NULL; return NULL;
} }
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
list_add_tail(&ctrl->node, &hdl->ctrls); list_add_tail(&ctrl->node, &hdl->ctrls);
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
return ctrl; return ctrl;
} }
...@@ -1564,7 +1565,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, ...@@ -1564,7 +1565,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
return 0; return 0;
if (hdl->error) if (hdl->error)
return hdl->error; return hdl->error;
mutex_lock(&add->lock); mutex_lock(add->lock);
list_for_each_entry(ref, &add->ctrl_refs, node) { list_for_each_entry(ref, &add->ctrl_refs, node) {
struct v4l2_ctrl *ctrl = ref->ctrl; struct v4l2_ctrl *ctrl = ref->ctrl;
...@@ -1578,7 +1579,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, ...@@ -1578,7 +1579,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
if (ret) if (ret)
break; break;
} }
mutex_unlock(&add->lock); mutex_unlock(add->lock);
return ret; return ret;
} }
EXPORT_SYMBOL(v4l2_ctrl_add_handler); EXPORT_SYMBOL(v4l2_ctrl_add_handler);
...@@ -1742,11 +1743,11 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, ...@@ -1742,11 +1743,11 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
len = strlen(prefix); len = strlen(prefix);
if (len && prefix[len - 1] != ' ') if (len && prefix[len - 1] != ' ')
colon = ": "; colon = ": ";
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
list_for_each_entry(ctrl, &hdl->ctrls, node) list_for_each_entry(ctrl, &hdl->ctrls, node)
if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED)) if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
log_ctrl(ctrl, prefix, colon); log_ctrl(ctrl, prefix, colon);
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
} }
EXPORT_SYMBOL(v4l2_ctrl_handler_log_status); EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
...@@ -1758,7 +1759,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) ...@@ -1758,7 +1759,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
if (hdl == NULL) if (hdl == NULL)
return 0; return 0;
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
list_for_each_entry(ctrl, &hdl->ctrls, node) list_for_each_entry(ctrl, &hdl->ctrls, node)
ctrl->done = false; ctrl->done = false;
...@@ -1783,7 +1784,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) ...@@ -1783,7 +1784,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
if (ret) if (ret)
break; break;
} }
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
return ret; return ret;
} }
EXPORT_SYMBOL(v4l2_ctrl_handler_setup); EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
...@@ -1798,7 +1799,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) ...@@ -1798,7 +1799,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
if (hdl == NULL) if (hdl == NULL)
return -EINVAL; return -EINVAL;
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
/* Try to find it */ /* Try to find it */
ref = find_ref(hdl, id); ref = find_ref(hdl, id);
...@@ -1823,7 +1824,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) ...@@ -1823,7 +1824,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
break; break;
} }
} }
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
if (!ref) if (!ref)
return -EINVAL; return -EINVAL;
...@@ -2000,7 +2001,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, ...@@ -2000,7 +2001,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
belong to the same cluster. */ belong to the same cluster. */
/* This has to be done with the handler lock taken. */ /* This has to be done with the handler lock taken. */
mutex_lock(&hdl->lock); mutex_lock(hdl->lock);
/* First zero the helper field in the master control references */ /* First zero the helper field in the master control references */
for (i = 0; i < cs->count; i++) for (i = 0; i < cs->count; i++)
...@@ -2022,7 +2023,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, ...@@ -2022,7 +2023,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
/* Point the mref helper to the current helper struct. */ /* Point the mref helper to the current helper struct. */
mref->helper = h; mref->helper = h;
} }
mutex_unlock(&hdl->lock); mutex_unlock(hdl->lock);
return 0; return 0;
} }
......
...@@ -485,7 +485,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) ...@@ -485,7 +485,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
gen_text(dev, vbuf, line++ * 16, 16, str); gen_text(dev, vbuf, line++ * 16, 16, str);
gain = v4l2_ctrl_g_ctrl(dev->gain); gain = v4l2_ctrl_g_ctrl(dev->gain);
mutex_lock(&dev->ctrl_handler.lock); mutex_lock(dev->ctrl_handler.lock);
snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
dev->brightness->cur.val, dev->brightness->cur.val,
dev->contrast->cur.val, dev->contrast->cur.val,
...@@ -509,7 +509,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) ...@@ -509,7 +509,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
dev->int_menu->qmenu_int[dev->int_menu->cur.val], dev->int_menu->qmenu_int[dev->int_menu->cur.val],
dev->int_menu->cur.val); dev->int_menu->cur.val);
gen_text(dev, vbuf, line++ * 16, 16, str); gen_text(dev, vbuf, line++ * 16, 16, str);
mutex_unlock(&dev->ctrl_handler.lock); mutex_unlock(dev->ctrl_handler.lock);
if (dev->button_pressed) { if (dev->button_pressed) {
dev->button_pressed--; dev->button_pressed--;
snprintf(str, sizeof(str), " button pressed!"); snprintf(str, sizeof(str), " button pressed!");
......
...@@ -167,7 +167,9 @@ struct v4l2_ctrl_ref { ...@@ -167,7 +167,9 @@ struct v4l2_ctrl_ref {
/** struct v4l2_ctrl_handler - The control handler keeps track of all the /** struct v4l2_ctrl_handler - The control handler keeps track of all the
* controls: both the controls owned by the handler and those inherited * controls: both the controls owned by the handler and those inherited
* from other handlers. * from other handlers.
* @_lock: Default for "lock".
* @lock: Lock to control access to this handler and its controls. * @lock: Lock to control access to this handler and its controls.
* May be replaced by the user right after init.
* @ctrls: The list of controls owned by this handler. * @ctrls: The list of controls owned by this handler.
* @ctrl_refs: The list of control references. * @ctrl_refs: The list of control references.
* @cached: The last found control reference. It is common that the same * @cached: The last found control reference. It is common that the same
...@@ -178,7 +180,8 @@ struct v4l2_ctrl_ref { ...@@ -178,7 +180,8 @@ struct v4l2_ctrl_ref {
* @error: The error code of the first failed control addition. * @error: The error code of the first failed control addition.
*/ */
struct v4l2_ctrl_handler { struct v4l2_ctrl_handler {
struct mutex lock; struct mutex _lock;
struct mutex *lock;
struct list_head ctrls; struct list_head ctrls;
struct list_head ctrl_refs; struct list_head ctrl_refs;
struct v4l2_ctrl_ref *cached; struct v4l2_ctrl_ref *cached;
...@@ -455,7 +458,7 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); ...@@ -455,7 +458,7 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
*/ */
static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
{ {
mutex_lock(&ctrl->handler->lock); mutex_lock(ctrl->handler->lock);
} }
/** v4l2_ctrl_lock() - Helper function to unlock the handler /** v4l2_ctrl_lock() - Helper function to unlock the handler
...@@ -464,7 +467,7 @@ static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) ...@@ -464,7 +467,7 @@ static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
*/ */
static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl) static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
{ {
mutex_unlock(&ctrl->handler->lock); mutex_unlock(ctrl->handler->lock);
} }
/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. /** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.
......
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