Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipu6: Fix compilation with kernels >= 6.6.0 #175

Merged
merged 2 commits into from
Nov 15, 2023

Conversation

jwrdegoede
Copy link
Contributor

Kernel 6.6 has made some significant changes to how v4l2-async (sub)dev registration works. Adjust the code accordingly.

Note this is based on building against a recent verison of the media_staging/master git tree. Since 6.6 has not been released yet there is a small chance that there might be some more work needed, but this should at least make things work with 6.6-rc1 once released.

@alvinpeters
Copy link

This might need some updating lol. IVSC driver just merged for 6.6.
https://lore.kernel.org/lkml/20230901142147.096c1b57@sal.lan/

@jwrdegoede
Copy link
Contributor Author

New push:

  1. Rebased on latest master
  2. Also fix compilation errors in i2c sensor drivers

@hao-yao
Copy link
Contributor

hao-yao commented Oct 17, 2023

Thank you @jwrdegoede . Would you mind also change the ov02e10.c?

diff --git a/drivers/media/i2c/ov02e10.c b/drivers/media/i2c/ov02e10.c
index bfdff21d3..fb9150ab6 100644
--- a/drivers/media/i2c/ov02e10.c
+++ b/drivers/media/i2c/ov02e10.c
@@ -1023,7 +1023,11 @@ static struct i2c_driver ov02e10_i2c_driver = {
                   .pm = &ov02e10_pm_ops,
                   .acpi_match_table = ov02e10_acpi_ids,
                    },
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
        .probe_new = ov02e10_probe,
+#else
+       .probe = ov02e10_probe,
+#endif
        .remove = ov02e10_remove,
 };
 

Besides, we need to change some var/struct names in v6.6 so please let me sync internally.

@jwrdegoede
Copy link
Contributor Author

Thank you @jwrdegoede . Would you mind also change the ov02e10.c?

Rebased to latest master and added the requested changes.

@hao-yao
Copy link
Contributor

hao-yao commented Oct 27, 2023

Hi Hans,

Internally we want to change align struct definitions with IPU6 in upstreaming, so I changed a bit more. Could you try this patch?

diff --git a/drivers/media/pci/intel/ipu-isys.c b/drivers/media/pci/intel/ipu-isys.c
index 8931934d9..3cc38d4c9 100644
--- a/drivers/media/pci/intel/ipu-isys.c
+++ b/drivers/media/pci/intel/ipu-isys.c
@@ -723,6 +723,7 @@ static int isys_iwake_watermark_cleanup(struct ipu_isys *isys)
 }
 
 /* The .bound() notifier callback when a match is found */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
 static int isys_notifier_bound(struct v4l2_async_notifier *notifier,
 			       struct v4l2_subdev *sd,
 			       struct v4l2_async_subdev *asd)
@@ -748,6 +749,33 @@ static void isys_notifier_unbind(struct v4l2_async_notifier *notifier,
 
 	dev_info(&isys->adev->dev, "unbind %s\n", sd->name);
 }
+#else
+static int isys_notifier_bound(struct v4l2_async_notifier *notifier,
+			       struct v4l2_subdev *sd,
+			       struct v4l2_async_connection *asc)
+{
+	struct ipu_isys *isys = container_of(notifier,
+					struct ipu_isys, notifier);
+	struct sensor_async_sd *s_asd = container_of(asc,
+					struct sensor_async_sd, asc);
+
+	dev_info(&isys->adev->dev, "bind %s nlanes is %d port is %d\n",
+		 sd->name, s_asd->csi2.nlanes, s_asd->csi2.port);
+	isys_complete_ext_device_registration(isys, sd, &s_asd->csi2);
+
+	return v4l2_device_register_subdev_nodes(&isys->v4l2_dev);
+}
+
+static void isys_notifier_unbind(struct v4l2_async_notifier *notifier,
+				 struct v4l2_subdev *sd,
+				 struct v4l2_async_connection *asc)
+{
+	struct ipu_isys *isys = container_of(notifier,
+					struct ipu_isys, notifier);
+
+	dev_info(&isys->adev->dev, "unbind %s\n", sd->name);
+}
+#endif
 
 static int isys_notifier_complete(struct v4l2_async_notifier *notifier)
 {
@@ -765,6 +793,7 @@ static const struct v4l2_async_notifier_operations isys_async_ops = {
 	.complete = isys_notifier_complete,
 };
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
 static int isys_fwnode_parse(struct device *dev,
 			     struct v4l2_fwnode_endpoint *vep,
 			     struct v4l2_async_subdev *asd)
@@ -777,6 +806,7 @@ static int isys_fwnode_parse(struct device *dev,
 
 	return 0;
 }
+#endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) && LINUX_VERSION_CODE != KERNEL_VERSION(5, 15, 71)
 static int isys_notifier_init(struct ipu_isys *isys)
@@ -813,13 +843,7 @@ static int isys_notifier_init(struct ipu_isys *isys)
 
 	return ret;
 }
