/*
  * Add a control mapping to a given control.
  */
-static int __uvc_ctrl_add_mapping(struct uvc_device *dev,
+static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
        struct uvc_control *ctrl, const struct uvc_control_mapping *mapping)
 {
        struct uvc_control_mapping *map;
                map->set = uvc_set_le_value;
 
        list_add_tail(&map->list, &ctrl->info.mappings);
-       uvc_dbg(dev, CONTROL, "Adding mapping '%s' to control %pUl/%u\n",
+       uvc_dbg(chain->dev, CONTROL, "Adding mapping '%s' to control %pUl/%u\n",
                map->name, ctrl->info.entity, ctrl->info.selector);
 
        return 0;
                goto done;
        }
 
-       ret = __uvc_ctrl_add_mapping(dev, ctrl, mapping);
+       ret = __uvc_ctrl_add_mapping(chain, ctrl, mapping);
        if (ret < 0)
                atomic_dec(&dev->nmappings);
 
  * Add control information and hardcoded stock control mappings to the given
  * device.
  */
-static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl)
+static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
+                              struct uvc_control *ctrl)
 {
        const struct uvc_control_info *info = uvc_ctrls;
        const struct uvc_control_info *iend = info + ARRAY_SIZE(uvc_ctrls);
        for (; info < iend; ++info) {
                if (uvc_entity_match_guid(ctrl->entity, info->entity) &&
                    ctrl->index == info->index) {
-                       uvc_ctrl_add_info(dev, ctrl, info);
+                       uvc_ctrl_add_info(chain->dev, ctrl, info);
                        /*
                         * Retrieve control flags from the device. Ignore errors
                         * and work with default flag values from the uvc_ctrl
                         * array when the device doesn't properly implement
                         * GET_INFO on standard controls.
                         */
-                       uvc_ctrl_get_flags(dev, ctrl, &ctrl->info);
+                       uvc_ctrl_get_flags(chain->dev, ctrl, &ctrl->info);
                        break;
                 }
        }
        for (; mapping < mend; ++mapping) {
                if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
                    ctrl->info.selector == mapping->selector)
-                       __uvc_ctrl_add_mapping(dev, ctrl, mapping);
+                       __uvc_ctrl_add_mapping(chain, ctrl, mapping);
        }
 }
 
 /*
  * Initialize device controls.
  */
-int uvc_ctrl_init_device(struct uvc_device *dev)
+static int uvc_ctrl_init_chain(struct uvc_video_chain *chain)
 {
        struct uvc_entity *entity;
        unsigned int i;
 
-       INIT_WORK(&dev->async_ctrl.work, uvc_ctrl_status_event_work);
-
        /* Walk the entities list and instantiate controls */
-       list_for_each_entry(entity, &dev->entities, list) {
+       list_for_each_entry(entity, &chain->entities, chain) {
                struct uvc_control *ctrl;
                unsigned int bControlSize = 0, ncontrols;
                u8 *bmControls = NULL;
                }
 
                /* Remove bogus/blacklisted controls */
-               uvc_ctrl_prune_entity(dev, entity);
+               uvc_ctrl_prune_entity(chain->dev, entity);
 
                /* Count supported controls and allocate the controls array */
                ncontrols = memweight(bmControls, bControlSize);
                        ctrl->entity = entity;
                        ctrl->index = i;
 
-                       uvc_ctrl_init_ctrl(dev, ctrl);
+                       uvc_ctrl_init_ctrl(chain, ctrl);
                        ctrl++;
                }
        }
        return 0;
 }
 
+int uvc_ctrl_init_device(struct uvc_device *dev)
+{
+       struct uvc_video_chain *chain;
+       int ret;
+
+       INIT_WORK(&dev->async_ctrl.work, uvc_ctrl_status_event_work);
+
+       list_for_each_entry(chain, &dev->chains, list) {
+               ret = uvc_ctrl_init_chain(chain);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 /*
  * Cleanup device controls.
  */