diff mbox

[v8,0/7] i2c-atr and FPDLink

Message ID 20230120153417.1156207-1-tomi.valkeinen@ideasonboard.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomi Valkeinen Jan. 20, 2023, 3:34 p.m. UTC
Hi,

You can find v7 from:

https://lore.kernel.org/all/20230118124031.788940-1-tomi.valkeinen@ideasonboard.com/

Diff to v7 included below.

Main changes in v8:
- Added missing 'link-frequencies' to ti,ds90ub960.yaml
- Dropped ATR select/deselect ops
- Don't use devm_kzalloc() in i2c_atr_new()
- Fixed the reported error handling paths (mainly adding
  fwnode_handle_puts)
- Dropped all WARNs
- Plenty of cosmetic/style changes

I saw the suggestion to change the i2c_atr to be embedded in the main
driver's private data struct. That change has not been done in this
version.

 Tomi

Luca Ceresoli (1):
  i2c: add I2C Address Translator (ATR) support

Tomi Valkeinen (6):
  dt-bindings: media: add TI DS90UB913 FPD-Link III Serializer
  dt-bindings: media: add TI DS90UB953 FPD-Link III Serializer
  dt-bindings: media: add TI DS90UB960 FPD-Link III Deserializer
  media: i2c: add DS90UB960 driver
  media: i2c: add DS90UB913 driver
  media: i2c: add DS90UB953 driver

 .../bindings/media/i2c/ti,ds90ub913.yaml      |  133 +
 .../bindings/media/i2c/ti,ds90ub953.yaml      |  134 +
 .../bindings/media/i2c/ti,ds90ub960.yaml      |  431 ++
 Documentation/i2c/index.rst                   |    1 +
 Documentation/i2c/muxes/i2c-atr.rst           |   83 +
 MAINTAINERS                                   |   16 +
 drivers/i2c/Kconfig                           |    9 +
 drivers/i2c/Makefile                          |    1 +
 drivers/i2c/i2c-atr.c                         |  532 ++
 drivers/media/i2c/Kconfig                     |   47 +
 drivers/media/i2c/Makefile                    |    3 +
 drivers/media/i2c/ds90ub913.c                 |  851 ++++
 drivers/media/i2c/ds90ub953.c                 | 1572 ++++++
 drivers/media/i2c/ds90ub960.c                 | 4278 +++++++++++++++++
 include/linux/i2c-atr.h                       |  113 +
 include/media/i2c/ds90ub9xx.h                 |   16 +
 16 files changed, 8220 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,ds90ub913.yaml
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,ds90ub953.yaml
 create mode 100644 Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
 create mode 100644 Documentation/i2c/muxes/i2c-atr.rst
 create mode 100644 drivers/i2c/i2c-atr.c
 create mode 100644 drivers/media/i2c/ds90ub913.c
 create mode 100644 drivers/media/i2c/ds90ub953.c
 create mode 100644 drivers/media/i2c/ds90ub960.c
 create mode 100644 include/linux/i2c-atr.h
 create mode 100644 include/media/i2c/ds90ub9xx.h

Interdiff against v7:

base-commit: 76dcd734eca23168cb008912c0f69ff408905235
prerequisite-patch-id: 341bbdcbd14f0b6f38c88f1390f9437873a03430
prerequisite-patch-id: e5d34269150d94ecb7fd670ad31e14aaae78e099
prerequisite-patch-id: 24ff7b1c013fa9acd8b93c2506eae39eb2a1021c
prerequisite-patch-id: 15edf6091d7c2d340f25711961bb8459addc8d58
prerequisite-patch-id: 9beff6fd1d22dbfe565931de81b27739e45ced05
prerequisite-patch-id: 37bc00c7315371c9a906af0d718ecedd871a43e0
prerequisite-patch-id: 8218595c50635ab48a9c8cd8c580da9f431d539f
prerequisite-patch-id: 7f163276a04d212d009ee6e96fb545d5b781cc44
prerequisite-patch-id: 0db299d92565612520411ef624e097131feb2d97
prerequisite-patch-id: 6b521ad1868b9a507930dd6a2e0e2d19b5947456
prerequisite-patch-id: d32e1105a1285cceac8fd8e84649070174a6b23e
prerequisite-patch-id: 2927a4ef079c55e7807cda150d4b9eb29978136a
prerequisite-patch-id: 77546a2e202557910e9a3635534163cc80134ea4
prerequisite-patch-id: 462fabb2b21019636e1f7e793dafc51caf40400e
prerequisite-patch-id: 604c8c3f3e7fab7698eb73795bae573f88b808db
prerequisite-patch-id: 75a3d7b072e718fb2bd854743b9b2023d68a822b
prerequisite-patch-id: a9c64a3360938ac230261ffc3e0cbd8cb66550d3
prerequisite-patch-id: a5c57341047e53ecaeb28181319700dd3ace62aa
prerequisite-patch-id: e9b8da97c9fea3cd3268adf8387cb3df179649e5
prerequisite-patch-id: 2767b8af9e0742b52b81b2dbce3b5ce5203e3610

Comments

Tomi Valkeinen Jan. 20, 2023, 3:37 p.m. UTC | #1
On 20/01/2023 17:34, Tomi Valkeinen wrote:
> Hi,
> 
> You can find v7 from:
> 
> https://lore.kernel.org/all/20230118124031.788940-1-tomi.valkeinen@ideasonboard.com/
> 
> Diff to v7 included below.
> 
> Main changes in v8:
> - Added missing 'link-frequencies' to ti,ds90ub960.yaml
> - Dropped ATR select/deselect ops
> - Don't use devm_kzalloc() in i2c_atr_new()
> - Fixed the reported error handling paths (mainly adding
>    fwnode_handle_puts)
> - Dropped all WARNs
> - Plenty of cosmetic/style changes
> 
> I saw the suggestion to change the i2c_atr to be embedded in the main
> driver's private data struct. That change has not been done in this
> version.

Ah, and just now I realized I did not pick the documentation changes 
from Luca.

  Tomi
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
index 1ba22450cdba..bb921caa85a7 100644
--- a/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/ti,ds90ub960.yaml
@@ -190,9 +190,12 @@  properties:
               data-lanes:
                 minItems: 1
                 maxItems: 4
+              link-frequencies:
+                maxItems: 1
 
             required:
               - data-lanes
+              - link-frequencies
 
       port@5:
         $ref: /schemas/graph.yaml#/$defs/port-base
@@ -208,9 +211,12 @@  properties:
               data-lanes:
                 minItems: 1
                 maxItems: 4
+              link-frequencies:
+                maxItems: 1
 
             required:
               - data-lanes
+              - link-frequencies
 
     required:
       - port@0
@@ -273,12 +279,12 @@  examples:
             };
           };
 
-          /* Port 2, unused */
+          /* Port 2, unconnected */
           port@2 {
             reg = <2>;
           };
 
-          /* Port 3, unused */
+          /* Port 3, unconnected */
           port@3 {
             reg = <3>;
           };
@@ -293,7 +299,7 @@  examples:
             };
           };
 
-          /* Port 5, unused */
+          /* Port 5, unconnected */
           port@5 {
             reg = <5>;
           };
diff --git a/drivers/i2c/i2c-atr.c b/drivers/i2c/i2c-atr.c
index 1d43cf3824eb..c872647ae808 100644
--- a/drivers/i2c/i2c-atr.c
+++ b/drivers/i2c/i2c-atr.c
@@ -16,8 +16,8 @@ 
 #include <linux/mutex.h>
 #include <linux/slab.h>
 
-#define ATR_MAX_ADAPTERS 99	/* Just a sanity limit */
-#define ATR_MAX_SYMLINK_LEN 16	/* Longest name is 10 chars: "channel-99" */
+#define ATR_MAX_ADAPTERS 100	/* Just a sanity limit */
+#define ATR_MAX_SYMLINK_LEN 11	/* Longest name is 10 chars: "channel-99" */
 
 /**
  * struct i2c_atr_cli2alias_pair - Holds the alias assigned to a client.
@@ -179,18 +179,12 @@  static int i2c_atr_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 	struct i2c_adapter *parent = atr->parent;
 	int ret;
 
-	/* Switch to the right atr port */
-	if (atr->ops->select) {
-		ret = atr->ops->select(atr, chan->chan_id);
-		if (ret < 0)
-			goto out_deselect;
-	}
-
 	/* Translate addresses */
 	mutex_lock(&chan->orig_addrs_lock);
+
 	ret = i2c_atr_map_msgs(chan, msgs, num);
 	if (ret < 0)
-		goto out_unlock_deselect;
+		goto err_unlock;
 
 	/* Perform the transfer */
 	ret = i2c_transfer(parent, msgs, num);
@@ -198,13 +192,9 @@  static int i2c_atr_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 	/* Restore addresses */
 	i2c_atr_unmap_msgs(chan, msgs, num);
 
-out_unlock_deselect:
+err_unlock:
 	mutex_unlock(&chan->orig_addrs_lock);
 
-out_deselect:
-	if (atr->ops->deselect)
-		atr->ops->deselect(atr, chan->chan_id);
-
 	return ret;
 }
 
@@ -216,7 +206,6 @@  static int i2c_atr_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	struct i2c_atr *atr = chan->atr;
 	struct i2c_adapter *parent = atr->parent;
 	struct i2c_atr_cli2alias_pair *c2a;
-	int ret = 0;
 
 	c2a = i2c_atr_find_mapping_by_addr(&chan->alias_list, addr);
 	if (!c2a) {
@@ -224,15 +213,8 @@  static int i2c_atr_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 		return -ENXIO;
 	}
 
-	if (atr->ops->select)
-		ret = atr->ops->select(atr, chan->chan_id);
-	if (!ret)
-		ret = i2c_smbus_xfer(parent, c2a->alias, flags, read_write,
-				     command, size, data);
-	if (atr->ops->deselect)
-		atr->ops->deselect(atr, chan->chan_id);
-
-	return ret;
+	return i2c_smbus_xfer(parent, c2a->alias, flags, read_write, command,
+			      size, data);
 }
 
 static u32 i2c_atr_functionality(struct i2c_adapter *adap)
@@ -372,8 +354,7 @@  struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev,
 	if (!ops || !ops->attach_client || !ops->detach_client)
 		return ERR_PTR(-EINVAL);
 
-	atr = devm_kzalloc(dev, struct_size(atr, adapter, max_adapters),
-			   GFP_KERNEL);
+	atr = kzalloc(struct_size(atr, adapter, max_adapters), GFP_KERNEL);
 	if (!atr)
 		return ERR_PTR(-ENOMEM);
 
@@ -405,6 +386,7 @@  void i2c_atr_delete(struct i2c_atr *atr)
 {
 	bus_unregister_notifier(&i2c_bus_type, &atr->i2c_nb);
 	mutex_destroy(&atr->lock);
+	kfree(atr);
 }
 EXPORT_SYMBOL_NS_GPL(i2c_atr_delete, I2C_ATR);
 
@@ -502,15 +484,18 @@  EXPORT_SYMBOL_NS_GPL(i2c_atr_add_adapter, I2C_ATR);
 void i2c_atr_del_adapter(struct i2c_atr *atr, u32 chan_id)
 {
 	char symlink_name[ATR_MAX_SYMLINK_LEN];
-
-	struct i2c_adapter *adap = atr->adapter[chan_id];
-	struct i2c_atr_chan *chan = adap->algo_data;
-	struct fwnode_handle *fwnode = dev_fwnode(&adap->dev);
+	struct i2c_adapter *adap;
+	struct i2c_atr_chan *chan;
+	struct fwnode_handle *fwnode;
 	struct device *dev = atr->dev;
 
+	adap = atr->adapter[chan_id];
 	if (!adap)
 		return;
 
+	chan = adap->algo_data;
+	fwnode = dev_fwnode(&adap->dev);
+
 	dev_dbg(dev, "Removing ATR child bus %d\n", i2c_adapter_id(adap));
 
 	snprintf(symlink_name, sizeof(symlink_name), "channel-%u",
diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c
index befa78128a9a..60a07b5bace3 100644
--- a/drivers/media/i2c/ds90ub913.c
+++ b/drivers/media/i2c/ds90ub913.c
@@ -337,7 +337,7 @@  static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(&priv->client->dev,
 				"Failed to find stream from source frame desc\n");
 			ret = -EPIPE;
-			goto out;
+			goto out_unlock;
 		}
 
 		fd->entry[fd->num_entries].stream = route->source_stream;
@@ -349,7 +349,7 @@  static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		fd->num_entries++;
 	}
 
-out:
+out_unlock:
 	v4l2_subdev_unlock_state(state);
 
 	return ret;
@@ -626,7 +626,7 @@  static int ub913_parse_dt(struct ub913_data *priv)
 	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
 						    UB913_PAD_SINK, 0, 0);
 	if (!ep_fwnode) {
-		dev_err(dev, "No sink endpoint\n");
+		dev_err_probe(dev, -ENOENT, "No sink endpoint\n");
 		return -ENOENT;
 	}
 
@@ -636,7 +636,7 @@  static int ub913_parse_dt(struct ub913_data *priv)
 	fwnode_handle_put(ep_fwnode);
 
 	if (ret) {
-		dev_err(dev, "OF: failed to parse pclk-sample: %d\n", ret);
+		dev_err_probe(dev, ret, "failed to parse 'pclk-sample'\n");
 		return ret;
 	}
 
@@ -706,7 +706,7 @@  static int ub913_subdev_init(struct ub913_data *priv)
 
 	ret = v4l2_subdev_init_finalize(&priv->sd);
 	if (ret)
-		goto err_entity_cleanup;
+		goto err_fwnode_put;
 
 	ret = ub913_v4l2_notifier_register(priv);
 	if (ret) {
@@ -727,6 +727,8 @@  static int ub913_subdev_init(struct ub913_data *priv)
 	ub913_v4l2_nf_unregister(priv);
 err_subdev_cleanup:
 	v4l2_subdev_cleanup(&priv->sd);
+err_fwnode_put:
+	fwnode_handle_put(priv->sd.fwnode);
 err_entity_cleanup:
 	media_entity_cleanup(&priv->sd.entity);
 
@@ -738,6 +740,7 @@  static void ub913_subdev_uninit(struct ub913_data *priv)
 	v4l2_async_unregister_subdev(&priv->sd);
 	ub913_v4l2_nf_unregister(priv);
 	v4l2_subdev_cleanup(&priv->sd);
+	fwnode_handle_put(priv->sd.fwnode);
 	media_entity_cleanup(&priv->sd.entity);
 }
 
@@ -764,7 +767,7 @@  static int ub913_probe(struct i2c_client *client)
 
 	/*
 	 * ub913 can also work without ext clock, but that is not supported by
-	 * the driver yet
+	 * the driver yet.
 	 */
 	priv->clkin = devm_clk_get(dev, "clkin");
 	if (IS_ERR(priv->clkin))
diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c
index ec33e16da3d1..738652f2294b 100644
--- a/drivers/media/i2c/ds90ub953.c
+++ b/drivers/media/i2c/ds90ub953.c
@@ -18,7 +18,6 @@ 
 #include <linux/kernel.h>
 #include <linux/math64.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
 #include <linux/property.h>
 #include <linux/rational.h>
 #include <linux/regmap.h>
@@ -52,8 +51,8 @@ 
 #define UB953_REG_CLKOUT_CTRL0			0x06
 #define UB953_REG_CLKOUT_CTRL1			0x07
 
-#define UB953_REG_SCL_HIGH_TIME			0x0B
-#define UB953_REG_SCL_LOW_TIME			0x0C
+#define UB953_REG_SCL_HIGH_TIME			0x0b
+#define UB953_REG_SCL_LOW_TIME			0x0c
 
 #define UB953_REG_LOCAL_GPIO_DATA		0x0d
 #define UB953_REG_LOCAL_GPIO_DATA_GPIO_RMTEN(n)		BIT(4 + (n))
@@ -74,9 +73,9 @@ 
 #define UB953_REG_CRC_ERR_CNT2			0x56
 
 #define UB953_REG_CSI_ERR_CNT			0x5c
-#define UB953_REG_CSI_ERR_STATUS		0x5D
-#define UB953_REG_CSI_ERR_DLANE01		0x5E
-#define UB953_REG_CSI_ERR_DLANE23		0x5F
+#define UB953_REG_CSI_ERR_STATUS		0x5d
+#define UB953_REG_CSI_ERR_DLANE01		0x5e
+#define UB953_REG_CSI_ERR_DLANE23		0x5f
 #define UB953_REG_CSI_ERR_CLK_LANE		0x60
 #define UB953_REG_CSI_PKT_HDR_VC_ID		0x61
 #define UB953_REG_PKT_HDR_WC_LSB		0x62
@@ -104,12 +103,12 @@ 
 #define UB953_IND_PGEN_BAR_SIZE0		0x07
 #define UB953_IND_PGEN_ACT_LPF1			0x08
 #define UB953_IND_PGEN_ACT_LPF0			0x09
-#define UB953_IND_PGEN_TOT_LPF1			0x0A
-#define UB953_IND_PGEN_TOT_LPF0			0x0B
-#define UB953_IND_PGEN_LINE_PD1			0x0C
-#define UB953_IND_PGEN_LINE_PD0			0x0D
-#define UB953_IND_PGEN_VBP			0x0E
-#define UB953_IND_PGEN_VFP			0x0F
+#define UB953_IND_PGEN_TOT_LPF1			0x0a
+#define UB953_IND_PGEN_TOT_LPF0			0x0b
+#define UB953_IND_PGEN_LINE_PD1			0x0c
+#define UB953_IND_PGEN_LINE_PD0			0x0d
+#define UB953_IND_PGEN_VBP			0x0e
+#define UB953_IND_PGEN_VFP			0x0f
 #define UB953_IND_PGEN_COLOR(n)			(0x10 + (n)) /* n <= 15 */
 
 /* Note: Only sync mode supported for now */
@@ -160,7 +159,7 @@  struct ub953_data {
 
 	enum ub953_mode		mode;
 
-	struct ds90ub9xx_platform_data *plat_data;
+	const struct ds90ub9xx_platform_data	*plat_data;
 };
 
 static inline struct ub953_data *sd_to_ub953(struct v4l2_subdev *sd)
@@ -180,12 +179,15 @@  static int ub953_read(struct ub953_data *priv, u8 reg, u8 *val)
 	mutex_lock(&priv->reg_lock);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(&priv->client->dev, "Cannot read register 0x%02x: %d\n",
 			reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
 
+	*val = v;
+
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -207,7 +209,7 @@  static int ub953_write(struct ub953_data *priv, u8 reg, u8 val)
 	return ret;
 }
 
-static int _ub953_select_ind_reg_block(struct ub953_data *priv, u8 block)
+static int ub953_select_ind_reg_block(struct ub953_data *priv, u8 block)
 {
 	struct device *dev = &priv->client->dev;
 	int ret;
@@ -235,16 +237,16 @@  __maybe_unused static int ub953_read_ind(struct ub953_data *priv, u8 block,
 
 	mutex_lock(&priv->reg_lock);
 
-	ret = _ub953_select_ind_reg_block(priv, block);
+	ret = ub953_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_ADDR failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	ret = regmap_read(priv->regmap, UB953_REG_IND_ACC_DATA, &v);
@@ -252,12 +254,12 @@  __maybe_unused static int ub953_read_ind(struct ub953_data *priv, u8 block,
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_DATA failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	*val = v;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -269,16 +271,16 @@  static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
 
 	mutex_lock(&priv->reg_lock);
 
-	ret = _ub953_select_ind_reg_block(priv, block);
+	ret = ub953_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_ADDR failed when writing %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val);
@@ -288,7 +290,7 @@  static int ub953_write_ind(struct ub953_data *priv, u8 block, u8 reg, u8 val)
 			block, reg, ret);
 	}
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -300,27 +302,27 @@  static int ub953_write_ind16(struct ub953_data *priv, u8 block, u8 reg, u16 val)
 
 	mutex_lock(&priv->reg_lock);
 
-	ret = _ub953_select_ind_reg_block(priv, block);
+	ret = ub953_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val >> 8);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg + 1);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val & 0xff);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -503,7 +505,6 @@  static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 				struct v4l2_mbus_frame_desc *fd)
 {
 	struct ub953_data *priv = sd_to_ub953(sd);
-	const struct v4l2_subdev_krouting *routing;
 	struct v4l2_mbus_frame_desc source_fd;
 	struct v4l2_subdev_route *route;
 	struct v4l2_subdev_state *state;
@@ -523,9 +524,7 @@  static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 
 	state = v4l2_subdev_lock_and_get_active_state(sd);
 
-	routing = &state->routing;
-
-	for_each_active_route(routing, route) {
+	for_each_active_route(&state->routing, route) {
 		struct v4l2_mbus_frame_desc_entry *source_entry = NULL;
 		unsigned int i;
 
@@ -543,7 +542,7 @@  static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(&priv->client->dev,
 				"Failed to find stream from source frame desc\n");
 			ret = -EPIPE;
-			goto out;
+			goto out_unlock;
 		}
 
 		fd->entry[fd->num_entries].stream = route->source_stream;
@@ -558,7 +557,7 @@  static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		fd->num_entries++;
 	}
 
-out:
+out_unlock:
 	v4l2_subdev_unlock_state(state);
 
 	return ret;
@@ -1268,25 +1267,20 @@  static int ub953_parse_dt(struct ub953_data *priv)
 
 	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
 						    UB953_PAD_SINK, 0, 0);
-	if (!ep_fwnode) {
-		dev_err(dev, "OF: no endpoint\n");
-		return -ENOENT;
-	}
+	if (!ep_fwnode)
+		return dev_err_probe(dev, -ENOENT, "no endpoint found\n");
 
 	ret = fwnode_property_count_u32(ep_fwnode, "data-lanes");
 
 	fwnode_handle_put(ep_fwnode);
 
-	if (ret <= 0) {
-		dev_err(dev, "failed to parse property 'data-lanes': %d\n",
-			ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "failed to parse property 'data-lanes'\n");
 
-	if (ret != 1 && ret != 2 && ret != 4) {
-		dev_err(dev, "bad number of data-lanes: %d\n", ret);
-		return -EINVAL;
-	}
+	if (ret != 1 && ret != 2 && ret != 4)
+		return dev_err_probe(dev, -EINVAL,
+				     "bad number of data-lanes: %d\n", ret);
 
 	priv->num_data_lanes = ret;
 
@@ -1324,7 +1318,7 @@  static int ub953_hw_init(struct ub953_data *priv)
 		break;
 	default:
 		return dev_err_probe(dev, -EIO,
-				     "Illegal mode in mode register\n");
+				     "Invalid mode in mode register\n");
 	}
 
 	dev_dbg(dev, "mode from %s: %#x\n", mode_override ? "reg" : "strap",
@@ -1366,8 +1360,7 @@  static int ub953_subdev_init(struct ub953_data *priv)
 
 	v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub953_subdev_ops);
 
-	v4l2_ctrl_handler_init(&priv->ctrl_handler,
-			       ARRAY_SIZE(ub953_tpg_qmenu) - 1);
+	v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
 	priv->sd.ctrl_handler = &priv->ctrl_handler;
 
 	v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &ub953_ctrl_ops,
@@ -1375,9 +1368,11 @@  static int ub953_subdev_init(struct ub953_data *priv)
 				     ARRAY_SIZE(ub953_tpg_qmenu) - 1, 0, 0,
 				     ub953_tpg_qmenu);
 
-	if (priv->ctrl_handler.error)
-		return dev_err_probe(dev, priv->ctrl_handler.error,
-				     "Failed to set up v4l2 controls\n");
+	if (priv->ctrl_handler.error) {
+		ret = priv->ctrl_handler.error;
+		dev_err_probe(dev, ret, "Failed to set up v4l2 controls\n");
+		goto err_remove_ctrls;
+	}
 
 	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
 			  V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_STREAMS;
@@ -1406,7 +1401,7 @@  static int ub953_subdev_init(struct ub953_data *priv)
 
 	ret = v4l2_subdev_init_finalize(&priv->sd);
 	if (ret)
-		goto err_entity_cleanup;
+		goto err_fwnode_put;
 
 	ret = ub953_v4l2_notifier_register(priv);
 	if (ret) {
@@ -1427,6 +1422,8 @@  static int ub953_subdev_init(struct ub953_data *priv)
 	ub953_v4l2_notifier_unregister(priv);
 err_free_state:
 	v4l2_subdev_cleanup(&priv->sd);
+err_fwnode_put:
+	fwnode_handle_put(priv->sd.fwnode);
 err_entity_cleanup:
 	media_entity_cleanup(&priv->sd.entity);
 err_remove_ctrls:
@@ -1440,6 +1437,7 @@  static void ub953_subdev_uninit(struct ub953_data *priv)
 	v4l2_async_unregister_subdev(&priv->sd);
 	ub953_v4l2_notifier_unregister(priv);
 	v4l2_subdev_cleanup(&priv->sd);
+	fwnode_handle_put(priv->sd.fwnode);
 	media_entity_cleanup(&priv->sd.entity);
 	v4l2_ctrl_handler_free(&priv->ctrl_handler);
 }
@@ -1456,9 +1454,7 @@  static int ub953_probe(struct i2c_client *client)
 
 	priv->client = client;
 
-	priv->hw_data = of_device_get_match_data(dev);
-	if (!priv->hw_data)
-		return -ENODEV;
+	priv->hw_data = device_get_match_data(dev);
 
 	priv->plat_data = dev_get_platdata(&client->dev);
 	if (!priv->plat_data)
@@ -1544,8 +1540,8 @@  static const struct ub953_hw_data ds90ub971_hw = {
 };
 
 static const struct i2c_device_id ub953_id[] = {
-	{ "ds90ub953-q1", 0 },
-	{ "ds90ub971-q1", 0 },
+	{ "ds90ub953-q1", (kernel_ulong_t)&ds90ub953_hw },
+	{ "ds90ub971-q1", (kernel_ulong_t)&ds90ub971_hw },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, ub953_id);
diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
index 2cefb3744901..eb391f0259b3 100644
--- a/drivers/media/i2c/ds90ub960.c
+++ b/drivers/media/i2c/ds90ub960.c
@@ -19,7 +19,6 @@ 
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/of_device.h>
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
@@ -31,6 +30,8 @@ 
 #include <media/v4l2-event.h>
 #include <media/v4l2-subdev.h>
 
+#define MHZ(v) ((u32)((v) * 1000000U))
+
 #define UB960_POLL_TIME_MS	500
 
 #define UB960_MAX_RX_NPORTS	4
@@ -147,7 +148,13 @@ 
 #define UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT	0
 
 #define UB960_XR_AEQ_CTL1			0x42
-#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_SHIFT	4
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_FPD_CLK	BIT(6)
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_ENCODING	BIT(5)
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_PARITY	BIT(4)
+#define UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK        \
+	(UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_FPD_CLK |  \
+	 UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_ENCODING | \
+	 UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_PARITY)
 #define UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN	BIT(0)
 
 #define UB960_XR_AEQ_ERR_THOLD			0x43
@@ -160,9 +167,14 @@ 
 #define UB960_RR_BCC_STATUS_SLAVE_ERR		BIT(2)
 #define UB960_RR_BCC_STATUS_SLAVE_TO		BIT(1)
 #define UB960_RR_BCC_STATUS_RESP_ERR		BIT(0)
+#define UB960_RR_BCC_STATUS_ERROR_MASK                                    \
+	(UB960_RR_BCC_STATUS_SEQ_ERROR | UB960_RR_BCC_STATUS_MASTER_ERR | \
+	 UB960_RR_BCC_STATUS_MASTER_TO | UB960_RR_BCC_STATUS_SLAVE_ERR |  \
+	 UB960_RR_BCC_STATUS_SLAVE_TO | UB960_RR_BCC_STATUS_RESP_ERR)
 
 #define UB960_RR_FPD3_CAP			0x4A
 #define UB960_RR_RAW_EMBED_DTYPE		0x4B
+#define UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT	6
 
 #define UB960_SR_FPD3_PORT_SEL			0x4C
 
@@ -173,6 +185,10 @@ 
 #define UB960_RR_RX_PORT_STS1_PARITY_ERROR	BIT(2)
 #define UB960_RR_RX_PORT_STS1_PORT_PASS		BIT(1)
 #define UB960_RR_RX_PORT_STS1_LOCK_STS		BIT(0)
+#define UB960_RR_RX_PORT_STS1_ERROR_MASK       \
+	(UB960_RR_RX_PORT_STS1_BCC_CRC_ERROR | \
+	 UB960_RR_RX_PORT_STS1_BCC_SEQ_ERROR | \
+	 UB960_RR_RX_PORT_STS1_PARITY_ERROR)
 
 #define UB960_RR_RX_PORT_STS2			0x4E
 #define UB960_RR_RX_PORT_STS2_LINE_LEN_UNSTABLE	BIT(7)
@@ -183,6 +199,8 @@ 
 #define UB960_RR_RX_PORT_STS2_FREQ_STABLE	BIT(2)
 #define UB960_RR_RX_PORT_STS2_CABLE_FAULT	BIT(1)
 #define UB960_RR_RX_PORT_STS2_LINE_CNT_CHG	BIT(0)
+#define UB960_RR_RX_PORT_STS2_ERROR_MASK       \
+	UB960_RR_RX_PORT_STS2_BUFFER_ERROR
 
 #define UB960_RR_RX_FREQ_HIGH			0x4F
 #define UB960_RR_RX_FREQ_LOW			0x50
@@ -196,6 +214,7 @@ 
 
 #define UB960_RR_BCC_CONFIG			0x58
 #define UB960_RR_BCC_CONFIG_I2C_PASS_THROUGH	BIT(6)
+#define UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK	GENMASK(2, 0)
 
 #define UB960_RR_DATAPATH_CTL1			0x59
 #define UB960_RR_DATAPATH_CTL2			0x5A
@@ -207,10 +226,17 @@ 
 #define UB960_RR_SLAVE_ALIAS(n)			(0x65 + (n))
 
 #define UB960_RR_PORT_CONFIG			0x6D
+#define UB960_RR_PORT_CONFIG_FPD3_MODE_MASK	GENMASK(1, 0)
+
 #define UB960_RR_BC_GPIO_CTL(n)			(0x6E + (n)) /* n < 2 */
 #define UB960_RR_RAW10_ID			0x70
+#define UB960_RR_RAW10_ID_VC_SHIFT		6
+#define UB960_RR_RAW10_ID_DT_SHIFT		0
+
 #define UB960_RR_RAW12_ID			0x71
 #define UB960_RR_CSI_VC_MAP			0x72
+#define UB960_RR_CSI_VC_MAP_SHIFT(x)		((x) * 2)
+
 #define UB960_RR_LINE_COUNT_HI			0x73
 #define UB960_RR_LINE_COUNT_LO			0x74
 #define UB960_RR_LINE_LEN_1			0x75
@@ -224,9 +250,15 @@ 
 #define UB960_RR_CSI_RX_STS_CKSUM_ERR		BIT(2)
 #define UB960_RR_CSI_RX_STS_ECC2_ERR		BIT(1)
 #define UB960_RR_CSI_RX_STS_ECC1_ERR		BIT(0)
+#define UB960_RR_CSI_RX_STS_ERROR_MASK                                    \
+	(UB960_RR_CSI_RX_STS_LENGTH_ERR | UB960_RR_CSI_RX_STS_CKSUM_ERR | \
+	 UB960_RR_CSI_RX_STS_ECC2_ERR | UB960_RR_CSI_RX_STS_ECC1_ERR)
 
 #define UB960_RR_CSI_ERR_COUNTER		0x7B
 #define UB960_RR_PORT_CONFIG2			0x7C
+#define UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_MASK GENMASK(7, 6)
+#define UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT 6
+
 #define UB960_RR_PORT_CONFIG2_LV_POL_LOW	BIT(1)
 #define UB960_RR_PORT_CONFIG2_FV_POL_LOW	BIT(0)
 
@@ -267,6 +299,8 @@ 
 #define UB960_RR_AEQ_CTL2_SET_AEQ_FLOOR		BIT(2)
 
 #define UB960_RR_AEQ_STATUS			0xD3
+#define UB960_RR_AEQ_STATUS_STATUS_2		GENMASK(5, 3)
+#define UB960_RR_AEQ_STATUS_STATUS_1		GENMASK(2, 0)
 
 #define UB960_RR_AEQ_BYPASS			0xD4
 #define UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_SHIFT	5
@@ -336,8 +370,10 @@ 
 #define UB960_MIN_AEQ_STROBE_POS -7
 #define UB960_MAX_AEQ_STROBE_POS 7
 
-#define UB960_MIN_MANUAL_STROBE_POS -(7 + 6)
-#define UB960_MAX_MANUAL_STROBE_POS (7 + 6)
+#define UB960_MANUAL_STROBE_EXTRA_DELAY 6
+
+#define UB960_MIN_MANUAL_STROBE_POS -(7 + UB960_MANUAL_STROBE_EXTRA_DELAY)
+#define UB960_MAX_MANUAL_STROBE_POS (7 + UB960_MANUAL_STROBE_EXTRA_DELAY)
 #define UB960_NUM_MANUAL_STROBE_POS (UB960_MAX_MANUAL_STROBE_POS - UB960_MIN_MANUAL_STROBE_POS + 1)
 
 #define UB960_MIN_EQ_LEVEL 0
@@ -584,12 +620,15 @@  static int ub960_read(struct ub960_data *priv, u8 reg, u8 *val)
 	mutex_lock(&priv->reg_lock);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s: cannot read register 0x%02x (%d)!\n",
 			__func__, reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
+
+	*val = v;
 
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -639,7 +678,7 @@  static int _ub960_rxport_select(struct ub960_data *priv, u8 nport)
 		return 0;
 
 	ret = regmap_write(priv->regmap, UB960_SR_FPD3_PORT_SEL,
-			   (nport << 4) | (1 << nport));
+			   (nport << 4) | BIT(nport));
 	if (ret) {
 		dev_err(dev, "%s: cannot select rxport %d (%d)!\n", __func__,
 			nport, ret);
@@ -663,12 +702,15 @@  static int ub960_rxport_read(struct ub960_data *priv, u8 nport, u8 reg, u8 *val)
 	_ub960_rxport_select(priv, nport);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s: cannot read register 0x%02x (%d)!\n",
 			__func__, reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
+
+	*val = v;
 
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -704,7 +746,6 @@  static int ub960_rxport_update_bits(struct ub960_data *priv, u8 nport, u8 reg,
 	_ub960_rxport_select(priv, nport);
 
 	ret = regmap_update_bits(priv->regmap, reg, mask, val);
-
 	if (ret)
 		dev_err(dev, "%s: cannot update register 0x%02x (%d)!\n",
 			__func__, reg, ret);
@@ -724,7 +765,7 @@  static int _ub960_csiport_select(struct ub960_data *priv, u8 nport)
 		return 0;
 
 	ret = regmap_write(priv->regmap, UB960_SR_CSI_PORT_SEL,
-			   (nport << 4) | (1 << nport));
+			   (nport << 4) | BIT(nport));
 	if (ret) {
 		dev_err(dev, "%s: cannot select csi port %d (%d)!\n", __func__,
 			nport, ret);
@@ -749,12 +790,15 @@  static int ub960_csiport_read(struct ub960_data *priv, u8 nport, u8 reg,
 	_ub960_csiport_select(priv, nport);
 
 	ret = regmap_read(priv->regmap, reg, &v);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s: cannot read register 0x%02x (%d)!\n",
 			__func__, reg, ret);
-	else
-		*val = v;
+		goto out_unlock;
+	}
+
+	*val = v;
 
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -791,7 +835,6 @@  static int ub960_csiport_update_bits(struct ub960_data *priv, u8 nport, u8 reg,
 	_ub960_csiport_select(priv, nport);
 
 	ret = regmap_update_bits(priv->regmap, reg, mask, val);
-
 	if (ret)
 		dev_err(dev, "%s: cannot update register 0x%02x (%d)!\n",
 			__func__, reg, ret);
@@ -830,14 +873,14 @@  static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val)
 
 	ret = _ub960_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_ADDR failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	ret = regmap_read(priv->regmap, UB960_SR_IND_ACC_DATA, &v);
@@ -845,12 +888,12 @@  static int ub960_read_ind(struct ub960_data *priv, u8 block, u8 reg, u8 *val)
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_DATA failed when reading %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
 	*val = v;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -863,24 +906,26 @@  static int ub960_write_ind(struct ub960_data *priv, u8 block, u8 reg, u8 val)
 	mutex_lock(&priv->reg_lock);
 
 	ret = _ub960_select_ind_reg_block(priv, block);
+	if (ret)
+		goto out_unlock;
+
+	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_ADDR failed when writing %u:%x02x: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
-	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
+	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val);
 	if (ret) {
 		dev_err(&priv->client->dev,
 			"Write to IND_ACC_DATA failed when writing %u:%x02x\n: %d\n",
 			block, reg, ret);
-		goto out;
+		goto out_unlock;
 	}
 
-	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val);
-
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -894,25 +939,25 @@  static int ub960_write_ind16(struct ub960_data *priv, u8 block, u8 reg, u16 val)
 
 	ret = _ub960_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val >> 8);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg + 1);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, val & 0xff);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -922,28 +967,31 @@  static int ub960_ind_update_bits(struct ub960_data *priv, u8 block, u8 reg,
 				 u8 mask, u8 val)
 {
 	int ret;
-	u32 v;
 
 	mutex_lock(&priv->reg_lock);
 
 	ret = _ub960_select_ind_reg_block(priv, block);
 	if (ret)
-		goto out;
+		goto out_unlock;
 
 	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_ADDR, reg);
-	if (ret)
-		goto out;
-
-	ret = regmap_read(priv->regmap, UB960_SR_IND_ACC_DATA, &v);
-	if (ret)
-		goto out;
-
-	v &= ~mask;
-	v |= val;
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Write to IND_ACC_ADDR failed when updating %u:%x02x: %d\n",
+			block, reg, ret);
+		goto out_unlock;
+	}
 
-	ret = regmap_write(priv->regmap, UB960_SR_IND_ACC_DATA, v);
+	ret = regmap_update_bits(priv->regmap, UB960_SR_IND_ACC_DATA, mask,
+				 val);
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Write to IND_ACC_DATA failed when updating %u:%x02x: %d\n",
+			block, reg, ret);
+		goto out_unlock;
+	}
 
-out:
+out_unlock:
 	mutex_unlock(&priv->reg_lock);
 
 	return ret;
@@ -992,13 +1040,13 @@  static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id,
 	if (!entry) {
 		dev_err(dev, "rx%u: alias pool exhausted\n", rxport->nport);
 		ret = -EADDRNOTAVAIL;
-		goto out;
+		goto out_unlock;
 	}
 
-	if (port_reg_idx_mask == (1 << UB960_MAX_PORT_ALIASES) - 1) {
+	if (port_reg_idx_mask == GENMASK(UB960_MAX_PORT_ALIASES - 1, 0)) {
 		dev_err(dev, "rx%u: all aliases in use\n", rxport->nport);
 		ret = -EADDRNOTAVAIL;
-		goto out;
+		goto out_unlock;
 	}
 
 	alias = entry->alias_id;
@@ -1022,7 +1070,7 @@  static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id,
 	dev_dbg(dev, "rx%u: client 0x%02x mapped at alias 0x%02x (%s)\n",
 		rxport->nport, client->addr, alias, client->name);
 
-out:
+out_unlock:
 	mutex_unlock(&priv->atr_alias_table.lock);
 	return ret;
 }
@@ -1055,7 +1103,7 @@  static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id,
 	if (pool_idx == priv->atr_alias_table.num_entries) {
 		dev_err(dev, "rx%u: client 0x%02x is not mapped!\n",
 			rxport->nport, client->addr);
-		goto out;
+		goto out_unlock;
 	}
 
 	alias = entry->alias_id;
@@ -1071,7 +1119,7 @@  static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id,
 	dev_dbg(dev, "rx%u: client 0x%02x unmapped from alias 0x%02x (%s)\n",
 		rxport->nport, client->addr, alias, client->name);
 
-out:
+out_unlock:
 	mutex_unlock(&priv->atr_alias_table.lock);
 }
 
