From: Ken Sloat <ksl...@aampglobal.com>

In some usages isc->raw_fmt will not be initialized. If this
is the case, it is very possible that a NULL struct de-reference
will occur, as this member is referenced many times.

To prevent this, add safety checks for this member and handle
situations accordingly.

Signed-off-by: Ken Sloat <ksl...@aampglobal.com>
---
 drivers/media/platform/atmel/atmel-isc.c | 64 ++++++++++++++++--------
 1 file changed, 44 insertions(+), 20 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc.c 
b/drivers/media/platform/atmel/atmel-isc.c
index 50178968b8a6..4cccaa4f2ce9 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -902,6 +902,15 @@ static inline bool sensor_is_preferred(const struct 
isc_format *isc_fmt)
                !isc_fmt->isc_support;
 }
 
+static inline u32 get_preferred_mbus_code(const struct isc_device *isc,
+               const struct isc_format *isc_fmt)
+{
+       if (sensor_is_preferred(isc_fmt) || !isc->raw_fmt)
+               return isc_fmt->mbus_code;
+       else
+               return isc->raw_fmt->mbus_code;
+}
+
 static struct fmt_config *get_fmt_config(u32 fourcc)
 {
        struct fmt_config *config;
@@ -955,7 +964,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 
pipeline)
 {
        struct regmap *regmap = isc->regmap;
        struct isc_ctrls *ctrls = &isc->ctrls;
-       struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
+       struct fmt_config *config;
        u32 val, bay_cfg;
        const u32 *gamma;
        unsigned int i;
@@ -969,7 +978,12 @@ static void isc_set_pipeline(struct isc_device *isc, u32 
pipeline)
        if (!pipeline)
                return;
 
-       bay_cfg = config->cfa_baycfg;
+       if (isc->raw_fmt) {
+               config = get_fmt_config(isc->raw_fmt->fourcc);
+               bay_cfg = config->cfa_baycfg;
+       } else {
+               bay_cfg = 0;
+       }
 
        regmap_write(regmap, ISC_WB_CFG, bay_cfg);
        regmap_write(regmap, ISC_WB_O_RGR, 0x0);
@@ -1022,12 +1036,20 @@ static void isc_set_histogram(struct isc_device *isc)
 {
        struct regmap *regmap = isc->regmap;
        struct isc_ctrls *ctrls = &isc->ctrls;
-       struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
+       struct fmt_config *config;
+       u32     cfa_baycfg;
+
+       if (isc->raw_fmt) {
+               config = get_fmt_config(isc->raw_fmt->fourcc);
+               cfa_baycfg = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
+       } else {
+               cfa_baycfg = 0;
+       }
 
        if (ctrls->awb && (ctrls->hist_stat != HIST_ENABLED)) {
                regmap_write(regmap, ISC_HIS_CFG,
                             ISC_HIS_CFG_MODE_R |
-                            (config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT) |
+                                cfa_baycfg |
                             ISC_HIS_CFG_RAR);
                regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN);
                regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE);
@@ -1075,7 +1097,7 @@ static int isc_configure(struct isc_device *isc)
        struct regmap *regmap = isc->regmap;
        const struct isc_format *current_fmt = isc->current_fmt;
        struct fmt_config *curfmt_config = get_fmt_config(current_fmt->fourcc);
-       struct fmt_config *rawfmt_config = get_fmt_config(isc->raw_fmt->fourcc);
+       struct fmt_config *rawfmt_config;
        struct isc_subdev_entity *subdev = isc->current_subdev;
        u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline;
 
@@ -1085,7 +1107,12 @@ static int isc_configure(struct isc_device *isc)
                isc_get_param(current_fmt, &rlp_mode, &dcfg);
                isc->ctrls.hist_stat = HIST_INIT;
        } else {
-               pfe_cfg0 = rawfmt_config->pfe_cfg0_bps;
+               if (isc->raw_fmt) {
+                       rawfmt_config = get_fmt_config(isc->raw_fmt->fourcc);
+                       pfe_cfg0 = rawfmt_config->pfe_cfg0_bps;
+               } else {
+                       pfe_cfg0 = curfmt_config->pfe_cfg0_bps;
+               }
                pipeline = curfmt_config->bits_pipeline;
                rlp_mode = curfmt_config->rlp_cfg_mode;
                dcfg = curfmt_config->dcfg_imode |
@@ -1315,10 +1342,7 @@ static int isc_try_fmt(struct isc_device *isc, struct 
v4l2_format *f,
        if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT)
                pixfmt->height = ISC_MAX_SUPPORT_HEIGHT;
 
-       if (sensor_is_preferred(isc_fmt))
-               mbus_code = isc_fmt->mbus_code;
-       else
-               mbus_code = isc->raw_fmt->mbus_code;
+       mbus_code = get_preferred_mbus_code(isc, isc_fmt);
 
        v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
        ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
@@ -1442,10 +1466,7 @@ static int isc_enum_framesizes(struct file *file, void 
*fh,
        if (!isc_fmt)
                return -EINVAL;
 
-       if (sensor_is_preferred(isc_fmt))
-               fse.code = isc_fmt->mbus_code;
-       else
-               fse.code = isc->raw_fmt->mbus_code;
+       fse.code = get_preferred_mbus_code(isc, isc_fmt);
 
        ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
                               NULL, &fse);
@@ -1476,10 +1497,7 @@ static int isc_enum_frameintervals(struct file *file, 
void *fh,
        if (!isc_fmt)
                return -EINVAL;
 
-       if (sensor_is_preferred(isc_fmt))
-               fie.code = isc_fmt->mbus_code;
-       else
-               fie.code = isc->raw_fmt->mbus_code;
+       fie.code = get_preferred_mbus_code(isc, isc_fmt);
 
        ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
                               enum_frame_interval, NULL, &fie);
@@ -1668,7 +1686,7 @@ static void isc_awb_work(struct work_struct *w)
        struct isc_device *isc =
                container_of(w, struct isc_device, awb_work);
        struct regmap *regmap = isc->regmap;
-       struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc);
+       struct fmt_config *config;
        struct isc_ctrls *ctrls = &isc->ctrls;
        u32 hist_id = ctrls->hist_id;
        u32 baysel;
@@ -1686,7 +1704,13 @@ static void isc_awb_work(struct work_struct *w)
        }
 
        ctrls->hist_id = hist_id;
-       baysel = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
+
+       if (isc->raw_fmt) {
+               config = get_fmt_config(isc->raw_fmt->fourcc);
+               baysel = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
+       } else {
+               baysel = 0;
+       }
 
        pm_runtime_get_sync(isc->dev);
 
-- 
2.17.1

Reply via email to