switch (mbus_cfg->type) {
        case V4L2_MBUS_PARALLEL:
                csicfg->ext_vsync = 1;
-               csicfg->vsync_pol = (mbus_cfg->flags &
+               csicfg->vsync_pol = (mbus_cfg->bus.parallel.flags &
                                     V4L2_MBUS_VSYNC_ACTIVE_LOW) ? 1 : 0;
-               csicfg->hsync_pol = (mbus_cfg->flags &
+               csicfg->hsync_pol = (mbus_cfg->bus.parallel.flags &
                                     V4L2_MBUS_HSYNC_ACTIVE_LOW) ? 1 : 0;
-               csicfg->pixclk_pol = (mbus_cfg->flags &
+               csicfg->pixclk_pol = (mbus_cfg->bus.parallel.flags &
                                      V4L2_MBUS_PCLK_SAMPLE_FALLING) ? 1 : 0;
                csicfg->clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
                break;
 
 
        if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
                cfg->type = V4L2_MBUS_CSI2_DPHY;
-               cfg->flags = V4L2_MBUS_CSI2_1_LANE |
+               cfg->bus.mipi_csi2.num_data_lanes = 1;
+               cfg->bus.mipi_csi2.flags =
                                V4L2_MBUS_CSI2_CHANNEL_0 |
                                V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
        } else {
                 * The ADV7180 sensor supports BT.601/656 output modes.
                 * The BT.656 is default and not yet configurable by s/w.
                 */
-               cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
-                                V4L2_MBUS_DATA_ACTIVE_HIGH;
+               cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+                                         V4L2_MBUS_PCLK_SAMPLE_RISING |
+                                         V4L2_MBUS_DATA_ACTIVE_HIGH;
                cfg->type = V4L2_MBUS_BT656;
        }
 
 
                return -EINVAL;
 
        config->type = V4L2_MBUS_CSI2_DPHY;
-       switch (tx->active_lanes) {
-       case 1:
-               config->flags = V4L2_MBUS_CSI2_1_LANE;
-               break;
-
-       case 2:
-               config->flags = V4L2_MBUS_CSI2_2_LANE;
-               break;
-
-       case 3:
-               config->flags = V4L2_MBUS_CSI2_3_LANE;
-               break;
-
-       case 4:
-               config->flags = V4L2_MBUS_CSI2_4_LANE;
-               break;
-       }
+       config->bus.mipi_csi2.num_data_lanes = tx->active_lanes;
 
        return 0;
 }
 
                                     unsigned int pad,
                                     struct v4l2_mbus_config *cfg)
 {
-       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
-                    V4L2_MBUS_DATA_ACTIVE_HIGH;
        cfg->type = V4L2_MBUS_BT656;
+       cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+                                 V4L2_MBUS_PCLK_SAMPLE_RISING |
+                                 V4L2_MBUS_DATA_ACTIVE_HIGH;
 
        return 0;
 }
 
                                   struct v4l2_mbus_config *cfg)
 {
        /* MT9M001 has all capture_format parameters fixed */
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
        cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->bus.parallel.flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+                                 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+                                 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+                                 V4L2_MBUS_DATA_ACTIVE_HIGH |
+                                 V4L2_MBUS_MASTER;
 
        return 0;
 }
 
 {
        struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
 
-       cfg->flags = V4L2_MBUS_MASTER |
-               V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->type = V4L2_MBUS_PARALLEL;
 
-       cfg->flags |= mt9m111->pclk_sample ? V4L2_MBUS_PCLK_SAMPLE_RISING :
-               V4L2_MBUS_PCLK_SAMPLE_FALLING;
+       cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+                                 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+                                 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+                                 V4L2_MBUS_DATA_ACTIVE_HIGH;
 
-       cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->bus.parallel.flags |= mt9m111->pclk_sample ?
+                                  V4L2_MBUS_PCLK_SAMPLE_RISING :
+                                  V4L2_MBUS_PCLK_SAMPLE_FALLING;
 
        return 0;
 }
 
        if (ret)
                return ret;
 
-       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH
-                  | ((comj & COMJ_VSYNC_HIGH)  ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
-                                               : V4L2_MBUS_VSYNC_ACTIVE_LOW)
-                  | ((comf & COMF_HREF_LOW)    ? V4L2_MBUS_HSYNC_ACTIVE_LOW
-                                               : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
-                  | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
-                                               : V4L2_MBUS_PCLK_SAMPLE_FALLING);
        cfg->type = V4L2_MBUS_PARALLEL;
 
+       cfg->bus.parallel.flags = V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH
+               | ((comj & COMJ_VSYNC_HIGH)  ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
+                                            : V4L2_MBUS_VSYNC_ACTIVE_LOW)
+               | ((comf & COMF_HREF_LOW)    ? V4L2_MBUS_HSYNC_ACTIVE_LOW
+                                            : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+               | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
+                                            : V4L2_MBUS_PCLK_SAMPLE_FALLING);
        return 0;
 }
 
 
                                  unsigned int pad,
                                  struct v4l2_mbus_config *cfg)
 {
-       cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
-               V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
-               V4L2_MBUS_DATA_ACTIVE_HIGH;
        cfg->type = V4L2_MBUS_PARALLEL;
+       cfg->bus.parallel.flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
+                                 V4L2_MBUS_MASTER |
+                                 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+                                 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+                                 V4L2_MBUS_DATA_ACTIVE_HIGH;
 
        return 0;
 }
 
        cfg->type = V4L2_MBUS_CSI2_DPHY;
 
        /* Support for non-continuous CSI-2 clock is missing in the driver */
-       cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
-       switch (state->csi_lanes_in_use) {
-       case 1:
-               cfg->flags |= V4L2_MBUS_CSI2_1_LANE;
-               break;
-       case 2:
-               cfg->flags |= V4L2_MBUS_CSI2_2_LANE;
-               break;
-       case 3:
-               cfg->flags |= V4L2_MBUS_CSI2_3_LANE;
-               break;
-       case 4:
-               cfg->flags |= V4L2_MBUS_CSI2_4_LANE;
-               break;
-       default:
-               return -EINVAL;
-       }
+       cfg->bus.mipi_csi2.flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+       cfg->bus.mipi_csi2.num_data_lanes = state->csi_lanes_in_use;
 
        return 0;
 }
 
        struct tvp5150 *decoder = to_tvp5150(sd);
 
        cfg->type = decoder->mbus_type;
-       cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING
-                  | V4L2_MBUS_FIELD_EVEN_LOW | V4L2_MBUS_DATA_ACTIVE_HIGH;
+       cfg->bus.parallel.flags = V4L2_MBUS_MASTER
+                               | V4L2_MBUS_PCLK_SAMPLE_RISING
+                               | V4L2_MBUS_FIELD_EVEN_LOW
+                               | V4L2_MBUS_DATA_ACTIVE_HIGH;
 
        return 0;
 }
 
 
        dev_dbg(csi2dc->dev, "subdev sending on channel %d\n", csi2dc->vc);
 
-       csi2dc->clk_gated = mbus_config.flags &
+       csi2dc->clk_gated = mbus_config.bus.parallel.flags &
                                V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
 
        dev_dbg(csi2dc->dev, "mbus_config: %s clock\n",
 
         * PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering
         * roles should match.
         */
-       if (cfg.flags != mbus_config) {
+       if (cfg.bus.parallel.flags != mbus_config) {
                unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER |
                                                            V4L2_MBUS_SLAVE);
-               if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER |
-                                                  V4L2_MBUS_SLAVE))) {
+               unsigned int flags = cfg.bus.parallel.flags;
+
+               if (pxa_mbus_role != (flags & (V4L2_MBUS_MASTER |
+                                              V4L2_MBUS_SLAVE))) {
                        dev_err(pcdev_to_dev(pcdev),
                                "Unsupported mbus configuration: bus mastering\n");
                        return -EINVAL;
                }
 
-               if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
+               if (flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
                        dev_err(pcdev_to_dev(pcdev),
                                "Unsupported mbus configuration: DATA_ACTIVE_LOW\n");
                        return -EINVAL;
                }
        }
 
-       pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt);
+       pxa_camera_setup_cicr(pcdev, cfg.bus.parallel.flags, pixfmt);
 
        return 0;
 }
 
                                  unsigned int *lanes)
 {
        struct v4l2_mbus_config mbus_config = { 0 };
-       unsigned int num_lanes = UINT_MAX;
        int ret;
 
        *lanes = priv->lanes;
                return -EINVAL;
        }
 
-       if (mbus_config.flags & V4L2_MBUS_CSI2_1_LANE)
-               num_lanes = 1;
-       else if (mbus_config.flags & V4L2_MBUS_CSI2_2_LANE)
-               num_lanes = 2;
-       else if (mbus_config.flags & V4L2_MBUS_CSI2_3_LANE)
-               num_lanes = 3;
-       else if (mbus_config.flags & V4L2_MBUS_CSI2_4_LANE)
-               num_lanes = 4;
-
-       if (num_lanes > priv->lanes) {
+       if (mbus_config.bus.mipi_csi2.num_data_lanes > priv->lanes) {
                dev_err(priv->dev,
                        "Unsupported mbus config: too many data lanes %u\n",
-                       num_lanes);
+                       mbus_config.bus.mipi_csi2.num_data_lanes);
                return -EINVAL;
        }
 
-       *lanes = num_lanes;
+       *lanes = mbus_config.bus.mipi_csi2.num_data_lanes;
 
        return 0;
 }
 
 
        /* compose mbus_config from the upstream endpoint */
        mbus_cfg.type = priv->upstream_ep.bus_type;
-       mbus_cfg.flags = is_parallel_bus(&priv->upstream_ep) ?
-               priv->upstream_ep.bus.parallel.flags :
-               priv->upstream_ep.bus.mipi_csi2.flags;
+       if (is_parallel_bus(&priv->upstream_ep))
+               mbus_cfg.bus.parallel = priv->upstream_ep.bus.parallel;
+       else
+               mbus_cfg.bus.mipi_csi2 = priv->upstream_ep.bus.mipi_csi2;
 
        if_fmt = *infmt;
        crop = priv->crop;
 
 static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
 {
        struct v4l2_mbus_config mbus_config = { 0 };
-       unsigned int num_lanes = UINT_MAX;
        int ret;
 
        *lanes = csi2->data_lanes;
                return -EINVAL;
        }
 
-       switch (mbus_config.flags & V4L2_MBUS_CSI2_LANES) {
-       case V4L2_MBUS_CSI2_1_LANE:
-               num_lanes = 1;
-               break;
-       case V4L2_MBUS_CSI2_2_LANE:
-               num_lanes = 2;
-               break;
-       case V4L2_MBUS_CSI2_3_LANE:
-               num_lanes = 3;
-               break;
-       case V4L2_MBUS_CSI2_4_LANE:
-               num_lanes = 4;
-               break;
-       default:
-               num_lanes = csi2->data_lanes;
-               break;
-       }
-
-       if (num_lanes > csi2->data_lanes) {
+       if (mbus_config.bus.mipi_csi2.num_data_lanes > csi2->data_lanes) {
                dev_err(csi2->dev,
                        "Unsupported mbus config: too many data lanes %u\n",
-                       num_lanes);
+                       mbus_config.bus.mipi_csi2.num_data_lanes);
                return -EINVAL;
        }
 
-       *lanes = num_lanes;
+       *lanes = mbus_config.bus.mipi_csi2.num_data_lanes;
 
        return 0;
 }
 
 
 /**
  * struct v4l2_mbus_config - media bus configuration
- * @type:      in: interface type
- * @flags:     in / out: configuration flags, depending on @type
+ * @type: interface type
+ * @bus: bus configuration data structure
+ * @bus.parallel: embedded &struct v4l2_mbus_config_parallel.
+ *               Used if the bus is parallel or BT.656.
+ * @bus.mipi_csi1: embedded &struct v4l2_mbus_config_mipi_csi1.
+ *                Used if the bus is MIPI Alliance's Camera Serial
+ *                Interface version 1 (MIPI CSI1) or Standard
+ *                Mobile Imaging Architecture's Compact Camera Port 2
+ *                (SMIA CCP2).
+ * @bus.mipi_csi2: embedded &struct v4l2_mbus_config_mipi_csi2.
+ *                Used if the bus is MIPI Alliance's Camera Serial
+ *                Interface version 2 (MIPI CSI2).
  */
 struct v4l2_mbus_config {
        enum v4l2_mbus_type type;
-       unsigned int flags;
+       union {
+               struct v4l2_mbus_config_parallel parallel;
+               struct v4l2_mbus_config_mipi_csi1 mipi_csi1;
+               struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
+       } bus;
 };
 
 /**