@@ -1103,7 +1151,7 @@  static int ub960_parse_dt_txport(struct ub960_data *priv,
 	priv->txports[nport] = txport;
 
 	ret = fwnode_property_count_u32(ep_fwnode, "data-lanes");
-	if (ret <= 0) {
+	if (ret < 0) {
 		dev_err(dev, "tx%u: failed to parse 'data-lanes': %d\n", nport,
 			ret);
 		goto err_free_txport;
@@ -1111,20 +1159,6 @@  static int ub960_parse_dt_txport(struct ub960_data *priv,
 
 	txport->num_data_lanes = ret;
 
-	ret = fwnode_property_count_u64(ep_fwnode, "link-frequencies");
-	if (ret < 0) {
-		dev_err(dev, "tx%u: failed to parse 'link-frequencies': %d\n",
-			nport, ret);
-		goto err_free_txport;
-	}
-
-	if (ret != 1) {
-		dev_err(dev,
-			"tx%u: 'link-frequencies' must contain a single frequency: %d\n",
-			nport, ret);
-		goto err_free_txport;
-	}
-
 	ret = fwnode_property_read_u64(ep_fwnode, "link-frequencies", &freq);
 	if (ret) {
 		dev_err(dev, "tx%u: failed to read 'link-frequencies': %d\n",
@@ -1135,10 +1169,10 @@  static int ub960_parse_dt_txport(struct ub960_data *priv,
 	priv->tx_link_freq[0] = freq;
 	priv->tx_data_rate = freq * 2;
 
-	if (priv->tx_data_rate != 1600000000 &&
-	    priv->tx_data_rate != 1200000000 &&
-	    priv->tx_data_rate != 800000000 &&
-	    priv->tx_data_rate != 400000000) {
+	if (priv->tx_data_rate != MHZ(1600) &&
+	    priv->tx_data_rate != MHZ(1200) &&
+	    priv->tx_data_rate != MHZ(800) &&
+	    priv->tx_data_rate != MHZ(400)) {
 		dev_err(dev, "tx%u: invalid 'link-frequencies' value\n", nport);
 		return -EINVAL;
 	}
@@ -1160,14 +1194,14 @@  static void ub960_csi_handle_events(struct ub960_data *priv, u8 nport)
 	int ret;
 
 	ret = ub960_csiport_read(priv, nport, UB960_TR_CSI_TX_ISR, &csi_tx_isr);
+	if (ret)
+		return;
 
-	if (!ret) {
-		if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_SYNC_ERROR)
-			dev_warn(dev, "TX%u: CSI_SYNC_ERROR\n", nport);
+	if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_SYNC_ERROR)
+		dev_warn(dev, "TX%u: CSI_SYNC_ERROR\n", nport);
 
-		if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_PASS_ERROR)
-			dev_warn(dev, "TX%u: CSI_PASS_ERROR\n", nport);
-	}
+	if (csi_tx_isr & UB960_TR_CSI_TX_ISR_IS_CSI_PASS_ERROR)
+		dev_warn(dev, "TX%u: CSI_PASS_ERROR\n", nport);
 }
 
 /* -----------------------------------------------------------------------------
@@ -1193,8 +1227,8 @@  static int ub960_rxport_enable_vpocs(struct ub960_data *priv)
 	return 0;
 
 err_disable_vpocs:
-	for (; nport > 0; --nport) {
-		struct ub960_rxport *rxport = priv->rxports[nport - 1];
+	while (nport--) {
+		struct ub960_rxport *rxport = priv->rxports[nport];
 
 		if (!rxport || !rxport->vpoc)
 			continue;
@@ -1253,12 +1287,16 @@  static int ub960_rxport_get_strobe_pos(struct ub960_data *priv,
 	ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport),
 		       UB960_IR_RX_ANA_STROBE_SET_CLK, &v);
 
-	clk_delay = v & UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY ? 0 : 6;
+	clk_delay = (v & UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY) ?
+			    0 :
+			    UB960_MANUAL_STROBE_EXTRA_DELAY;
 
 	ub960_read_ind(priv, UB960_IND_TARGET_RX_ANA(nport),
 		       UB960_IR_RX_ANA_STROBE_SET_DATA, &v);
 
-	data_delay = v & UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY ? 0 : 6;
+	data_delay = (v & UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY) ?
+			     0 :
+			     UB960_MANUAL_STROBE_EXTRA_DELAY;
 
 	ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_0, &v);
 	if (ret)
@@ -1282,17 +1320,13 @@  static void ub960_rxport_set_strobe_pos(struct ub960_data *priv,
 {
 	u8 clk_delay, data_delay;
 
-	if (WARN_ON(strobe_pos < UB960_MIN_MANUAL_STROBE_POS ||
-		    strobe_pos > UB960_MAX_MANUAL_STROBE_POS))
-		return;
-
 	clk_delay = UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY;
 	data_delay = UB960_IR_RX_ANA_STROBE_SET_DATA_NO_EXTRA_DELAY;
 
-	if (strobe_pos < -7)
-		clk_delay = abs(strobe_pos) - 6;
-	else if (strobe_pos > 7)
-		data_delay = strobe_pos - 6;
+	if (strobe_pos < UB960_MIN_AEQ_STROBE_POS)
+		clk_delay = abs(strobe_pos) - UB960_MANUAL_STROBE_EXTRA_DELAY;
+	else if (strobe_pos > UB960_MAX_AEQ_STROBE_POS)
+		data_delay = strobe_pos - UB960_MANUAL_STROBE_EXTRA_DELAY;
 	else if (strobe_pos < 0)
 		clk_delay = abs(strobe_pos) | UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY;
 	else if (strobe_pos > 0)
@@ -1308,11 +1342,9 @@  static void ub960_rxport_set_strobe_pos(struct ub960_data *priv,
 static void ub960_rxport_set_strobe_range(struct ub960_data *priv,
 					  s8 strobe_min, s8 strobe_max)
 {
-	WARN_ON(strobe_min < UB960_MIN_AEQ_STROBE_POS);
-	WARN_ON(strobe_max > UB960_MAX_AEQ_STROBE_POS);
-
-	strobe_min += 7;
-	strobe_max += 7;
+	/* Convert the signed strobe pos to positive zero based value */
+	strobe_min -= UB960_MIN_AEQ_STROBE_POS;
+	strobe_max -= UB960_MIN_AEQ_STROBE_POS;
 
 	ub960_write(priv, UB960_XR_SFILTER_CFG,
 		    ((u8)strobe_min << UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) |
@@ -1329,7 +1361,8 @@  static int ub960_rxport_get_eq_level(struct ub960_data *priv,
 	if (ret)
 		return ret;
 
-	*eq_level = (v & 0x7) + ((v >> 3) & 0x7);
+	*eq_level = (v & UB960_RR_AEQ_STATUS_STATUS_1) +
+		    (v & UB960_RR_AEQ_STATUS_STATUS_2);
 
 	return 0;
 }
@@ -1338,26 +1371,24 @@  static void ub960_rxport_set_eq_level(struct ub960_data *priv,
 				      unsigned int nport, u8 eq_level)
 {
 	u8 eq_stage_1_select_value, eq_stage_2_select_value;
+	const unsigned int eq_stage_max = 7;
 	u8 v;
 
-	if (eq_level <= 7) {
+	if (eq_level <= eq_stage_max) {
 		eq_stage_1_select_value = eq_level;
 		eq_stage_2_select_value = 0;
 	} else {
-		eq_stage_1_select_value = 7;
-		eq_stage_2_select_value = eq_level - 7;
+		eq_stage_1_select_value = eq_stage_max;
+		eq_stage_2_select_value = eq_level - eq_stage_max;
 	}
 
-	WARN_ON(eq_stage_1_select_value > 7);
-	WARN_ON(eq_stage_2_select_value > 7);
-
 	ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v);
 
 	v &= ~(UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_MASK |
 	       UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_MASK);
 	v |= eq_stage_1_select_value << UB960_RR_AEQ_BYPASS_EQ_STAGE1_VALUE_SHIFT;
 	v |= eq_stage_2_select_value << UB960_RR_AEQ_BYPASS_EQ_STAGE2_VALUE_SHIFT;
-	v |= UB960_RR_AEQ_BYPASS_ENABLE; /* Enable AEQ Bypass */
+	v |= UB960_RR_AEQ_BYPASS_ENABLE;
 
 	ub960_rxport_write(priv, nport, UB960_RR_AEQ_BYPASS, v);
 }
@@ -1388,7 +1419,7 @@  static void ub960_rxport_config_eq(struct ub960_data *priv, unsigned int nport)
 	} else {
 		/* Enable SFILTER and error control */
 		ub960_write(priv, UB960_XR_AEQ_CTL1,
-			    (0x7 << UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_SHIFT) |
+			    UB960_XR_AEQ_CTL1_AEQ_ERR_CTL_MASK |
 				    UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN);
 
 		/* Set AEQ strobe range */
@@ -1472,8 +1503,10 @@  static int ub960_rxport_link_ok(struct ub960_data *priv, unsigned int nport,
 
 	parity_errors = (v1 << 8) | v2;
 
-	errors = (rx_port_sts1 & 0x2c) || (rx_port_sts2 & 0x20) ||
-		 (bcc_sts & 0x3f) || (csi_rx_sts & 0xf) || csi_err_cnt ||
+	errors = (rx_port_sts1 & UB960_RR_RX_PORT_STS1_ERROR_MASK) ||
+		 (rx_port_sts2 & UB960_RR_RX_PORT_STS2_ERROR_MASK) ||
+		 (bcc_sts & UB960_RR_BCC_STATUS_ERROR_MASK) ||
+		 (csi_rx_sts & UB960_RR_CSI_RX_STS_ERROR_MASK) || csi_err_cnt ||
 		 parity_errors;
 
 	*ok = !errors;
@@ -1621,7 +1654,6 @@  static unsigned long ub960_calc_bc_clk_rate_ub960(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return 0;
 	}
 
@@ -1644,7 +1676,6 @@  static unsigned long ub960_calc_bc_clk_rate_ub9702(struct ub960_data *priv,
 		return 9437500;
 
 	default:
-		WARN_ON(true);
 		return 0;
 	}
 }
@@ -1716,17 +1747,17 @@  static int ub960_rxport_add_serializers(struct ub960_data *priv)
 	return 0;
 
 err_remove_sers:
-	for (; nport > 0; --nport) {
-		struct ub960_rxport *rxport = priv->rxports[nport - 1];
+	while (nport--) {
+		struct ub960_rxport *rxport = priv->rxports[nport];
 
 		if (!rxport)
 			continue;
 
-		rxport = priv->rxports[nport - 1];
+		rxport = priv->rxports[nport];
 		if (!rxport)
 			continue;
 
-		ub960_rxport_remove_serializer(priv, nport - 1);
+		ub960_rxport_remove_serializer(priv, nport);
 	}
 
 	return ret;
@@ -1756,7 +1787,7 @@  static void ub960_init_tx_port(struct ub960_data *priv,
 	 * From the datasheet: "initial CSI Skew-Calibration
 	 * sequence [...] should be set when operating at 1.6 Gbps"
 	 */
-	if (priv->tx_data_rate == 1600000000)
+	if (priv->tx_data_rate == MHZ(1600))
 		csi_ctl |= UB960_TR_CSI_CTL_CSI_CAL_EN;
 
 	csi_ctl |= (4 - txport->num_data_lanes) << 4;
@@ -1773,19 +1804,19 @@  static int ub960_init_tx_ports(struct ub960_data *priv)
 	/* TX ports */
 
 	switch (priv->tx_data_rate) {
-	case 1600000000:
+	case MHZ(1600):
 	default:
 		speed_select = 0;
 		pll_div = 0x10;
 		break;
-	case 1200000000:
+	case MHZ(1200):
 		speed_select = 1;
 		break;
-	case 800000000:
+	case MHZ(800):
 		speed_select = 2;
 		pll_div = 0x10;
 		break;
-	case 400000000:
+	case MHZ(400):
 		speed_select = 3;
 		pll_div = 0x10;
 		break;
@@ -1797,17 +1828,17 @@  static int ub960_init_tx_ports(struct ub960_data *priv)
 		ub960_write(priv, UB960_SR_CSI_PLL_DIV, pll_div);
 
 		switch (priv->tx_data_rate) {
-		case 1600000000:
+		case MHZ(1600):
 		default:
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0x80);
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4B, 0x2A);
 			break;
-		case 800000000:
+		case MHZ(800):
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0x90);
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4F, 0x2A);
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x4B, 0x2A);
 			break;
-		case 400000000:
+		case MHZ(400):
 			ub960_write_ind(priv, UB960_IND_TARGET_CSI_ANA, 0x92, 0xA0);
 			break;
 		}
@@ -1858,32 +1889,34 @@  static void ub960_init_rx_port_ub960(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return;
 	}
 
-	ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG, 0x7,
+	ub960_rxport_update_bits(priv, nport, UB960_RR_BCC_CONFIG,
+				 UB960_RR_BCC_CONFIG_BC_FREQ_SEL_MASK,
 				 bc_freq_val);
 
 	switch (rxport->rx_mode) {
-	default:
-		WARN_ON(true);
-		fallthrough;
-
 	case RXPORT_MODE_RAW10:
 		/* FPD3_MODE = RAW10 Mode (DS90UB913A-Q1 / DS90UB933-Q1 compatible) */
-		ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG, 0x3,
+		ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG,
+					 UB960_RR_PORT_CONFIG_FPD3_MODE_MASK,
 					 0x3);
 
 		/*
-		 * RAW10_8BIT_CTL = 0b11 : 8-bit processing using lower 8 bits
-		 * 0b10 : 8-bit processing using upper 8 bits
+		 * RAW10_8BIT_CTL = 0b10 : 8-bit processing using upper 8 bits
 		 */
 		ub960_rxport_update_bits(priv, nport, UB960_RR_PORT_CONFIG2,
-					 0x3 << 6, 0x2 << 6);
+			UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_MASK,
+			0x2 << UB960_RR_PORT_CONFIG2_RAW10_8BIT_CTL_SHIFT);
 
 		break;
 
+	case RXPORT_MODE_RAW12_HF:
+	case RXPORT_MODE_RAW12_LF:
+		/* Not implemented */
+		return;
+
 	case RXPORT_MODE_CSI2_SYNC:
 	case RXPORT_MODE_CSI2_ASYNC:
 		/* CSI-2 Mode (DS90UB953-Q1 compatible) */
@@ -1951,7 +1984,6 @@  static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return;
 	}
 
@@ -1980,7 +2012,7 @@  static void ub960_init_rx_port_ub9702_fpd3(struct ub960_data *priv,
 
 	/* RX port to half-rate */
 	ub960_update_bits(priv, UB960_SR_FPD_RATE_CFG, 0x3 << (nport * 2),
-			  1 << (nport * 2));
+			  BIT(nport * 2));
 }
 
 static void ub960_init_rx_port_ub9702_fpd4_aeq(struct ub960_data *priv,
@@ -2045,7 +2077,6 @@  static void ub960_init_rx_port_ub9702_fpd4(struct ub960_data *priv,
 		break;
 
 	default:
-		WARN_ON(true);
 		return;
 	}
 
@@ -2091,10 +2122,6 @@  static void ub960_init_rx_port_ub9702(struct ub960_data *priv,
 		ub960_init_rx_port_ub9702_fpd4(priv, rxport);
 
 	switch (rxport->rx_mode) {
-	default:
-		WARN_ON(true);
-		fallthrough;
-
 	case RXPORT_MODE_RAW10:
 		/*
 		 * RAW10_8BIT_CTL = 0b11 : 8-bit processing using lower 8 bits
@@ -2105,6 +2132,11 @@  static void ub960_init_rx_port_ub9702(struct ub960_data *priv,
 
 		break;
 
+	case RXPORT_MODE_RAW12_HF:
+	case RXPORT_MODE_RAW12_LF:
+		/* Not implemented */
+		return;
+
 	case RXPORT_MODE_CSI2_SYNC:
 	case RXPORT_MODE_CSI2_ASYNC:
 
@@ -2283,7 +2315,7 @@  static void ub960_get_vc_maps(struct ub960_data *priv,
 			      struct v4l2_subdev_state *state, u8 *vc)
 {
 	const struct v4l2_subdev_krouting *routing = &state->routing;
-	u8 cur_vc[UB960_MAX_TX_NPORTS] = { 0 };
+	u8 cur_vc[UB960_MAX_TX_NPORTS] = { };
 	u8 handled_mask = 0;
 	unsigned int i;
 
@@ -2292,7 +2324,6 @@  static void ub960_get_vc_maps(struct ub960_data *priv,
 		unsigned int rx, tx;
 
 		rx = ub960_pad_to_port(priv, route->sink_pad);
-
 		if (BIT(rx) & handled_mask)
 			continue;
 
@@ -2360,8 +2391,8 @@  static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 		u8 meta_dt;
 		u32 meta_lines;
 		u32 tx_port;
-	} rx_data[UB960_MAX_RX_NPORTS] = { 0 };
-	u8 vc_map[UB960_MAX_RX_NPORTS] = { 0 };
+	} rx_data[UB960_MAX_RX_NPORTS] = { };
+	u8 vc_map[UB960_MAX_RX_NPORTS] = { };
 
 	ub960_get_vc_maps(priv, state, vc_map);
 
@@ -2432,19 +2463,20 @@  static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 			continue;
 
 		switch (rxport->rx_mode) {
-		default:
-			WARN_ON(true);
-			fallthrough;
-
 		case RXPORT_MODE_RAW10:
 			ub960_rxport_write(priv, nport, UB960_RR_RAW10_ID,
-					   rx_data[nport].pixel_dt | (vc << 6));
+				rx_data[nport].pixel_dt | (vc << UB960_RR_RAW10_ID_VC_SHIFT));
 
 			ub960_rxport_write(priv, rxport->nport,
-					   UB960_RR_RAW_EMBED_DTYPE,
-					   (rx_data[nport].meta_lines << 6) |
-						   rx_data[nport].meta_dt);
+				UB960_RR_RAW_EMBED_DTYPE,
+				(rx_data[nport].meta_lines << UB960_RR_RAW_EMBED_DTYPE_LINES_SHIFT) |
+					rx_data[nport].meta_dt);
+
+			break;
 
+		case RXPORT_MODE_RAW12_HF:
+		case RXPORT_MODE_RAW12_LF:
+			/* Not implemented */
 			break;
 
 		case RXPORT_MODE_CSI2_SYNC:
@@ -2452,8 +2484,10 @@  static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 			if (!priv->hw_data->is_ub9702) {
 				/* Map all VCs from this port to the same VC */
 				ub960_rxport_write(priv, nport, UB960_RR_CSI_VC_MAP,
-						   (vc << 6) | (vc << 4) |
-							   (vc << 2) | (vc << 0));
+						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(3)) |
+						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(2)) |
+						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(1)) |
+						   (vc << UB960_RR_CSI_VC_MAP_SHIFT(0)));
 			} else {
 				unsigned int i;
 
@@ -2485,16 +2519,13 @@  static int ub960_configure_ports_for_streaming(struct ub960_data *priv,
 static void ub960_update_streaming_status(struct ub960_data *priv)
 {
 	unsigned int i;
-	bool streaming = false;
 
 	for (i = 0; i < UB960_MAX_NPORTS; ++i) {
-		if (priv->stream_enable_mask[i]) {
-			streaming = true;
+		if (priv->stream_enable_mask[i])
 			break;
-		}
 	}
 
-	priv->streaming = streaming;
+	priv->streaming = i < UB960_MAX_NPORTS;
 }
 
 static int ub960_enable_streams(struct v4l2_subdev *sd,
@@ -2506,7 +2537,7 @@  static int ub960_enable_streams(struct v4l2_subdev *sd,
 	const struct v4l2_subdev_krouting *routing;
 	unsigned int source_stream;
 	int ret;
-	u64 sink_streams[UB960_MAX_RX_NPORTS] = { 0 };
+	u64 sink_streams[UB960_MAX_RX_NPORTS] = { };
 	unsigned int nport;
 	unsigned int failed_port;
 
@@ -2607,7 +2638,8 @@  static int ub960_enable_streams(struct v4l2_subdev *sd,
 			priv->rxports[nport]->source_sd,
 			priv->rxports[nport]->source_sd_pad,
 			sink_streams[nport]);
-		WARN_ON(ret);
+		if (ret)
+			dev_err(dev, "Failed to disable streams: %d\n", ret);
 
 		priv->stream_enable_mask[nport] &= ~sink_streams[nport];
 
@@ -2636,7 +2668,7 @@  static int ub960_disable_streams(struct v4l2_subdev *sd,
 	const struct v4l2_subdev_krouting *routing;
 	int ret;
 	unsigned int source_stream;
-	u64 sink_streams[UB960_MAX_RX_NPORTS] = { 0 };
+	u64 sink_streams[UB960_MAX_RX_NPORTS] = { };
 	unsigned int nport;
 
 	dev_dbg(dev, "Disable streams %u:%#llx\n", source_pad,
@@ -2681,7 +2713,8 @@  static int ub960_disable_streams(struct v4l2_subdev *sd,
 			priv->rxports[nport]->source_sd,
 			priv->rxports[nport]->source_sd_pad,
 			sink_streams[nport]);
-		WARN_ON(ret);
+		if (ret)
+			dev_err(dev, "Failed to disable streams: %d\n", ret);
 
 		priv->stream_enable_mask[nport] &= ~sink_streams[nport];
 
@@ -2709,7 +2742,7 @@  static int ub960_s_stream(struct v4l2_subdev *sd, int enable)
 	const struct v4l2_subdev_krouting *routing;
 	struct v4l2_subdev_state *state;
 	struct v4l2_subdev_route *route;
-	u64 pad_stream_masks[UB960_MAX_TX_NPORTS] = { 0 };
+	u64 pad_stream_masks[UB960_MAX_TX_NPORTS] = { };
 	unsigned int nport;
 	int ret = 0;
 
@@ -2731,15 +2764,15 @@  static int ub960_s_stream(struct v4l2_subdev *sd, int enable)
 				pad_stream_masks[nport]);
 
 			if (ret) {
-				for (; nport > 0; --nport) {
-					if (pad_stream_masks[nport - 1] == 0)
+				while (nport--) {
+					if (pad_stream_masks[nport] == 0)
 						continue;
 
 					ub960_disable_streams(
 						sd, state,
 						priv->hw_data->num_rxports +
-							nport - 1,
-						pad_stream_masks[nport - 1]);
+							nport,
+						pad_stream_masks[nport]);
 				}
 
 				break;
@@ -2827,7 +2860,7 @@  static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 	struct v4l2_subdev_state *state;
 	int ret = 0;
 	struct device *dev = &priv->client->dev;
-	u8 vc_map[UB960_MAX_RX_NPORTS] = { 0 };
+	u8 vc_map[UB960_MAX_RX_NPORTS] = { };
 
 	if (!ub960_pad_is_source(priv, pad))
 		return -EINVAL;
@@ -2861,7 +2894,7 @@  static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(dev,
 				"Failed to get source frame desc for pad %u\n",
 				route->sink_pad);
-			goto out;
+			goto out_unlock;
 		}
 
 		for (i = 0; i < source_fd.num_entries; ++i)
@@ -2874,7 +2907,7 @@  static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 			dev_err(dev,
 				"Failed to find stream from source frame desc\n");
 			ret = -EPIPE;
-			goto out;
+			goto out_unlock;
 		}
 
 		fd->entry[fd->num_entries].stream = route->source_stream;
@@ -2896,14 +2929,14 @@  static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 
 			if (!fmt) {
 				ret = -EINVAL;
-				goto out;
+				goto out_unlock;
 			}
 
 			ub960_fmt = ub960_find_format(fmt->code);
 			if (!ub960_fmt) {
 				dev_err(dev, "Unable to find format\n");
 				ret = -EINVAL;
-				goto out;
+				goto out_unlock;
 			}
 
 			fd->entry[fd->num_entries].bus.csi2.dt =
@@ -2913,7 +2946,7 @@  static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
 		fd->num_entries++;
 	}
 
-out:
+out_unlock:
 	v4l2_subdev_unlock_state(state);
 
 	return ret;
@@ -2995,7 +3028,7 @@  static int ub960_log_status(struct v4l2_subdev *sd)
 	struct v4l2_subdev_state *state;
 	unsigned int nport;
 	u8 v = 0, v1 = 0, v2 = 0;
-	char id[7];
+	u8 id[7];
 
 	state = v4l2_subdev_lock_and_get_active_state(sd);
 
@@ -3275,31 +3308,30 @@  static irqreturn_t ub960_handle_events(int irq, void *arg)
 	struct ub960_data *priv = arg;
 	unsigned int i;
 	u8 int_sts;
+	u8 fwd_sts;
 	int ret;
 
 	ret = ub960_read(priv, UB960_SR_INTERRUPT_STS, &int_sts);
+	if (ret || !int_sts)
+		return IRQ_NONE;
 
-	if (!ret && int_sts) {
-		u8 fwd_sts;
+	dev_dbg(&priv->client->dev, "INTERRUPT_STS %x\n", int_sts);
 
-		dev_dbg(&priv->client->dev, "INTERRUPT_STS %x\n", int_sts);
+	ub960_read(priv, UB960_SR_FWD_STS, &fwd_sts);
 
-		ub960_read(priv, UB960_SR_FWD_STS, &fwd_sts);
+	dev_dbg(&priv->client->dev, "FWD_STS %#02x\n", fwd_sts);
 
-		dev_dbg(&priv->client->dev, "FWD_STS %#02x\n", fwd_sts);
-
-		for (i = 0; i < priv->hw_data->num_txports; ++i) {
-			if (int_sts & UB960_SR_INTERRUPT_STS_IS_CSI_TX(i))
-				ub960_csi_handle_events(priv, i);
-		}
+	for (i = 0; i < priv->hw_data->num_txports; ++i) {
+		if (int_sts & UB960_SR_INTERRUPT_STS_IS_CSI_TX(i))
+			ub960_csi_handle_events(priv, i);
+	}
 
-		for (i = 0; i < priv->hw_data->num_rxports; i++) {
-			if (!priv->rxports[i])
-				continue;
+	for (i = 0; i < priv->hw_data->num_rxports; ++i) {
+		if (!priv->rxports[i])
+			continue;
 
-			if (int_sts & UB960_SR_INTERRUPT_STS_IS_RX(i))
-				ub960_rxport_handle_events(priv, i);
-		}
+		if (int_sts & UB960_SR_INTERRUPT_STS_IS_RX(i))
+			ub960_rxport_handle_events(priv, i);
 	}
 
 	return IRQ_HANDLED;
@@ -3469,7 +3501,7 @@  ub960_parse_dt_rxport_link_properties(struct ub960_data *priv,
 		dev_err(dev, "rx%u: illegal 'strobe-pos' value: %d\n", nport,
 			strobe_pos);
 	} else {
-		// NOTE: ignored unless global manual strobe pos is set
+		/* NOTE: ignored unless global manual strobe pos is set */
 		rxport->eq.strobe_pos = strobe_pos;
 		if (!priv->strobe.manual)
 			dev_warn(dev,
@@ -3620,12 +3652,14 @@  ub960_fwnode_get_link_by_regs(struct fwnode_handle *links_fwnode,
 	fwnode_for_each_child_node(links_fwnode, link_fwnode) {
 		u32 link_num;
 
-		if (strncmp(fwnode_get_name(link_fwnode), "link@", 5) != 0)
+		if (!str_has_prefix(fwnode_get_name(link_fwnode), "link@"))
 			continue;
 
 		ret = fwnode_property_read_u32(link_fwnode, "reg", &link_num);
-		if (ret)
+		if (ret) {
+			fwnode_handle_put(link_fwnode);
 			return NULL;
+		}
 
 		if (nport == link_num) {
 			fwnode_handle_put(link_fwnode);
@@ -3823,8 +3857,8 @@  static int ub960_v4l2_notifier_register(struct ub960_data *priv)
 					       rxport->source_ep_fwnode,
 					       struct ub960_asd);
 		if (IS_ERR(asd)) {
-			dev_err(dev, "Failed to add subdev for source %u: %ld",
-				i, PTR_ERR(asd));
+			dev_err(dev, "Failed to add subdev for source %u: %pe",
+				i, asd);
 			v4l2_async_nf_cleanup(&priv->notifier);
 			return PTR_ERR(asd);
 		}
@@ -3857,8 +3891,7 @@  static int ub960_create_subdev(struct ub960_data *priv)
 	int ret;
 
 	v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub960_subdev_ops);
-	v4l2_ctrl_handler_init(&priv->ctrl_handler,
-			       ARRAY_SIZE(ub960_tpg_qmenu) - 1);
+	v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
 	priv->sd.ctrl_handler = &priv->ctrl_handler;
 
 	v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &ub960_ctrl_ops,
@@ -4011,14 +4044,13 @@  static int ub960_enable_core_hw(struct ub960_data *priv)
 	u8 refclk_freq;
 
 	ret = regulator_enable(priv->vddio);
-	if (ret) {
-		dev_err(dev, "failed to enable VDDIO regulator\n");
-		return ret;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to enable VDDIO regulator\n");
 
 	ret = clk_prepare_enable(priv->refclk);
 	if (ret) {
-		dev_err(dev, "Failed to enable refclk: %d\n", ret);
+		dev_err_probe(dev, ret, "Failed to enable refclk\n");
 		goto err_disable_vddio;
 	}
 
@@ -4036,7 +4068,7 @@  static int ub960_enable_core_hw(struct ub960_data *priv)
 	/* Runtime check register accessibility */
 	ret = ub960_read(priv, UB960_SR_REV_MASK, &rev_mask);
 	if (ret) {
-		dev_err(dev, "Cannot read first register (%d), abort\n", ret);
+		dev_err_probe(dev, ret, "Cannot read first register, abort\n");
 		goto err_pd_gpio;
 	}
 
@@ -4061,9 +4093,7 @@  static int ub960_enable_core_hw(struct ub960_data *priv)
 	return 0;
 
 err_pd_gpio:
-	if (priv->pd_gpio)
-		gpiod_set_value_cansleep(priv->pd_gpio, 1);
-
+	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 	clk_disable_unprepare(priv->refclk);
 err_disable_vddio:
 	regulator_disable(priv->vddio);
@@ -4073,11 +4103,8 @@  static int ub960_enable_core_hw(struct ub960_data *priv)
 
 static void ub960_disable_core_hw(struct ub960_data *priv)
 {
-	if (priv->pd_gpio)
-		gpiod_set_value_cansleep(priv->pd_gpio, 1);
-
+	gpiod_set_value_cansleep(priv->pd_gpio, 1);
 	clk_disable_unprepare(priv->refclk);
-
 	regulator_disable(priv->vddio);
 }
 
@@ -4093,9 +4120,7 @@  static int ub960_probe(struct i2c_client *client)
 
 	priv->client = client;
 
-	priv->hw_data = of_device_get_match_data(dev);
-	if (!priv->hw_data)
-		return -ENODEV;
+	priv->hw_data = device_get_match_data(dev);
 
 	mutex_init(&priv->reg_lock);
 	mutex_init(&priv->atr_alias_table.lock);
@@ -4144,7 +4169,7 @@  static int ub960_probe(struct i2c_client *client)
 
 	ub960_reset(priv, false);
 
-	ub960_rxport_wait_locks(priv, 0xf, NULL);
+	ub960_rxport_wait_locks(priv, GENMASK(3, 0), NULL);
 
 	/*
 	 * Clear any errors caused by switching the RX port settings while
@@ -4222,8 +4247,8 @@  static const struct ub960_hw_data ds90ub9702_hw = {
 };
 
 static const struct i2c_device_id ub960_id[] = {
-	{ "ds90ub960-q1", 0 },
-	{ "ds90ub9702-q1", 0 },
+	{ "ds90ub960-q1", (kernel_ulong_t)&ds90ub960_hw },
+	{ "ds90ub9702-q1", (kernel_ulong_t)&ds90ub9702_hw },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, ub960_id);
@@ -4241,7 +4266,6 @@  static struct i2c_driver ds90ub960_driver = {
 	.id_table	= ub960_id,
 	.driver = {
 		.name	= "ds90ub960",
-		.owner = THIS_MODULE,
 		.of_match_table = ub960_dt_ids,
 	},
 };
diff --git a/include/linux/i2c-atr.h b/include/linux/i2c-atr.h
index 10a313ab2105..721d08a6ff9b 100644
--- a/include/linux/i2c-atr.h
+++ b/include/linux/i2c-atr.h
@@ -20,8 +20,6 @@  struct i2c_atr;
 
 /**
  * struct i2c_atr_ops - Callbacks from ATR to the device driver.
- * @select:        Ask the driver to select a child bus (optional)
- * @deselect:      Ask the driver to deselect a child bus (optional)
  * @attach_client: Notify the driver of a new device connected on a child
  *                 bus. The driver must choose an I2C alias, configure the
  *                 hardware to use it and return it in `alias_id`.
@@ -32,8 +30,6 @@  struct i2c_atr;
  * All these functions return 0 on success, a negative error code otherwise.
  */
 struct i2c_atr_ops {
-	int (*select)(struct i2c_atr *atr, u32 chan_id);
-	int (*deselect)(struct i2c_atr *atr, u32 chan_id);
 	int (*attach_client)(struct i2c_atr *atr, u32 chan_id,
 			     const struct i2c_client *client, u16 *alias_id);
 	void (*detach_client)(struct i2c_atr *atr, u32 chan_id,