-
-static void isys_notifier_cleanup(struct ipu_isys *isys)
-{
-	v4l2_async_notifier_unregister(&isys->notifier);
-	v4l2_async_notifier_cleanup(&isys->notifier);
-}
-#else
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
 static int isys_notifier_init(struct ipu_isys *isys)
 {
 	struct ipu_device *isp = isys->adev->isp;
@@ -852,7 +876,79 @@ static int isys_notifier_init(struct ipu_isys *isys)
 
 	return ret;
 }
+#else
+static int isys_notifier_init(struct ipu_isys *isys)
+{
+	const struct ipu_isys_internal_csi2_pdata *csi2 =
+	    &isys->pdata->ipdata->csi2;
+	struct ipu_device *isp = isys->adev->isp;
+	struct device *dev = &isp->pdev->dev;
+	unsigned int i;
+	int ret;
+
+	v4l2_async_nf_init(&isys->notifier, &isys->v4l2_dev);
+
+	for (i = 0; i < csi2->nports; i++) {
+		struct v4l2_fwnode_endpoint vep = {
+			.bus_type = V4L2_MBUS_CSI2_DPHY
+		};
+		struct sensor_async_sd *s_asd;
+		struct fwnode_handle *ep;
+
+		ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), i, 0,
+						FWNODE_GRAPH_ENDPOINT_NEXT);
+		if (!ep)
+			continue;
+
+		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+		if (ret)
+			goto err_parse;
+
+		s_asd = v4l2_async_nf_add_fwnode_remote(&isys->notifier, ep,
+							struct
+							sensor_async_sd);
+		if (IS_ERR(s_asd)) {
+			ret = PTR_ERR(s_asd);
+			goto err_parse;
+		}
+
+		s_asd->csi2.port = vep.base.port;
+		s_asd->csi2.nlanes = vep.bus.mipi_csi2.num_data_lanes;
+
+		fwnode_handle_put(ep);
+
+		continue;
+
+err_parse:
+		fwnode_handle_put(ep);
+		return ret;
+	}
+
+	if (list_empty(&isys->notifier.waiting_list)) {
+		/* isys probe could continue with async subdevs missing */
+		dev_warn(&isys->adev->dev, "no subdev found in graph\n");
+		return 0;
+	}
+
+	isys->notifier.ops = &isys_async_ops;
+	ret = v4l2_async_nf_register(&isys->notifier);
+	if (ret) {
+		dev_err(&isys->adev->dev,
+			"failed to register async notifier : %d\n", ret);
+		v4l2_async_nf_cleanup(&isys->notifier);
+	}
+
+	return ret;
+}
+#endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) && LINUX_VERSION_CODE != KERNEL_VERSION(5, 15, 71)
+static void isys_notifier_cleanup(struct ipu_isys *isys)
+{
+	v4l2_async_notifier_unregister(&isys->notifier);
+	v4l2_async_notifier_cleanup(&isys->notifier);
+}
+#else
 static void isys_notifier_cleanup(struct ipu_isys *isys)
 {
 	v4l2_async_nf_unregister(&isys->notifier);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-phy.c b/drivers/media/pci/intel/ipu6/ipu6-isys-phy.c
index c26780106..bc4aafabf 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-phy.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-phy.c
@@ -504,12 +504,21 @@ int ipu6_isys_phy_common_init(struct ipu_isys *isys)
 	struct ipu_bus_device *adev = to_ipu_bus_device(&isys->adev->dev);
 	struct ipu_device *isp = adev->isp;
 	void __iomem *isp_base = isp->base;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
 	struct v4l2_async_subdev *asd;
 	struct sensor_async_subdev *s_asd;
 	unsigned int i;
 
 	list_for_each_entry(asd, &isys->notifier.asd_list, asd_list) {
 		s_asd = container_of(asd, struct sensor_async_subdev, asd);
+#else
+	struct v4l2_async_connection *asc;
+	struct sensor_async_sd *s_asd;
+	unsigned int i;
+
+	list_for_each_entry(asc, &isys->notifier.done_list, asc_entry) {
+		s_asd = container_of(asc, struct sensor_async_sd, asc);
+#endif
 		phy_id = s_asd->csi2.port / 4;
 		phy_base = isp_base + IPU6_ISYS_PHY_BASE(phy_id);
 
@@ -562,6 +571,7 @@ int ipu6_isys_phy_config(struct ipu_isys *isys)
 	struct ipu_device *isp = adev->isp;
 	void __iomem *isp_base = isp->base;
 	const struct phy_reg **phy_config_regs;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
 	struct v4l2_async_subdev *asd;
 	struct sensor_async_subdev *s_asd;
 	struct ipu_isys_csi2_config cfg;
@@ -569,6 +579,15 @@ int ipu6_isys_phy_config(struct ipu_isys *isys)
 
 	list_for_each_entry(asd, &isys->notifier.asd_list, asd_list) {
 		s_asd = container_of(asd, struct sensor_async_subdev, asd);
+#else
+	struct v4l2_async_connection *asc;
+	struct sensor_async_sd *s_asd;
+	struct ipu_isys_csi2_config cfg;
+	int i;
+
+	list_for_each_entry(asc, &isys->notifier.done_list, asc_entry) {
+		s_asd = container_of(asc, struct sensor_async_sd, asc);
+#endif
 		cfg.port = s_asd->csi2.port;
 		cfg.nlanes = s_asd->csi2.nlanes;
 		phy_port = ipu6_isys_driver_port_to_phy_port(&cfg);
diff --git a/include/media/ipu-isys.h b/include/media/ipu-isys.h
index b75febf80..0788b1b40 100644
--- a/include/media/ipu-isys.h
+++ b/include/media/ipu-isys.h
@@ -6,6 +6,7 @@
 
 #include <linux/i2c.h>
 #include <linux/clkdev.h>
+#include <linux/version.h>
 #include <media/v4l2-async.h>
 
 #define IPU_ISYS_MAX_CSI2_LANES		4
@@ -36,9 +37,16 @@ struct ipu_isys_subdev_pdata {
 	struct ipu_isys_clk_mapping *clk_map;
 };
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
 struct sensor_async_subdev {
 	struct v4l2_async_subdev asd;
 	struct ipu_isys_csi2_config csi2;
 };
 
+#else
+struct sensor_async_sd {
+	struct v4l2_async_connection asc;
+	struct ipu_isys_csi2_config csi2;
+};
+#endif
 #endif /* MEDIA_IPU_H */

Kernel 6.6 has made some significant changes to how v4l2-async
(sub)dev registration works. Adjust the code accordingly.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Kernel 6.6.0 has dropped the probe_new i2c_driver callback,
all drivers must now use the probe callback which now uses
the same func-prototype as probe_new used to.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
@jwrdegoede
Copy link
Contributor Author

@hao-yao:

Internally we want to change align struct definitions with IPU6 in upstreaming, so I changed a bit more. Could you try this patch?

Sorry for being a bit slow. Yes that works and looks a bit cleaner too.

I've just pushed a new version (also rebased on the latest master) using this approach, thanks.

@hao-yao
Copy link
Contributor

hao-yao commented Nov 15, 2023

Thank you @jwrdegoede !

@hao-yao hao-yao merged commit 067270f into intel:master Nov 15, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants