Skip to contentSkip to conversation

media: Add a helper for obtaining the clock producer

PATCH Superseded Mehdi Djait 8 participants 70 messages Jun 19, 2025 – Jun 24, 2025

Subsystems (46)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover media: Add a helper for obtaining the clock producer

Hello everyone,

Here is my v1 for the new helper v4l2_devm_sensor_clk_get()

Any testing of the patches is GREATLY APPRECIATED! Especially the two drivers with the special ACPI case:
1) OV8865
2) OV2680

Background
----------

A reference to the clock producer is not available to the kernel in ACPI-based platforms but the sensor drivers still need them.

devm_clk_get() will return an error and the probe function will fail.

Solution
--------

Introduce a generic helper for v4l2 sensor drivers on both DT- and ACPI-based platforms.

This helper behaves the same as clk_get_optional() except where there is no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency" ACPI _DSD property and register a fixed frequency clock with the frequency indicated in the property.

Solution for special ACPI case
------------------------------

This function also handles the special ACPI-based system case where:

1) The clock-frequency _DSD property is present.
2) A reference to the clock producer is present, where the clock is provided by a camera sensor PMIC driver (e.g. int3472/tps68470.c)

In this case try to set the clock-frequency value to the provided clock.

RFC History
-----------

RFC v4 -> RFC v5:
Suggested by Arnd Bergmann:
- removed IS_REACHABLE(CONFIG_COMMON_CLK). IS_REACHABLE() is actually
discouraged [1]. COFIG_COMMON_CLK is a bool, so IS_ENABLED() will be the
right solution here
Suggested by Hans de Goede:
- added handling for the special ACPI-based system case, where
both a reference to the clock-provider and the _DSD
clock-frequency are present.
- updated the function's kernel-doc and the commit msg
to mention this special case.
Link RFC v4: https://lore.kernel.org/linux-media/[email protected]/
[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/kbuild/kconfig-language.rst?h=next-20250513&id=700bd25bd4f47a0f4e02e0a25dde05f1a6b16eea

RFC v3 -> RFC v4:
Suggested by Laurent:
- removed the #ifdef to use IS_REACHABLE(CONFIG_COMMON_CLK)
- changed to kasprintf() to allocate the clk name when id is NULL and used the __free(kfree) scope-based cleanup helper when
defining the variable to hold the allocated name
Link v3: https://lore.kernel.org/linux-media/[email protected]/

RFC v2 -> RFC v3:
- Added #ifdef CONFIG_COMMON_CLK for the ACPI case
Link v2: https://lore.kernel.org/linux-media/[email protected]/

RFC v1 -> RFC v2:
Suggested by Sakari:
- removed clk_name
- removed the IS_ERR() check
- improved the kernel-doc comment and commit msg
Link v1: https://lore.kernel.org/linux-media/[email protected]

Mehdi Djait (55):
media: v4l2-common: Add a helper for obtaining the clock producer
Documentation: media: camera-sensor: Mention
v4l2_devm_sensor_clk_get() for obtaining the clock
media: i2c: ar0521: Use the v4l2 helper for obtaining the clock
media: i2c: ds90ub913: Use the v4l2 helper for obtaining the clock
media: i2c: ds90ub960: Use the v4l2 helper for obtaining the clock
media: i2c: et8ek8: Use the v4l2 helper for obtaining the clock
media: i2c: gc05a2: Use the v4l2 helper for obtaining the clock
media: i2c: gc08a3: Use the v4l2 helper for obtaining the clock
media: i2c: gc2145: Use the v4l2 helper for obtaining the clock
media: i2c: hi846: Use the v4l2 helper for obtaining the clock
media: i2c: imx214: Use the v4l2 helper for obtaining the clock
media: i2c: imx219: Use the v4l2 helper for obtaining the clock
media: i2c: imx283: Use the v4l2 helper for obtaining the clock
media: i2c: imx290: Use the v4l2 helper for obtaining the clock
media: i2c: imx296: Use the v4l2 helper for obtaining the clock
media: i2c: imx334: Use the v4l2 helper for obtaining the clock
media: i2c: imx335: Use the v4l2 helper for obtaining the clock
media: i2c: imx412: Use the v4l2 helper for obtaining the clock
media: i2c: imx415: Use the v4l2 helper for obtaining the clock
media: i2c: max2175: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m001: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m111: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m114: Use the v4l2 helper for obtaining the clock
media: i2c: mt9p031: Use the v4l2 helper for obtaining the clock
media: i2c: mt9t112: Use the v4l2 helper for obtaining the clock
media: i2c: mt9v032: Use the v4l2 helper for obtaining the clock
media: i2c: mt9v111: Use the v4l2 helper for obtaining the clock
media: i2c: ov02a10: Use the v4l2 helper for obtaining the clock
media: i2c: ov2659: Use the v4l2 helper for obtaining the clock
media: i2c: ov2685: Use the v4l2 helper for obtaining the clock
media: i2c: ov5640: Use the v4l2 helper for obtaining the clock
media: i2c: ov5645: Use the v4l2 helper for obtaining the clock
media: i2c: ov5647: Use the v4l2 helper for obtaining the clock
media: i2c: ov5648: Use the v4l2 helper for obtaining the clock
media: i2c: ov5695: Use the v4l2 helper for obtaining the clock
media: i2c: ov64a40: Use the v4l2 helper for obtaining the clock
media: i2c: ov6650: Use the v4l2 helper for obtaining the clock
media: i2c: ov7740: Use the v4l2 helper for obtaining the clock
media: i2c: ov8856: Use the v4l2 helper for obtaining the clock
media: i2c: ov8858: Use the v4l2 helper for obtaining the clock
media: i2c: ov8865: Use the v4l2 helper for obtaining the clock
media: i2c: ov9282: Use the v4l2 helper for obtaining the clock
media: i2c: ov9640: Use the v4l2 helper for obtaining the clock
media: i2c: ov9650: Use the v4l2 helper for obtaining the clock
media: i2c: s5c73m3: Use the v4l2 helper for obtaining the clock
media: i2c: s5k5baf: Use the v4l2 helper for obtaining the clock
media: i2c: s5k6a3: Use the v4l2 helper for obtaining the clock
media: i2c: st-mipid02: Use the v4l2 helper for obtaining the clock
media: i2c: tc358743: Use the v4l2 helper for obtaining the clock
media: i2c: tc358746: Use the v4l2 helper for obtaining the clock
media: i2c: thp7312: Use the v4l2 helper for obtaining the clock
media: i2c: vd55g1: Use the v4l2 helper for obtaining the clock
media: i2c: vd56g3: Use the v4l2 helper for obtaining the clock
media: i2c: vgxy61: Use the v4l2 helper for obtaining the clock
media: i2c: ov2680: Use the v4l2 helper for obtaining the clock

 .../driver-api/media/camera-sensor.rst        |  3 +-
 drivers/media/i2c/ar0521.c                    |  2 +-
 drivers/media/i2c/ds90ub913.c                 |  2 +-
 drivers/media/i2c/ds90ub960.c                 |  2 +-
 drivers/media/i2c/et8ek8/et8ek8_driver.c      |  2 +-
 drivers/media/i2c/gc05a2.c                    |  2 +-
 drivers/media/i2c/gc08a3.c                    |  2 +-
 drivers/media/i2c/gc2145.c                    |  2 +-
 drivers/media/i2c/hi846.c                     |  2 +-
 drivers/media/i2c/imx214.c                    |  2 +-
 drivers/media/i2c/imx219.c                    |  2 +-
 drivers/media/i2c/imx283.c                    |  2 +-
 drivers/media/i2c/imx290.c                    |  2 +-
 drivers/media/i2c/imx296.c                    |  2 +-
 drivers/media/i2c/imx334.c                    |  2 +-
 drivers/media/i2c/imx335.c                    |  2 +-
 drivers/media/i2c/imx412.c                    |  2 +-
 drivers/media/i2c/imx415.c                    |  2 +-
 drivers/media/i2c/max2175.c                   |  2 +-
 drivers/media/i2c/mt9m001.c                   |  2 +-
 drivers/media/i2c/mt9m111.c                   |  2 +-
 drivers/media/i2c/mt9m114.c                   |  2 +-
 drivers/media/i2c/mt9p031.c                   |  2 +-
 drivers/media/i2c/mt9t112.c                   |  2 +-
 drivers/media/i2c/mt9v032.c                   |  2 +-
 drivers/media/i2c/mt9v111.c                   |  2 +-
 drivers/media/i2c/ov02a10.c                   |  2 +-
 drivers/media/i2c/ov2659.c                    |  2 +-
 drivers/media/i2c/ov2680.c                    | 27 +++-------
 drivers/media/i2c/ov2685.c                    |  2 +-
 drivers/media/i2c/ov5640.c                    |  2 +-
 drivers/media/i2c/ov5645.c                    |  2 +-
 drivers/media/i2c/ov5647.c                    |  2 +-
 drivers/media/i2c/ov5648.c                    |  2 +-
 drivers/media/i2c/ov5695.c                    |  2 +-
 drivers/media/i2c/ov64a40.c                   |  2 +-
 drivers/media/i2c/ov6650.c                    |  2 +-
 drivers/media/i2c/ov7740.c                    |  2 +-
 drivers/media/i2c/ov8856.c                    |  2 +-
 drivers/media/i2c/ov8858.c                    |  2 +-
 drivers/media/i2c/ov8865.c                    | 32 ++----------
 drivers/media/i2c/ov9282.c                    |  2 +-
 drivers/media/i2c/ov9640.c                    |  2 +-
 drivers/media/i2c/ov9650.c                    |  2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c      |  2 +-
 drivers/media/i2c/s5k5baf.c                   |  2 +-
 drivers/media/i2c/s5k6a3.c                    |  2 +-
 drivers/media/i2c/st-mipid02.c                |  2 +-
 drivers/media/i2c/tc358743.c                  |  2 +-
 drivers/media/i2c/tc358746.c                  |  2 +-
 drivers/media/i2c/thp7312.c                   |  2 +-
 drivers/media/i2c/vd55g1.c                    |  2 +-
 drivers/media/i2c/vd56g3.c                    |  2 +-
 drivers/media/i2c/vgxy61.c                    |  2 +-
 drivers/media/v4l2-core/v4l2-common.c         | 49 +++++++++++++++++++
 include/media/v4l2-common.h                   | 25 ++++++++++
 56 files changed, 136 insertions(+), 102 deletions(-)
#1 lore raw

PATCH 1/55 media: v4l2-common: Add a helper for obtaining the clock producer

Introduce a helper for v4l2 sensor drivers on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

This helper behaves the same as clk_get_optional() except where there is no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency" ACPI _DSD property and register a fixed frequency clock with the frequency indicated in the property.

This function also handles the special ACPI-based system case where:
The clock-frequency _DSD property is present.
A reference to the clock producer is present, where the clock is provided by a camera sensor PMIC driver (e.g. int3472/tps68470.c)
In this case try to set the clock-frequency value to the provided clock.

drivers/media/v4l2-core/v4l2-common.c +49 -0
index bd160a8c9efe..c53221165c5a 100644
@@ -34,6 +34,9 @@
  * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
  */
 
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -673,3 +676,49 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
+
+struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id)
+{
+	const char *clk_id __free(kfree) = NULL;
+	struct clk_hw *clk_hw;
+	struct clk *clk;
+	bool acpi_node;
+	u32 rate;
+	int ret;
+
+	clk = devm_clk_get_optional(dev, id);
+	ret = device_property_read_u32(dev, "clock-frequency", &rate);
+	acpi_node = is_acpi_node(dev_fwnode(dev));
+
+	if (clk) {
+		if (!ret && acpi_node) {
+			ret = clk_set_rate(clk, rate);
+			if (ret) {
+				dev_err(dev, "Failed to set clock rate: %u\n",
+					rate);
+				return ERR_PTR(ret);
+			}
+		}
+		return clk;
+	}
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	if (!IS_ENABLED(CONFIG_COMMON_CLK) || !acpi_node)
+		return ERR_PTR(-ENOENT);
+
+	if (!id) {
+		clk_id = kasprintf(GFP_KERNEL, "clk-%s", dev_name(dev));
+		if (!clk_id)
+			return ERR_PTR(-ENOMEM);
+		id = clk_id;
+	}
+
+	clk_hw = devm_clk_hw_register_fixed_rate(dev, id, NULL, 0, rate);
+	if (IS_ERR(clk_hw))
+		return ERR_CAST(clk_hw);
+
+	return clk_hw->clk;
+}
+EXPORT_SYMBOL_GPL(devm_v4l2_sensor_clk_get);
include/media/v4l2-common.h +25 -0
index 0a43f56578bc..72d8fcc6057f 100644
@@ -620,6 +620,31 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
 			     unsigned int num_of_driver_link_freqs,
 			     unsigned long *bitmap);
 
+/**
+ * devm_v4l2_sensor_clk_get - lookup and obtain a reference to an optional clock
+ *			      producer for a camera sensor.
+ *
+ * @dev: device for v4l2 sensor clock "consumer"
+ * @id: clock consumer ID
+ *
+ * This function behaves the same way as clk_get_optional() except where there
+ * is no clock producer like in ACPI-based platforms.
+ *
+ * For ACPI-based platforms, the function will read the "clock-frequency"
+ * ACPI _DSD property and register a fixed-clock with the frequency indicated
+ * in the property.
+ *
+ * This function also handles the special ACPI-based system case where:
+ * The clock-frequency _DSD property is present.
+ * A reference to the clock producer is present, where the clock is provided by
+ * a camera sensor PMIC driver (e.g. int3472/tps68470.c)
+ * In this case try to set the clock-frequency value to the provided clock.
+ *
+ * Return:
+ * * pointer to a struct clk on success or an error code on failure.
+ */
+struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id);
+
 static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
 {
 	/*
maintainer Reviewed-by on v1 1/55
#2 lore raw

Re: [PATCH v1 01/55] media: v4l2-common: Add a helper for obtaining the clock producer

Hi Mehdi,

Thank you for the patch.

Quoted 4 lines · Mehdi Djait

Introduce a helper for v4l2 sensor drivers on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

This helper behaves the same as clk_get_optional() except where there is

It actually behaves like devm_clk_get(). The _optional variant returns NULL when the clok is not found, while the helper here return ERR_PTR(-ENOENT).

Quoted 84 lines

no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency" ACPI _DSD property and register a fixed frequency clock with the frequency indicated in the property.

This function also handles the special ACPI-based system case where:
The clock-frequency _DSD property is present.
A reference to the clock producer is present, where the clock is provided by a camera sensor PMIC driver (e.g. int3472/tps68470.c)
In this case try to set the clock-frequency value to the provided clock.

drivers/media/v4l2-core/v4l2-common.c +49 -0
index bd160a8c9efe..c53221165c5a 100644
@@ -34,6 +34,9 @@
  * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
  */
 
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -673,3 +676,49 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(v4l2_link_freq_to_bitmap);
+
+struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id)
+{
+	const char *clk_id __free(kfree) = NULL;
+	struct clk_hw *clk_hw;
+	struct clk *clk;
+	bool acpi_node;
+	u32 rate;
+	int ret;
+
+	clk = devm_clk_get_optional(dev, id);
+	ret = device_property_read_u32(dev, "clock-frequency", &rate);
+	acpi_node = is_acpi_node(dev_fwnode(dev));
+
+	if (clk) {
+		if (!ret && acpi_node) {
+			ret = clk_set_rate(clk, rate);
+			if (ret) {
+				dev_err(dev, "Failed to set clock rate: %u\n",
+					rate);
+				return ERR_PTR(ret);
+			}
+		}
+		return clk;
+	}
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	if (!IS_ENABLED(CONFIG_COMMON_CLK) || !acpi_node)
+		return ERR_PTR(-ENOENT);
+
+	if (!id) {
+		clk_id = kasprintf(GFP_KERNEL, "clk-%s", dev_name(dev));
+		if (!clk_id)
+			return ERR_PTR(-ENOMEM);
+		id = clk_id;
+	}
+
+	clk_hw = devm_clk_hw_register_fixed_rate(dev, id, NULL, 0, rate);
+	if (IS_ERR(clk_hw))
+		return ERR_CAST(clk_hw);
+
+	return clk_hw->clk;
+}
+EXPORT_SYMBOL_GPL(devm_v4l2_sensor_clk_get);
include/media/v4l2-common.h +0 -0
index 0a43f56578bc..72d8fcc6057f 100644
@@ -620,6 +620,31 @@ int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs,
 			     unsigned int num_of_driver_link_freqs,

include/media/v4l2-common.h int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, · line 630

Quoted 10 lines
include/media/v4l2-common.h +8 -0
 			     unsigned long *bitmap);
 
+/**
+ * devm_v4l2_sensor_clk_get - lookup and obtain a reference to an optional clock
+ *			      producer for a camera sensor.
+ *
+ * @dev: device for v4l2 sensor clock "consumer"
+ * @id: clock consumer ID
+ *
+ * This function behaves the same way as clk_get_optional() except where there

s/clk_get_optional/devm_clk_get/

include/media/v4l2-common.h int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, · line 641

Quoted 11 lines
include/media/v4l2-common.h +11 -0
+ * is no clock producer like in ACPI-based platforms.
+ *
+ * For ACPI-based platforms, the function will read the "clock-frequency"
+ * ACPI _DSD property and register a fixed-clock with the frequency indicated
+ * in the property.
+ *
+ * This function also handles the special ACPI-based system case where:
+ * The clock-frequency _DSD property is present.
+ * A reference to the clock producer is present, where the clock is provided by
+ * a camera sensor PMIC driver (e.g. int3472/tps68470.c)
+ * In this case try to set the clock-frequency value to the provided clock.

* This function also handles the special ACPI-based system case where:
*
* * The clock-frequency _DSD property is present.
* * A reference to the clock producer is present, where the clock is provided
* by a camera sensor PMIC driver (e.g. int3472/tps68470.c).
*
* In this case try to set the clock-frequency value to the provided clock.

to get proper formatting in the generated documentation.

include/media/v4l2-common.h int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, · line 644

Quoted 3 lines
include/media/v4l2-common.h +3 -0
+ *
+ * Return:
+ * * pointer to a struct clk on success or an error code on failure.

* Returns a pointer to a struct clk on success or an error pointer on failure.

include/media/v4l2-common.h int v4l2_link_freq_to_bitmap(struct device *dev, const u64 *fw_link_freqs, · line 647

Quoted 3 lines
include/media/v4l2-common.h +3 -0
+ */
+struct clk *devm_v4l2_sensor_clk_get(struct device *dev, const char *id);
+

Please add a forward declaration of struct clk towards the top of the file, with the other forwar declarations.

With those small issues fixed,

Quoted 3 lines
include/media/v4l2-common.h +0 -0
 static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
 {
 	/*
Signature · 3 lines
Regards,

Laurent Pinchart
#3 lore raw

PATCH 2/55 Documentation: media: camera-sensor: Mention v4l2_devm_sensor_clk_get() for obtaining the clock

In reply to Mehdi Djait

Add the new v4l2 helper devm_v4l2_sensor_clk_get() to Documentation. the helper works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Documentation/driver-api/media/camera-sensor.rst +2 -1
index c290833165e6..c82c018a5f40 100644
@@ -32,7 +32,8 @@ user.
 ACPI
 ~~~~
 
-Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
+Use ``devm_v4l2_sensor_clk_get()`` to get the clock. The function will read the
+``clock-frequency`` _DSD property to denote the frequency. The driver
 can rely on this frequency being used.
 
 Devicetree
maintainer
#4 lore raw

Re: [PATCH v1 02/55] Documentation: media: camera-sensor: Mention v4l2_devm_sensor_clk_get() for obtaining the clock

Hi Mehdi,

Thank you for the patch.

Quoted 11 lines · Mehdi Djait

Add the new v4l2 helper devm_v4l2_sensor_clk_get() to Documentation. the helper works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Documentation/driver-api/media/camera-sensor.rst +0 -0
index c290833165e6..c82c018a5f40 100644

Documentation/driver-api/media/camera-sensor.rst user. · line 37

Quoted 7 lines
Documentation/driver-api/media/camera-sensor.rst +2 -1
@@ -32,7 +32,8 @@ user.
 ACPI
 ~~~~
 
-Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
+Use ``devm_v4l2_sensor_clk_get()`` to get the clock. The function will read the
+``clock-frequency`` _DSD property to denote the frequency. The driver
 can rely on this frequency being used.

This isn't specific to ACPI anymore. I think the documentation should be refactored further. Here's a proposal.

Handling clocks
---------------

Camera sensors have an internal clock tree including a PLL and a number of divisors. The clock tree is generally configured by the driver based on a few input parameters that are specific to the hardware: the external clock frequency and the link frequency. The two parameters generally are specified by system firmware. **No other frequencies should be used in any circumstances.**

The reason why the clock frequencies are so important is that the system is usually designed to use specific external clock and link frequencies to ensure electro-magnetic compatibility. Using other frequencies may cause harmful effects elsewhere. Therefore only the pre-determined frequencies are configurable by the user.

The external clock frequency shall be retrieved by obtaining the external clock using the ``devm_v4l2_sensor_clk_get()`` helper function, and then getting its frequency with ``clk_get_rate()``. Usage of the helper function guarantees correct behaviour regardless of whether the sensor is integrated in a DT-based or ACPI-based system.

ACPI
~~~~

ACPI-based systems typically don't register the sensor external clock with the kernel, but specify the external clock frequency in the ``clock-frequency`` _DSD property. The ``devm_v4l2_sensor_clk_get()`` helper creates and returns a fixed clock set at that rate.

Devicetree
~~~~~~~~~~

Devicetree-based systems declare the sensor external clock in the device tree and reference it from the sensor node. The preferred way to select the external clock frequency is to use the ``assigned-clocks``, ``assigned-clock-parents`` and ``assigned-clock-rates`` properties in the sensor node to set the clock rate. See the `clock device tree bindings
<https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml>`_
for more information. The ``devm_v4l2_sensor_clk_get()`` helper retrieves and returns that clock.

This approach has the drawback that there's no guarantee that the frequency hasn't been modified directly or indirectly by another driver, or supported by the board's clock tree to begin with. Changes to the Common Clock Framework API are required to ensure reliability.

Quoted 2 lines
Documentation/driver-api/media/camera-sensor.rst +0 -0
 Devicetree
Signature · 3 lines
Regards,

Laurent Pinchart
maintainer
#5 lore raw

Re: [PATCH v1 02/55] Documentation: media: camera-sensor: Mention v4l2_devm_sensor_clk_get() for obtaining the clock

Hi Mehdi, Laurent,

Quoted 69 lines · Laurent Pinchart

Hi Mehdi,

Thank you for the patch.

Quoted 11 lines · Mehdi Djait

Add the new v4l2 helper devm_v4l2_sensor_clk_get() to Documentation. the helper works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Documentation/driver-api/media/camera-sensor.rst +0 -0
index c290833165e6..c82c018a5f40 100644

Documentation/driver-api/media/camera-sensor.rst user. · line 37

Quoted 7 lines
Documentation/driver-api/media/camera-sensor.rst +2 -1
@@ -32,7 +32,8 @@ user.
 ACPI
 ~~~~
 
-Read the ``clock-frequency`` _DSD property to denote the frequency. The driver
+Use ``devm_v4l2_sensor_clk_get()`` to get the clock. The function will read the
+``clock-frequency`` _DSD property to denote the frequency. The driver
 can rely on this frequency being used.

This isn't specific to ACPI anymore. I think the documentation should be refactored further. Here's a proposal.

Handling clocks
---------------

Camera sensors have an internal clock tree including a PLL and a number of divisors. The clock tree is generally configured by the driver based on a few input parameters that are specific to the hardware: the external clock frequency and the link frequency. The two parameters generally are specified by system firmware. **No other frequencies should be used in any circumstances.**

The reason why the clock frequencies are so important is that the system is usually designed to use specific external clock and link frequencies to ensure electro-magnetic compatibility. Using other frequencies may cause harmful effects elsewhere. Therefore only the pre-determined frequencies are configurable by the user.

The external clock frequency shall be retrieved by obtaining the external clock using the ``devm_v4l2_sensor_clk_get()`` helper function, and then getting its frequency with ``clk_get_rate()``. Usage of the helper function guarantees correct behaviour regardless of whether the sensor is integrated in a DT-based or ACPI-based system.

ACPI
~~~~

ACPI-based systems typically don't register the sensor external clock with the kernel, but specify the external clock frequency in the ``clock-frequency`` _DSD property. The ``devm_v4l2_sensor_clk_get()`` helper creates and returns a fixed clock set at that rate.

Devicetree
~~~~~~~~~~

Devicetree-based systems declare the sensor external clock in the device tree and reference it from the sensor node. The preferred way to select the external clock frequency is to use the ``assigned-clocks``, ``assigned-clock-parents`` and ``assigned-clock-rates`` properties in the sensor node to set the clock rate. See the `clock device tree bindings
<https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml>`_
for more information. The ``devm_v4l2_sensor_clk_get()`` helper retrieves and returns that clock.

Quoted 4 lines

This approach has the drawback that there's no guarantee that the frequency hasn't been modified directly or indirectly by another driver, or supported by the board's clock tree to begin with. Changes to the Common Clock Framework API are required to ensure reliability.

This looks good to me.

Quoted 5 lines
Quoted 4 lines
Documentation/driver-api/media/camera-sensor.rst +0 -0
 Devicetree
Signature · 3 lines
Regards,

Sakari Ailus
#6 lore raw

PATCH 3/55 media: i2c: ar0521: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ar0521.c +1 -1
index 24873149096c..87fb12774b95 100644
@@ -1077,7 +1077,7 @@ static int ar0521_probe(struct i2c_client *client)
 	}
 
 	/* Get master clock (extclk) */
-	sensor->extclk = devm_clk_get(dev, "extclk");
+	sensor->extclk = devm_v4l2_sensor_clk_get(dev, "extclk");
 	if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get extclk\n");
 		return PTR_ERR(sensor->extclk);
Acked-by Krzysztof Hałasa on v1 3/55
#7 lore raw

Re: [PATCH v1 03/55] media: i2c: ar0521: Use the v4l2 helper for obtaining the clock

Hi Mehdi,

I guess it's the same as all other patches in the series.

Sorry if the message formatting is weird - I'm a bit offline now.

Quoted 8 lines

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ar0521.c +1 -1
@@ -1077,7 +1077,7 @@ static int ar0521_probe(struct i2c_client *client)
        }
 
        /* Get master clock (extclk) */
-       sensor->extclk = devm_clk_get(dev, "extclk");
+       sensor->extclk = devm_v4l2_sensor_clk_get(dev, "extclk");
        if (IS_ERR(sensor->extclk)) {
                dev_err(dev, "failed to get extclk\n");
                return PTR_ERR(sensor->extclk);
#8 lore raw

PATCH 4/55 media: i2c: ds90ub913: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ds90ub913.c +1 -1
index 6d3f8617ef13..e3be10d248eb 100644
@@ -880,7 +880,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.
 	 */
-	priv->clkin = devm_clk_get(dev, "clkin");
+	priv->clkin = devm_v4l2_sensor_clk_get(dev, "clkin");
 	if (IS_ERR(priv->clkin))
 		return dev_err_probe(dev, PTR_ERR(priv->clkin),
 				     "Cannot get CLKIN\n");
#9 lore raw

PATCH 5/55 media: i2c: ds90ub960: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ds90ub960.c +1 -1
index 082fc62b0f5b..9de643122e65 100644
@@ -4964,7 +4964,7 @@ static int ub960_get_hw_resources(struct ub960_data *priv)
 		return dev_err_probe(dev, PTR_ERR(priv->pd_gpio),
 				     "Cannot get powerdown GPIO\n");
 
-	priv->refclk = devm_clk_get(dev, "refclk");
+	priv->refclk = devm_v4l2_sensor_clk_get(dev, "refclk");
 	if (IS_ERR(priv->refclk))
 		return dev_err_probe(dev, PTR_ERR(priv->refclk),
 				     "Cannot get REFCLK\n");
#10 lore raw

PATCH 6/55 media: i2c: et8ek8: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/et8ek8/et8ek8_driver.c +1 -1
index 7519863d77b1..3bc238e44f5b 100644
@@ -1433,7 +1433,7 @@ static int et8ek8_probe(struct i2c_client *client)
 		return PTR_ERR(sensor->vana);
 	}
 
-	sensor->ext_clk = devm_clk_get(dev, NULL);
+	sensor->ext_clk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->ext_clk)) {
 		dev_err(&client->dev, "could not get clock\n");
 		return PTR_ERR(sensor->ext_clk);
#11 lore raw

PATCH 7/55 media: i2c: gc05a2: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/gc05a2.c +1 -1
index 3f7f3d5abeeb..4dadd25e6c90 100644
@@ -1235,7 +1235,7 @@ static int gc05a2_probe(struct i2c_client *client)
 		return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
 				     "failed to init CCI\n");
 
-	gc05a2->xclk = devm_clk_get(dev, NULL);
+	gc05a2->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(gc05a2->xclk))
 		return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
 				     "failed to get xclk\n");
#12 lore raw

PATCH 8/55 media: i2c: gc08a3: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/gc08a3.c +1 -1
index 938709a677b6..5d38dfa9878e 100644
@@ -1199,7 +1199,7 @@ static int gc08a3_probe(struct i2c_client *client)
 		return dev_err_probe(dev, PTR_ERR(gc08a3->regmap),
 				     "failed to init CCI\n");
 
-	gc08a3->xclk = devm_clk_get(dev, NULL);
+	gc08a3->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(gc08a3->xclk))
 		return dev_err_probe(dev, PTR_ERR(gc08a3->xclk),
 				     "failed to get xclk\n");
#13 lore raw

PATCH 9/55 media: i2c: gc2145: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/gc2145.c +1 -1
index ba02161d46e7..52d9387559c9 100644
@@ -1334,7 +1334,7 @@ static int gc2145_probe(struct i2c_client *client)
 		return -EINVAL;
 
 	/* Get system clock (xclk) */
-	gc2145->xclk = devm_clk_get(dev, NULL);
+	gc2145->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(gc2145->xclk))
 		return dev_err_probe(dev, PTR_ERR(gc2145->xclk),
 				     "failed to get xclk\n");
#14 lore raw

PATCH 10/55 media: i2c: hi846: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/hi846.c +1 -1
index 172772decd3d..1ae5006cb9be 100644
@@ -2052,7 +2052,7 @@ static int hi846_probe(struct i2c_client *client)
 		return ret;
 	}
 
-	hi846->clock = devm_clk_get(&client->dev, NULL);
+	hi846->clock = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(hi846->clock)) {
 		dev_err(&client->dev, "failed to get clock: %pe\n",
 			hi846->clock);
#15 lore raw

PATCH 11/55 media: i2c: imx214: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx214.c +1 -1
index dd7bc45523d8..73e7bc2f85c0 100644
@@ -1271,7 +1271,7 @@ static int imx214_probe(struct i2c_client *client)
 
 	imx214->dev = dev;
 
-	imx214->xclk = devm_clk_get(dev, NULL);
+	imx214->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(imx214->xclk))
 		return dev_err_probe(dev, PTR_ERR(imx214->xclk),
 				     "failed to get xclk\n");
#16 lore raw

PATCH 12/55 media: i2c: imx219: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx219.c +1 -1
index 3b4f68543342..bb7808515178 100644
@@ -1188,7 +1188,7 @@ static int imx219_probe(struct i2c_client *client)
 				     "failed to initialize CCI\n");
 
 	/* Get system clock (xclk) */
-	imx219->xclk = devm_clk_get(dev, NULL);
+	imx219->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(imx219->xclk))
 		return dev_err_probe(dev, PTR_ERR(imx219->xclk),
 				     "failed to get xclk\n");
#17 lore raw

PATCH 13/55 media: i2c: imx283: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx283.c +1 -1
index da618c8cbadc..582fb528074b 100644
@@ -1462,7 +1462,7 @@ static int imx283_probe(struct i2c_client *client)
 	}
 
 	/* Get system clock (xclk) */
-	imx283->xclk = devm_clk_get(imx283->dev, NULL);
+	imx283->xclk = devm_v4l2_sensor_clk_get(imx283->dev, NULL);
 	if (IS_ERR(imx283->xclk)) {
 		return dev_err_probe(imx283->dev, PTR_ERR(imx283->xclk),
 				     "failed to get xclk\n");
#18 lore raw

PATCH 14/55 media: i2c: imx290: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx290.c +1 -1
index fbf7eba3d71d..759df6eb8545 100644
@@ -1600,7 +1600,7 @@ static int imx290_probe(struct i2c_client *client)
 		return ret;
 
 	/* Acquire resources. */
-	imx290->xclk = devm_clk_get(dev, "xclk");
+	imx290->xclk = devm_v4l2_sensor_clk_get(dev, "xclk");
 	if (IS_ERR(imx290->xclk))
 		return dev_err_probe(dev, PTR_ERR(imx290->xclk),
 				     "Could not get xclk\n");
#19 lore raw

PATCH 15/55 media: i2c: imx296: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx296.c +1 -1
index f3bec16b527c..3795b75a4397 100644
@@ -1044,7 +1044,7 @@ static int imx296_probe(struct i2c_client *client)
 		return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
 				     "failed to get reset GPIO\n");
 
-	sensor->clk = devm_clk_get(sensor->dev, "inck");
+	sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, "inck");
 	if (IS_ERR(sensor->clk))
 		return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
 				     "failed to get clock\n");
#20 lore raw

PATCH 16/55 media: i2c: imx334: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx334.c +1 -1
index 846b9928d4e8..7a9b14d102c9 100644
@@ -997,7 +997,7 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
 				     "failed to get reset gpio\n");
 
 	/* Get sensor input clock */
-	imx334->inclk = devm_clk_get(imx334->dev, NULL);
+	imx334->inclk = devm_v4l2_sensor_clk_get(imx334->dev, NULL);
 	if (IS_ERR(imx334->inclk))
 		return dev_err_probe(imx334->dev, PTR_ERR(imx334->inclk),
 					 "could not get inclk\n");
#21 lore raw

PATCH 17/55 media: i2c: imx335: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx335.c +1 -1
index 9b4db4cd4929..16173aeb3af0 100644
@@ -1026,7 +1026,7 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
 	}
 
 	/* Get sensor input clock */
-	imx335->inclk = devm_clk_get(imx335->dev, NULL);
+	imx335->inclk = devm_v4l2_sensor_clk_get(imx335->dev, NULL);
 	if (IS_ERR(imx335->inclk)) {
 		dev_err(imx335->dev, "could not get inclk\n");
 		return PTR_ERR(imx335->inclk);
#22 lore raw

PATCH 18/55 media: i2c: imx412: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx412.c +1 -1
index c74097a59c42..f35d63ea6c08 100644
@@ -933,7 +933,7 @@ static int imx412_parse_hw_config(struct imx412 *imx412)
 	}
 
 	/* Get sensor input clock */
-	imx412->inclk = devm_clk_get(imx412->dev, NULL);
+	imx412->inclk = devm_v4l2_sensor_clk_get(imx412->dev, NULL);
 	if (IS_ERR(imx412->inclk)) {
 		dev_err(imx412->dev, "could not get inclk\n");
 		return PTR_ERR(imx412->inclk);
#23 lore raw

PATCH 19/55 media: i2c: imx415: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx415.c +1 -1
index 9f37779bd611..f7897660f44f 100644
@@ -1251,7 +1251,7 @@ static int imx415_parse_hw_config(struct imx415 *sensor)
 		return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
 				     "failed to get reset GPIO\n");
 
-	sensor->clk = devm_clk_get(sensor->dev, "inck");
+	sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, "inck");
 	if (IS_ERR(sensor->clk))
 		return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
 				     "failed to get clock\n");
maintainer
#24 lore raw

Re: [PATCH v1 19/55] media: i2c: imx415: Use the v4l2 helper for obtaining the clock

Hi Mehdi,

Thanks for your patch!

Quoted 14 lines · Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/imx415.c +0 -0
index 9f37779bd611..f7897660f44f 100644

drivers/media/i2c/imx415.c static int imx415_parse_hw_config(struct imx415 *sensor) · line 1254

Quoted 5 lines
drivers/media/i2c/imx415.c +1 -1
@@ -1251,7 +1251,7 @@ static int imx415_parse_hw_config(struct imx415 *sensor)
 		return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset),
 				     "failed to get reset GPIO\n");
 
-	sensor->clk = devm_clk_get(sensor->dev, "inck");
+	sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, "inck");

Matthias Fend discovered a while ago that the driver is not in agreement with the DT binding, which does not require a certain clock name. However, the corresponding patch [0] has not landed in v6.16-rc1 AFAIK.

Can we translate the line above directly to

    sensor->clk = devm_v4l2_sensor_clk_get(sensor->dev, NULL);

?

Best regards,
Michael

drivers/media/i2c/imx415.c static int imx415_parse_hw_config(struct imx415 *sensor) · line 1257

Quoted 3 lines
drivers/media/i2c/imx415.c +0 -0
 	if (IS_ERR(sensor->clk))
 		return dev_err_probe(sensor->dev, PTR_ERR(sensor->clk),
 				     "failed to get clock\n");

[0] https://lore.kernel.org/all/[email protected]/

#25 lore raw

PATCH 20/55 media: i2c: max2175: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/max2175.c +1 -1
index bf02ca23a284..07b6e42567ae 100644
@@ -1305,7 +1305,7 @@ static int max2175_probe(struct i2c_client *client)
 		}
 	}
 
-	clk = devm_clk_get(&client->dev, NULL);
+	clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(clk)) {
 		ret = PTR_ERR(clk);
 		dev_err(&client->dev, "cannot get clock %d\n", ret);
#26 lore raw

PATCH 21/55 media: i2c: mt9m001: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9m001.c +1 -1
index 12d3e86bdc0f..184f0fb0963d 100644
@@ -743,7 +743,7 @@ static int mt9m001_probe(struct i2c_client *client)
 	if (!mt9m001)
 		return -ENOMEM;
 
-	mt9m001->clk = devm_clk_get(&client->dev, NULL);
+	mt9m001->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(mt9m001->clk))
 		return PTR_ERR(mt9m001->clk);
 
#27 lore raw

PATCH 22/55 media: i2c: mt9m111: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9m111.c +1 -1
index 9aa5dcda3805..8011d16d4874 100644
@@ -1279,7 +1279,7 @@ static int mt9m111_probe(struct i2c_client *client)
 			return ret;
 	}
 
-	mt9m111->clk = devm_clk_get(&client->dev, "mclk");
+	mt9m111->clk = devm_v4l2_sensor_clk_get(&client->dev, "mclk");
 	if (IS_ERR(mt9m111->clk))
 		return PTR_ERR(mt9m111->clk);
 
#28 lore raw

PATCH 23/55 media: i2c: mt9m114: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9m114.c +1 -1
index 5f0b0ad8f885..bef2512e5d48 100644
@@ -2360,7 +2360,7 @@ static int mt9m114_probe(struct i2c_client *client)
 		return ret;
 
 	/* Acquire clocks, GPIOs and regulators. */
-	sensor->clk = devm_clk_get(dev, NULL);
+	sensor->clk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->clk)) {
 		ret = PTR_ERR(sensor->clk);
 		dev_err_probe(dev, ret, "Failed to get clock\n");
#29 lore raw

PATCH 24/55 media: i2c: mt9p031: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9p031.c +1 -1
index 4ef5fb06131d..b48866831a7a 100644
@@ -233,7 +233,7 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
 	unsigned long ext_freq;
 	int ret;
 
-	mt9p031->clk = devm_clk_get(&client->dev, NULL);
+	mt9p031->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(mt9p031->clk))
 		return PTR_ERR(mt9p031->clk);
 
#30 lore raw

PATCH 25/55 media: i2c: mt9t112: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9t112.c +1 -1
index 878dff9b7577..685234577f30 100644
@@ -1078,7 +1078,7 @@ static int mt9t112_probe(struct i2c_client *client)
 
 	v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
 
-	priv->clk = devm_clk_get(&client->dev, "extclk");
+	priv->clk = devm_v4l2_sensor_clk_get(&client->dev, "extclk");
 	if (PTR_ERR(priv->clk) == -ENOENT) {
 		priv->clk = NULL;
 	} else if (IS_ERR(priv->clk)) {
#31 lore raw

PATCH 26/55 media: i2c: mt9v032: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9v032.c +1 -1
index 302120ff125e..467a83c1da57 100644
@@ -1058,7 +1058,7 @@ static int mt9v032_probe(struct i2c_client *client)
 	if (IS_ERR(mt9v032->regmap))
 		return PTR_ERR(mt9v032->regmap);
 
-	mt9v032->clk = devm_clk_get(&client->dev, NULL);
+	mt9v032->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(mt9v032->clk))
 		return PTR_ERR(mt9v032->clk);
 
#32 lore raw

PATCH 27/55 media: i2c: mt9v111: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/mt9v111.c +1 -1
index 723fe138e7bc..f92648b1777e 100644
@@ -1129,7 +1129,7 @@ static int mt9v111_probe(struct i2c_client *client)
 	mt9v111->dev = &client->dev;
 	mt9v111->client = client;
 
-	mt9v111->clk = devm_clk_get(&client->dev, NULL);
+	mt9v111->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(mt9v111->clk))
 		return PTR_ERR(mt9v111->clk);
 
#33 lore raw

PATCH 28/55 media: i2c: ov02a10: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov02a10.c +1 -1
index 6c30e1a0d814..74fc0687c849 100644
@@ -885,7 +885,7 @@ static int ov02a10_probe(struct i2c_client *client)
 		ov02a10->fmt.code = MEDIA_BUS_FMT_SRGGB10_1X10;
 	}
 
-	ov02a10->eclk = devm_clk_get(dev, "eclk");
+	ov02a10->eclk = devm_v4l2_sensor_clk_get(dev, "eclk");
 	if (IS_ERR(ov02a10->eclk))
 		return dev_err_probe(dev, PTR_ERR(ov02a10->eclk),
 				     "failed to get eclk\n");
#34 lore raw

PATCH 29/55 media: i2c: ov2659: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov2659.c +1 -1
index 06b7896c3eaf..92a13697ab83 100644
@@ -1437,7 +1437,7 @@ static int ov2659_probe(struct i2c_client *client)
 	ov2659->pdata = pdata;
 	ov2659->client = client;
 
-	ov2659->clk = devm_clk_get(&client->dev, "xvclk");
+	ov2659->clk = devm_v4l2_sensor_clk_get(&client->dev, "xvclk");
 	if (IS_ERR(ov2659->clk))
 		return PTR_ERR(ov2659->clk);
 
#35 lore raw

PATCH 30/55 media: i2c: ov2685: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov2685.c +1 -1
index 9b8481b8dcd4..dcd16530078e 100644
@@ -783,7 +783,7 @@ static int ov2685_probe(struct i2c_client *client)
 	ov2685->client = client;
 	ov2685->cur_mode = &supported_modes[0];
 
-	ov2685->xvclk = devm_clk_get(dev, "xvclk");
+	ov2685->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
 	if (IS_ERR(ov2685->xvclk)) {
 		dev_err(dev, "Failed to get xvclk\n");
 		return -EINVAL;
#36 lore raw

PATCH 31/55 media: i2c: ov5640: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov5640.c +1 -1
index 0dae0438aa80..861ebaaa20e3 100644
@@ -3898,7 +3898,7 @@ static int ov5640_probe(struct i2c_client *client)
 					       ov5640_dvp_default_fmt;
 
 	/* get system clock (xclk) */
-	sensor->xclk = devm_clk_get(dev, "xclk");
+	sensor->xclk = devm_v4l2_sensor_clk_get(dev, "xclk");
 	if (IS_ERR(sensor->xclk)) {
 		dev_err(dev, "failed to get xclk\n");
 		return PTR_ERR(sensor->xclk);
#37 lore raw

PATCH 32/55 media: i2c: ov5645: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov5645.c +1 -1
index 004d0ee5c3f5..70b4cdb1b9af 100644
@@ -1044,7 +1044,7 @@ static int ov5645_probe(struct i2c_client *client)
 				     "invalid bus type, must be CSI2\n");
 
 	/* get system clock (xclk) */
-	ov5645->xclk = devm_clk_get(dev, NULL);
+	ov5645->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(ov5645->xclk))
 		return dev_err_probe(dev, PTR_ERR(ov5645->xclk),
 				     "could not get xclk");
#38 lore raw

PATCH 33/55 media: i2c: ov5647: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov5647.c +1 -1
index a727beb9d57e..c8d2bd63c6a0 100644
@@ -1398,7 +1398,7 @@ static int ov5647_probe(struct i2c_client *client)
 		}
 	}
 
-	sensor->xclk = devm_clk_get(dev, NULL);
+	sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->xclk)) {
 		dev_err(dev, "could not get xclk");
 		return PTR_ERR(sensor->xclk);
#39 lore raw

PATCH 34/55 media: i2c: ov5648: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov5648.c +1 -1
index 4b86d2631bd1..8478ca3c49c2 100644
@@ -2521,7 +2521,7 @@ static int ov5648_probe(struct i2c_client *client)
 
 	/* External Clock */
 
-	sensor->xvclk = devm_clk_get(dev, NULL);
+	sensor->xvclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->xvclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->xvclk);
#40 lore raw

PATCH 35/55 media: i2c: ov5695: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov5695.c +1 -1
index 663eccdfea6a..12e57ddf00c9 100644
@@ -1264,7 +1264,7 @@ static int ov5695_probe(struct i2c_client *client)
 	ov5695->client = client;
 	ov5695->cur_mode = &supported_modes[0];
 
-	ov5695->xvclk = devm_clk_get(dev, "xvclk");
+	ov5695->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
 	if (IS_ERR(ov5695->xvclk)) {
 		dev_err(dev, "Failed to get xvclk\n");
 		return -EINVAL;
#41 lore raw

PATCH 36/55 media: i2c: ov64a40: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov64a40.c +1 -1
index a5da4fe47e0b..d7a13e855a41 100644
@@ -3550,7 +3550,7 @@ static int ov64a40_probe(struct i2c_client *client)
 		return PTR_ERR(ov64a40->cci);
 	}
 
-	ov64a40->xclk = devm_clk_get(&client->dev, NULL);
+	ov64a40->xclk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(ov64a40->xclk))
 		return dev_err_probe(&client->dev, PTR_ERR(ov64a40->xclk),
 				     "Failed to get clock\n");
#42 lore raw

PATCH 37/55 media: i2c: ov6650: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov6650.c +1 -1
index 9c7627161142..251a9058fe18 100644
@@ -898,7 +898,7 @@ static int ov6650_video_probe(struct v4l2_subdev *sd)
 	u8 pidh, pidl, midh, midl;
 	int i, ret = 0;
 
-	priv->clk = devm_clk_get(&client->dev, NULL);
+	priv->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 	if (IS_ERR(priv->clk)) {
 		ret = PTR_ERR(priv->clk);
 		dev_err(&client->dev, "clk request err: %d\n", ret);
#43 lore raw

PATCH 38/55 media: i2c: ov7740: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov7740.c +1 -1
index 1f1c0de8e510..280855667655 100644
@@ -1036,7 +1036,7 @@ static int ov7740_probe(struct i2c_client *client)
 	if (!ov7740)
 		return -ENOMEM;
 
-	ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
+	ov7740->xvclk = devm_v4l2_sensor_clk_get(&client->dev, "xvclk");
 	if (IS_ERR(ov7740->xvclk)) {
 		ret = PTR_ERR(ov7740->xvclk);
 		dev_err(&client->dev,
#44 lore raw

PATCH 39/55 media: i2c: ov8856: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov8856.c +1 -1
index 4b6874d2a104..8cc973fff767 100644
@@ -2274,7 +2274,7 @@ static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
 		return ret;
 
 	if (!is_acpi_node(fwnode)) {
-		ov8856->xvclk = devm_clk_get(dev, "xvclk");
+		ov8856->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
 		if (IS_ERR(ov8856->xvclk)) {
 			dev_err_probe(dev, PTR_ERR(ov8856->xvclk),
 				      "could not get xvclk clock\n");
#45 lore raw

PATCH 40/55 media: i2c: ov8858: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov8858.c +1 -1
index 95f9ae794846..c1c6bea8a68b 100644
@@ -1877,7 +1877,7 @@ static int ov8858_probe(struct i2c_client *client)
 	if (!ov8858)
 		return -ENOMEM;
 
-	ov8858->xvclk = devm_clk_get(dev, "xvclk");
+	ov8858->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
 	if (IS_ERR(ov8858->xvclk))
 		return dev_err_probe(dev, PTR_ERR(ov8858->xvclk),
 				     "Failed to get xvclk\n");
#46 lore raw

PATCH 41/55 media: i2c: ov8865: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov8865.c +3 -29
index 95ffe7536aa6..5cc278c3e169 100644
@@ -2956,7 +2956,6 @@ static int ov8865_probe(struct i2c_client *client)
 	struct ov8865_sensor *sensor;
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
-	unsigned int rate = 0;
 	unsigned int i;
 	int ret;
 
@@ -3019,39 +3018,14 @@ static int ov8865_probe(struct i2c_client *client)
 
 	/* External Clock */
 
-	sensor->extclk = devm_clk_get(dev, NULL);
-	if (PTR_ERR(sensor->extclk) == -ENOENT) {
-		dev_info(dev, "no external clock found, continuing...\n");
-		sensor->extclk = NULL;
-	} else if (IS_ERR(sensor->extclk)) {
+	sensor->extclk = devm_v4l2_sensor_clk_get(dev, NULL);
+	if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->extclk);
 		goto error_endpoint;
 	}
 
-	/*
-	 * We could have either a 24MHz or 19.2MHz clock rate from either dt or
-	 * ACPI...but we also need to support the weird IPU3 case which will
-	 * have an external clock AND a clock-frequency property. Check for the
-	 * clock-frequency property and if found, set that rate if we managed
-	 * to acquire a clock. This should cover the ACPI case. If the system
-	 * uses devicetree then the configured rate should already be set, so
-	 * we can just read it.
-	 */
-	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
-				       &rate);
-	if (!ret && sensor->extclk) {
-		ret = clk_set_rate(sensor->extclk, rate);
-		if (ret) {
-			dev_err_probe(dev, ret, "failed to set clock rate\n");
-			goto error_endpoint;
-		}
-	} else if (ret && !sensor->extclk) {
-		dev_err_probe(dev, ret, "invalid clock config\n");
-		goto error_endpoint;
-	}
-
-	sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+	sensor->extclk_rate = clk_get_rate(sensor->extclk);
 
 	for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
 		if (sensor->extclk_rate == supported_extclk_rates[i])
maintainer Reviewed-by on v1 41/55
#47 lore raw

Re: [PATCH v1 41/55] media: i2c: ov8865: Use the v4l2 helper for obtaining the clock

Hi Mehdi,

Thank you for the patch.

Quoted 8 lines · Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Quoted 56 lines
drivers/media/i2c/ov8865.c +3 -29
index 95ffe7536aa6..5cc278c3e169 100644
@@ -2956,7 +2956,6 @@ static int ov8865_probe(struct i2c_client *client)
 	struct ov8865_sensor *sensor;
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
-	unsigned int rate = 0;
 	unsigned int i;
 	int ret;
 
@@ -3019,39 +3018,14 @@ static int ov8865_probe(struct i2c_client *client)
 
 	/* External Clock */
 
-	sensor->extclk = devm_clk_get(dev, NULL);
-	if (PTR_ERR(sensor->extclk) == -ENOENT) {
-		dev_info(dev, "no external clock found, continuing...\n");
-		sensor->extclk = NULL;
-	} else if (IS_ERR(sensor->extclk)) {
+	sensor->extclk = devm_v4l2_sensor_clk_get(dev, NULL);
+	if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->extclk);
 		goto error_endpoint;
 	}
 
-	/*
-	 * We could have either a 24MHz or 19.2MHz clock rate from either dt or
-	 * ACPI...but we also need to support the weird IPU3 case which will
-	 * have an external clock AND a clock-frequency property. Check for the
-	 * clock-frequency property and if found, set that rate if we managed
-	 * to acquire a clock. This should cover the ACPI case. If the system
-	 * uses devicetree then the configured rate should already be set, so
-	 * we can just read it.
-	 */
-	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
-				       &rate);
-	if (!ret && sensor->extclk) {
-		ret = clk_set_rate(sensor->extclk, rate);
-		if (ret) {
-			dev_err_probe(dev, ret, "failed to set clock rate\n");
-			goto error_endpoint;
-		}
-	} else if (ret && !sensor->extclk) {
-		dev_err_probe(dev, ret, "invalid clock config\n");
-		goto error_endpoint;
-	}
-
-	sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+	sensor->extclk_rate = clk_get_rate(sensor->extclk);
 
 	for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
 		if (sensor->extclk_rate == supported_extclk_rates[i])
Signature · 3 lines
Regards,

Laurent Pinchart
maintainer
#48 lore raw

Re: [PATCH v1 41/55] media: i2c: ov8865: Use the v4l2 helper for obtaining the clock

Quoted 33 lines · Laurent Pinchart

Hi Mehdi,

Thank you for the patch.

Quoted 8 lines · Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Quoted 17 lines
drivers/media/i2c/ov8865.c +0 -1
index 95ffe7536aa6..5cc278c3e169 100644
@@ -2956,7 +2956,6 @@ static int ov8865_probe(struct i2c_client *client)
 	struct ov8865_sensor *sensor;
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
-	unsigned int rate = 0;
 	unsigned int i;
 	int ret;
 
@@ -3019,39 +3018,14 @@ static int ov8865_probe(struct i2c_client *client)
 
 	/* External Clock */
 
Quoted 9 lines

drivers/media/i2c/ov8865.c static int ov8865_probe(struct i2c_client *client) · line 3024

Quoted 9 lines
drivers/media/i2c/ov8865.c +2 -5
-	sensor->extclk = devm_clk_get(dev, NULL);
-	if (PTR_ERR(sensor->extclk) == -ENOENT) {
-		dev_info(dev, "no external clock found, continuing...\n");
-		sensor->extclk = NULL;
-	} else if (IS_ERR(sensor->extclk)) {
+	sensor->extclk = devm_v4l2_sensor_clk_get(dev, NULL);
+	if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->extclk);

Actually, I'd take this as an opportunity to write

ret = dev_err_probe(dev, PTR_ERR(sensor->extclk),

				    "failed to get external clock\n");
Quoted 30 lines
Quoted 30 lines
drivers/media/i2c/ov8865.c +1 -23
 		goto error_endpoint;
 	}
 
-	/*
-	 * We could have either a 24MHz or 19.2MHz clock rate from either dt or
-	 * ACPI...but we also need to support the weird IPU3 case which will
-	 * have an external clock AND a clock-frequency property. Check for the
-	 * clock-frequency property and if found, set that rate if we managed
-	 * to acquire a clock. This should cover the ACPI case. If the system
-	 * uses devicetree then the configured rate should already be set, so
-	 * we can just read it.
-	 */
-	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
-				       &rate);
-	if (!ret && sensor->extclk) {
-		ret = clk_set_rate(sensor->extclk, rate);
-		if (ret) {
-			dev_err_probe(dev, ret, "failed to set clock rate\n");
-			goto error_endpoint;
-		}
-	} else if (ret && !sensor->extclk) {
-		dev_err_probe(dev, ret, "invalid clock config\n");
-		goto error_endpoint;
-	}
-
-	sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+	sensor->extclk_rate = clk_get_rate(sensor->extclk);
 
 	for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {
 		if (sensor->extclk_rate == supported_extclk_rates[i])
Signature · 3 lines
Regards,

Laurent Pinchart
maintainer
#49 lore raw

Re: [PATCH v1 41/55] media: i2c: ov8865: Use the v4l2 helper for obtaining the clock

Hi Laurent,

Quoted 46 lines · Laurent Pinchart
Quoted 33 lines · Laurent Pinchart

Hi Mehdi,

Thank you for the patch.

Quoted 8 lines · Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Quoted 17 lines
drivers/media/i2c/ov8865.c +0 -1
index 95ffe7536aa6..5cc278c3e169 100644
@@ -2956,7 +2956,6 @@ static int ov8865_probe(struct i2c_client *client)
 	struct ov8865_sensor *sensor;
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
-	unsigned int rate = 0;
 	unsigned int i;
 	int ret;
 
@@ -3019,39 +3018,14 @@ static int ov8865_probe(struct i2c_client *client)
 
 	/* External Clock */
 
Quoted 9 lines

drivers/media/i2c/ov8865.c static int ov8865_probe(struct i2c_client *client) · line 3024

Quoted 9 lines
drivers/media/i2c/ov8865.c +2 -5
-	sensor->extclk = devm_clk_get(dev, NULL);
-	if (PTR_ERR(sensor->extclk) == -ENOENT) {
-		dev_info(dev, "no external clock found, continuing...\n");
-		sensor->extclk = NULL;
-	} else if (IS_ERR(sensor->extclk)) {
+	sensor->extclk = devm_v4l2_sensor_clk_get(dev, NULL);
+	if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->extclk);

Actually, I'd take this as an opportunity to write

Quoted 2 lines

ret = dev_err_probe(dev, PTR_ERR(sensor->extclk),

				    "failed to get external clock\n");

Wouldn't printing this kind of a message fit for devm_v4l2_sensor_clk_get() and consequently be removed from drivers?

Signature · 3 lines
Kind regards,

Sakari Ailus
maintainer
#50 lore raw

Re: [PATCH v1 41/55] media: i2c: ov8865: Use the v4l2 helper for obtaining the clock

Hi,

Quoted 49 lines · Sakari Ailus

Hi Laurent,

Quoted 46 lines · Laurent Pinchart
Quoted 33 lines · Laurent Pinchart

Hi Mehdi,

Thank you for the patch.

Quoted 8 lines · Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

Quoted 17 lines
drivers/media/i2c/ov8865.c +0 -1
index 95ffe7536aa6..5cc278c3e169 100644
@@ -2956,7 +2956,6 @@ static int ov8865_probe(struct i2c_client *client)
 	struct ov8865_sensor *sensor;
 	struct v4l2_subdev *subdev;
 	struct media_pad *pad;
-	unsigned int rate = 0;
 	unsigned int i;
 	int ret;
 
@@ -3019,39 +3018,14 @@ static int ov8865_probe(struct i2c_client *client)
 
 	/* External Clock */
 
Quoted 9 lines

drivers/media/i2c/ov8865.c static int ov8865_probe(struct i2c_client *client) · line 3024

Quoted 9 lines
drivers/media/i2c/ov8865.c +2 -5
-	sensor->extclk = devm_clk_get(dev, NULL);
-	if (PTR_ERR(sensor->extclk) == -ENOENT) {
-		dev_info(dev, "no external clock found, continuing...\n");
-		sensor->extclk = NULL;
-	} else if (IS_ERR(sensor->extclk)) {
+	sensor->extclk = devm_v4l2_sensor_clk_get(dev, NULL);
+	if (IS_ERR(sensor->extclk)) {
 		dev_err(dev, "failed to get external clock\n");
 		ret = PTR_ERR(sensor->extclk);

Actually, I'd take this as an opportunity to write

Quoted 5 lines
Quoted 2 lines

ret = dev_err_probe(dev, PTR_ERR(sensor->extclk),

				    "failed to get external clock\n");

Wouldn't printing this kind of a message fit for devm_v4l2_sensor_clk_get() and consequently be removed from drivers?

+1 to that suggestion having the helper always log an error on errors and then being able to just directly return an error without needing to log would be great.

Note the helper really should use dev_err_probe() for these errors, so that if devm_clk_get() ever starts returning -EPROBE_DEFER that will be handled properly.

Otherwise this looks good to me. Mehdi thank you for your work on this!

Regards,

Hans

#51 lore raw

PATCH 42/55 media: i2c: ov9282: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov9282.c +1 -1
index c882a021cf18..27c7c007c165 100644
@@ -1135,7 +1135,7 @@ static int ov9282_parse_hw_config(struct ov9282 *ov9282)
 	}
 
 	/* Get sensor input clock */
-	ov9282->inclk = devm_clk_get(ov9282->dev, NULL);
+	ov9282->inclk = devm_v4l2_sensor_clk_get(ov9282->dev, NULL);
 	if (IS_ERR(ov9282->inclk)) {
 		dev_err(ov9282->dev, "could not get inclk");
 		return PTR_ERR(ov9282->inclk);
#52 lore raw

PATCH 43/55 media: i2c: ov9640: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov9640.c +1 -1
index 01dbc0ba89c8..686d69c1a8eb 100644
@@ -718,7 +718,7 @@ static int ov9640_probe(struct i2c_client *client)
 
 	priv->subdev.ctrl_handler = &priv->hdl;
 
-	priv->clk = devm_clk_get(&client->dev, "mclk");
+	priv->clk = devm_v4l2_sensor_clk_get(&client->dev, "mclk");
 	if (IS_ERR(priv->clk)) {
 		ret = PTR_ERR(priv->clk);
 		goto ectrlinit;
#53 lore raw

PATCH 44/55 media: i2c: ov9650: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov9650.c +1 -1
index 026ea34d6291..18c60c91aa40 100644
@@ -1494,7 +1494,7 @@ static int ov965x_probe(struct i2c_client *client)
 	}
 
 	if (dev_fwnode(&client->dev)) {
-		ov965x->clk = devm_clk_get(&client->dev, NULL);
+		ov965x->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
 		if (IS_ERR(ov965x->clk))
 			return PTR_ERR(ov965x->clk);
 		ov965x->mclk_frequency = clk_get_rate(ov965x->clk);
#54 lore raw

PATCH 45/55 media: i2c: s5c73m3: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/s5c73m3/s5c73m3-core.c +1 -1
index 7716dfe2b8c9..ff0ced2d8e98 100644
@@ -1556,7 +1556,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
 	if (!node)
 		return -EINVAL;
 
-	state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME);
+	state->clock = devm_v4l2_sensor_clk_get(dev, S5C73M3_CLK_NAME);
 	if (IS_ERR(state->clock))
 		return PTR_ERR(state->clock);
 
#55 lore raw

PATCH 46/55 media: i2c: s5k5baf: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/s5k5baf.c +1 -1
index 24f399cd2124..01d37f49e5ad 100644
@@ -1967,7 +1967,7 @@ static int s5k5baf_probe(struct i2c_client *c)
 	if (ret < 0)
 		goto err_me;
 
-	state->clock = devm_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
+	state->clock = devm_v4l2_sensor_clk_get(state->sd.dev, S5K5BAF_CLK_NAME);
 	if (IS_ERR(state->clock)) {
 		ret = -EPROBE_DEFER;
 		goto err_me;
#56 lore raw

PATCH 47/55 media: i2c: s5k6a3: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/s5k6a3.c +1 -1
index 0c2674115b7b..927efaedbcad 100644
@@ -292,7 +292,7 @@ static int s5k6a3_probe(struct i2c_client *client)
 	mutex_init(&sensor->lock);
 	sensor->dev = dev;
 
-	sensor->clock = devm_clk_get(sensor->dev, S5K6A3_CLK_NAME);
+	sensor->clock = devm_v4l2_sensor_clk_get(sensor->dev, S5K6A3_CLK_NAME);
 	if (IS_ERR(sensor->clock))
 		return PTR_ERR(sensor->clock);
 
#57 lore raw

PATCH 48/55 media: i2c: st-mipid02: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/st-mipid02.c +1 -1
index f4568e87f018..ea848b52f628 100644
@@ -817,7 +817,7 @@ static int mipid02_probe(struct i2c_client *client)
 	v4l2_i2c_subdev_init(&bridge->sd, client, &mipid02_subdev_ops);
 
 	/* got and check clock */
-	bridge->xclk = devm_clk_get(dev, "xclk");
+	bridge->xclk = devm_v4l2_sensor_clk_get(dev, "xclk");
 	if (IS_ERR(bridge->xclk)) {
 		dev_err(dev, "failed to get xclk\n");
 		return PTR_ERR(bridge->xclk);
#58 lore raw

PATCH 49/55 media: i2c: tc358743: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/tc358743.c +1 -1
index 3d6703b75bfa..24043461b60a 100644
@@ -1930,7 +1930,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
 	u32 bps_pr_lane;
 	int ret;
 
-	refclk = devm_clk_get(dev, "refclk");
+	refclk = devm_v4l2_sensor_clk_get(dev, "refclk");
 	if (IS_ERR(refclk))
 		return dev_err_probe(dev, PTR_ERR(refclk),
 				     "failed to get refclk\n");
#59 lore raw

PATCH 50/55 media: i2c: tc358746: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/tc358746.c +1 -1
index 143aa1359aba..66d271cd516e 100644
@@ -1525,7 +1525,7 @@ static int tc358746_probe(struct i2c_client *client)
 		return dev_err_probe(dev, PTR_ERR(tc358746->regmap),
 				     "Failed to init regmap\n");
 
-	tc358746->refclk = devm_clk_get(dev, "refclk");
+	tc358746->refclk = devm_v4l2_sensor_clk_get(dev, "refclk");
 	if (IS_ERR(tc358746->refclk))
 		return dev_err_probe(dev, PTR_ERR(tc358746->refclk),
 				     "Failed to get refclk\n");
#60 lore raw

PATCH 51/55 media: i2c: thp7312: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/thp7312.c +1 -1
index 8852c56431fe..ca5c5c409c8c 100644
@@ -2109,7 +2109,7 @@ static int thp7312_probe(struct i2c_client *client)
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get regulators\n");
 
-	thp7312->iclk = devm_clk_get(dev, NULL);
+	thp7312->iclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(thp7312->iclk))
 		return dev_err_probe(dev, PTR_ERR(thp7312->iclk),
 				     "Failed to get iclk\n");
#61 lore raw

PATCH 52/55 media: i2c: vd55g1: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/vd55g1.c +1 -1
index 25e2fc88a036..693db225e04d 100644
@@ -1863,7 +1863,7 @@ static int vd55g1_probe(struct i2c_client *client)
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get regulators\n");
 
-	sensor->xclk = devm_clk_get(dev, NULL);
+	sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->xclk))
 		return dev_err_probe(dev, PTR_ERR(sensor->xclk),
 				     "Failed to get xclk\n");
#62 lore raw

PATCH 53/55 media: i2c: vd56g3: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/vd56g3.c +1 -1
index 5d951ad0b478..ac3e868dbb43 100644
@@ -1474,7 +1474,7 @@ static int vd56g3_probe(struct i2c_client *client)
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get regulators\n");
 
-	sensor->xclk = devm_clk_get(dev, NULL);
+	sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->xclk))
 		return dev_err_probe(dev, PTR_ERR(sensor->xclk),
 				     "Failed to get xclk\n");
#63 lore raw

PATCH 54/55 media: i2c: vgxy61: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

devm_clk_get() fails on ACPI-based platforms, where firmware does not provide a direct reference to the clock producer.

Replace devm_clk_get() with the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/vgxy61.c +1 -1
index 5b0479f3a3c0..d6529379d513 100644
@@ -1761,7 +1761,7 @@ static int vgxy61_probe(struct i2c_client *client)
 		return ret;
 	}
 
-	sensor->xclk = devm_clk_get(dev, NULL);
+	sensor->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
 	if (IS_ERR(sensor->xclk)) {
 		dev_err(dev, "failed to get xclk\n");
 		return PTR_ERR(sensor->xclk);
#64 lore raw

PATCH 55/55 media: i2c: ov2680: Use the v4l2 helper for obtaining the clock

In reply to Mehdi Djait

Use the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov2680.c +6 -21
index 7237fb27ecd0..c974169c92f8 100644
@@ -1079,7 +1079,6 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 	struct device *dev = sensor->dev;
 	struct fwnode_handle *ep_fwnode;
 	struct gpio_desc *gpio;
-	unsigned int rate = 0;
 	int i, ret;
 
 	/*
@@ -1114,13 +1113,6 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 
 	sensor->pwdn_gpio = gpio;
 
-	sensor->xvclk = devm_clk_get_optional(dev, "xvclk");
-	if (IS_ERR(sensor->xvclk)) {
-		ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk),
-				    "xvclk clock missing or invalid\n");
-		goto out_free_bus_cfg;
-	}
-
 	/*
 	 * We could have either a 24MHz or 19.2MHz clock rate from either DT or
 	 * ACPI... but we also need to support the weird IPU3 case which will
@@ -1130,22 +1122,15 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 	 * uses devicetree then the configured rate should already be set, so
 	 * we can just read it.
 	 */
-	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
-				       &rate);
-	if (ret && !sensor->xvclk) {
-		dev_err_probe(dev, ret, "invalid clock config\n");
+
+	sensor->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
+	if (IS_ERR(sensor->xvclk)) {
+		ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk),
+				    "xvclk clock missing or invalid\n");
 		goto out_free_bus_cfg;
 	}
 
-	if (!ret && sensor->xvclk) {
-		ret = clk_set_rate(sensor->xvclk, rate);
-		if (ret) {
-			dev_err_probe(dev, ret, "failed to set clock rate\n");
-			goto out_free_bus_cfg;
-		}
-	}
-
-	sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk);
+	sensor->xvclk_freq = clk_get_rate(sensor->xvclk);
 
 	for (i = 0; i < ARRAY_SIZE(ov2680_xvclk_freqs); i++) {
 		if (sensor->xvclk_freq == ov2680_xvclk_freqs[i])
maintainer
#65 lore raw

Re: [PATCH v1 55/55] media: i2c: ov2680: Use the v4l2 helper for obtaining the clock

Hi Mehdi,

Thank you for the patch.

Quoted 33 lines · Mehdi Djait

Use the new v4l2 helper devm_v4l2_sensor_clk_get() that works on both DT- and ACPI-based platforms to retrieve a reference to the clock producer from firmware.

drivers/media/i2c/ov2680.c +0 -8
index 7237fb27ecd0..c974169c92f8 100644
@@ -1079,7 +1079,6 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 	struct device *dev = sensor->dev;
 	struct fwnode_handle *ep_fwnode;
 	struct gpio_desc *gpio;
-	unsigned int rate = 0;
 	int i, ret;
 
 	/*
@@ -1114,13 +1113,6 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 
 	sensor->pwdn_gpio = gpio;
 
-	sensor->xvclk = devm_clk_get_optional(dev, "xvclk");
-	if (IS_ERR(sensor->xvclk)) {
-		ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk),
-				    "xvclk clock missing or invalid\n");
-		goto out_free_bus_cfg;
-	}
-
 	/*
 	 * We could have either a 24MHz or 19.2MHz clock rate from either DT or
 	 * ACPI... but we also need to support the weird IPU3 case which will

drivers/media/i2c/ov2680.c static int ov2680_parse_dt(struct ov2680_dev *sensor) · line 1124

Quoted 3 lines
drivers/media/i2c/ov2680.c +0 -0
@@ -1130,22 +1122,15 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor)
 	 * uses devicetree then the configured rate should already be set, so
 	 * we can just read it.
 	 */

Shouldn't you drop the comment, as in 41/55 ?

Apart from that, the patch looks good to me.

Quoted 25 lines
drivers/media/i2c/ov2680.c +6 -13
-	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
-				       &rate);
-	if (ret && !sensor->xvclk) {
-		dev_err_probe(dev, ret, "invalid clock config\n");
+
+	sensor->xvclk = devm_v4l2_sensor_clk_get(dev, "xvclk");
+	if (IS_ERR(sensor->xvclk)) {
+		ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk),
+				    "xvclk clock missing or invalid\n");
 		goto out_free_bus_cfg;
 	}
 
-	if (!ret && sensor->xvclk) {
-		ret = clk_set_rate(sensor->xvclk, rate);
-		if (ret) {
-			dev_err_probe(dev, ret, "failed to set clock rate\n");
-			goto out_free_bus_cfg;
-		}
-	}
-
-	sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk);
+	sensor->xvclk_freq = clk_get_rate(sensor->xvclk);
 
 	for (i = 0; i < ARRAY_SIZE(ov2680_xvclk_freqs); i++) {
 		if (sensor->xvclk_freq == ov2680_xvclk_freqs[i])
Signature · 3 lines
Regards,

Laurent Pinchart
maintainer Reviewed-by on the v1 series
#66 lore raw
In reply to Mehdi Djait

Hi Mehdi,

Thank you for the patch.

Quoted 81 lines · Mehdi Djait

Hello everyone,

Here is my v1 for the new helper v4l2_devm_sensor_clk_get()

Any testing of the patches is GREATLY APPRECIATED! Especially the two drivers with the special ACPI case:
1) OV8865
2) OV2680

Background
----------

A reference to the clock producer is not available to the kernel in ACPI-based platforms but the sensor drivers still need them.

devm_clk_get() will return an error and the probe function will fail.

Solution
--------

Introduce a generic helper for v4l2 sensor drivers on both DT- and ACPI-based platforms.

This helper behaves the same as clk_get_optional() except where there is no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency" ACPI _DSD property and register a fixed frequency clock with the frequency indicated in the property.

Solution for special ACPI case
------------------------------

This function also handles the special ACPI-based system case where:

1) The clock-frequency _DSD property is present.
2) A reference to the clock producer is present, where the clock is provided by a camera sensor PMIC driver (e.g. int3472/tps68470.c)

In this case try to set the clock-frequency value to the provided clock.

RFC History
-----------

RFC v4 -> RFC v5:
Suggested by Arnd Bergmann:
- removed IS_REACHABLE(CONFIG_COMMON_CLK). IS_REACHABLE() is actually
discouraged [1]. COFIG_COMMON_CLK is a bool, so IS_ENABLED() will be the
right solution here
Suggested by Hans de Goede:
- added handling for the special ACPI-based system case, where
both a reference to the clock-provider and the _DSD
clock-frequency are present.
- updated the function's kernel-doc and the commit msg
to mention this special case.
Link RFC v4: https://lore.kernel.org/linux-media/[email protected]/
[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/kbuild/kconfig-language.rst?h=next-20250513&id=700bd25bd4f47a0f4e02e0a25dde05f1a6b16eea

RFC v3 -> RFC v4:
Suggested by Laurent:
- removed the #ifdef to use IS_REACHABLE(CONFIG_COMMON_CLK)
- changed to kasprintf() to allocate the clk name when id is NULL and used the __free(kfree) scope-based cleanup helper when
defining the variable to hold the allocated name
Link v3: https://lore.kernel.org/linux-media/[email protected]/

RFC v2 -> RFC v3:
- Added #ifdef CONFIG_COMMON_CLK for the ACPI case
Link v2: https://lore.kernel.org/linux-media/[email protected]/

RFC v1 -> RFC v2:
Suggested by Sakari:
- removed clk_name
- removed the IS_ERR() check
- improved the kernel-doc comment and commit msg
Link v1: https://lore.kernel.org/linux-media/[email protected]

Quoted 7 lines

Mehdi Djait (55):
media: v4l2-common: Add a helper for obtaining the clock producer
Documentation: media: camera-sensor: Mention
v4l2_devm_sensor_clk_get() for obtaining the clock
media: i2c: ar0521: Use the v4l2 helper for obtaining the clock
media: i2c: ds90ub913: Use the v4l2 helper for obtaining the clock
media: i2c: ds90ub960: Use the v4l2 helper for obtaining the clock

Those two are FPD-Link serializer and deserializer drivers. I would leave them out, and only address camera sensors in this series, as ACPI integration for serdes or other kind of chips needs to be discussed separately.

Quoted 7 lines

media: i2c: et8ek8: Use the v4l2 helper for obtaining the clock
media: i2c: gc05a2: Use the v4l2 helper for obtaining the clock
media: i2c: gc08a3: Use the v4l2 helper for obtaining the clock
media: i2c: gc2145: Use the v4l2 helper for obtaining the clock
media: i2c: hi846: Use the v4l2 helper for obtaining the clock
media: i2c: imx214: Use the v4l2 helper for obtaining the clock
media: i2c: imx219: Use the v4l2 helper for obtaining the clock

Quoted 8 lines

media: i2c: imx283: Use the v4l2 helper for obtaining the clock
media: i2c: imx290: Use the v4l2 helper for obtaining the clock
media: i2c: imx296: Use the v4l2 helper for obtaining the clock
media: i2c: imx334: Use the v4l2 helper for obtaining the clock
media: i2c: imx335: Use the v4l2 helper for obtaining the clock
media: i2c: imx412: Use the v4l2 helper for obtaining the clock
media: i2c: imx415: Use the v4l2 helper for obtaining the clock
media: i2c: max2175: Use the v4l2 helper for obtaining the clock

This is a tuner, I would leave it out too.

Quoted 22 lines

media: i2c: mt9m001: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m111: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m114: Use the v4l2 helper for obtaining the clock
media: i2c: mt9p031: Use the v4l2 helper for obtaining the clock
media: i2c: mt9t112: Use the v4l2 helper for obtaining the clock
media: i2c: mt9v032: Use the v4l2 helper for obtaining the clock
media: i2c: mt9v111: Use the v4l2 helper for obtaining the clock
media: i2c: ov02a10: Use the v4l2 helper for obtaining the clock
media: i2c: ov2659: Use the v4l2 helper for obtaining the clock
media: i2c: ov2685: Use the v4l2 helper for obtaining the clock
media: i2c: ov5640: Use the v4l2 helper for obtaining the clock
media: i2c: ov5645: Use the v4l2 helper for obtaining the clock
media: i2c: ov5647: Use the v4l2 helper for obtaining the clock
media: i2c: ov5648: Use the v4l2 helper for obtaining the clock
media: i2c: ov5695: Use the v4l2 helper for obtaining the clock
media: i2c: ov64a40: Use the v4l2 helper for obtaining the clock
media: i2c: ov6650: Use the v4l2 helper for obtaining the clock
media: i2c: ov7740: Use the v4l2 helper for obtaining the clock
media: i2c: ov8856: Use the v4l2 helper for obtaining the clock
media: i2c: ov8858: Use the v4l2 helper for obtaining the clock
media: i2c: ov8865: Use the v4l2 helper for obtaining the clock
media: i2c: ov9282: Use the v4l2 helper for obtaining the clock

Quoted 8 lines

media: i2c: ov9640: Use the v4l2 helper for obtaining the clock
media: i2c: ov9650: Use the v4l2 helper for obtaining the clock
media: i2c: s5c73m3: Use the v4l2 helper for obtaining the clock
media: i2c: s5k5baf: Use the v4l2 helper for obtaining the clock
media: i2c: s5k6a3: Use the v4l2 helper for obtaining the clock
media: i2c: st-mipid02: Use the v4l2 helper for obtaining the clock
media: i2c: tc358743: Use the v4l2 helper for obtaining the clock
media: i2c: tc358746: Use the v4l2 helper for obtaining the clock

Those three drivers are for a CSI-2 to parallel or HDMI to CSI-2 bridges, I would leave them out too.

Quoted 1 line

media: i2c: thp7312: Use the v4l2 helper for obtaining the clock

And this is an external ISP, that I would also leave out for now.

Quoted 4 lines

media: i2c: vd55g1: Use the v4l2 helper for obtaining the clock
media: i2c: vd56g3: Use the v4l2 helper for obtaining the clock
media: i2c: vgxy61: Use the v4l2 helper for obtaining the clock
media: i2c: ov2680: Use the v4l2 helper for obtaining the clock

All the rest should be sensors, but please double-check.

For the sensor driver patches *except* ov8865 and ov2680,

Quoted 58 lines
 .../driver-api/media/camera-sensor.rst        |  3 +-
 drivers/media/i2c/ar0521.c                    |  2 +-
 drivers/media/i2c/ds90ub913.c                 |  2 +-
 drivers/media/i2c/ds90ub960.c                 |  2 +-
 drivers/media/i2c/et8ek8/et8ek8_driver.c      |  2 +-
 drivers/media/i2c/gc05a2.c                    |  2 +-
 drivers/media/i2c/gc08a3.c                    |  2 +-
 drivers/media/i2c/gc2145.c                    |  2 +-
 drivers/media/i2c/hi846.c                     |  2 +-
 drivers/media/i2c/imx214.c                    |  2 +-
 drivers/media/i2c/imx219.c                    |  2 +-
 drivers/media/i2c/imx283.c                    |  2 +-
 drivers/media/i2c/imx290.c                    |  2 +-
 drivers/media/i2c/imx296.c                    |  2 +-
 drivers/media/i2c/imx334.c                    |  2 +-
 drivers/media/i2c/imx335.c                    |  2 +-
 drivers/media/i2c/imx412.c                    |  2 +-
 drivers/media/i2c/imx415.c                    |  2 +-
 drivers/media/i2c/max2175.c                   |  2 +-
 drivers/media/i2c/mt9m001.c                   |  2 +-
 drivers/media/i2c/mt9m111.c                   |  2 +-
 drivers/media/i2c/mt9m114.c                   |  2 +-
 drivers/media/i2c/mt9p031.c                   |  2 +-
 drivers/media/i2c/mt9t112.c                   |  2 +-
 drivers/media/i2c/mt9v032.c                   |  2 +-
 drivers/media/i2c/mt9v111.c                   |  2 +-
 drivers/media/i2c/ov02a10.c                   |  2 +-
 drivers/media/i2c/ov2659.c                    |  2 +-
 drivers/media/i2c/ov2680.c                    | 27 +++-------
 drivers/media/i2c/ov2685.c                    |  2 +-
 drivers/media/i2c/ov5640.c                    |  2 +-
 drivers/media/i2c/ov5645.c                    |  2 +-
 drivers/media/i2c/ov5647.c                    |  2 +-
 drivers/media/i2c/ov5648.c                    |  2 +-
 drivers/media/i2c/ov5695.c                    |  2 +-
 drivers/media/i2c/ov64a40.c                   |  2 +-
 drivers/media/i2c/ov6650.c                    |  2 +-
 drivers/media/i2c/ov7740.c                    |  2 +-
 drivers/media/i2c/ov8856.c                    |  2 +-
 drivers/media/i2c/ov8858.c                    |  2 +-
 drivers/media/i2c/ov8865.c                    | 32 ++----------
 drivers/media/i2c/ov9282.c                    |  2 +-
 drivers/media/i2c/ov9640.c                    |  2 +-
 drivers/media/i2c/ov9650.c                    |  2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c      |  2 +-
 drivers/media/i2c/s5k5baf.c                   |  2 +-
 drivers/media/i2c/s5k6a3.c                    |  2 +-
 drivers/media/i2c/st-mipid02.c                |  2 +-
 drivers/media/i2c/tc358743.c                  |  2 +-
 drivers/media/i2c/tc358746.c                  |  2 +-
 drivers/media/i2c/thp7312.c                   |  2 +-
 drivers/media/i2c/vd55g1.c                    |  2 +-
 drivers/media/i2c/vd56g3.c                    |  2 +-
 drivers/media/i2c/vgxy61.c                    |  2 +-
 drivers/media/v4l2-core/v4l2-common.c         | 49 +++++++++++++++++++
 include/media/v4l2-common.h                   | 25 ++++++++++
 56 files changed, 136 insertions(+), 102 deletions(-)
Signature · 3 lines
Regards,

Laurent Pinchart
maintainer
#67 lore raw
In reply to Mehdi Djait

Hi Mehdi,

Thanks for your work!

Quoted 16 lines · Mehdi Djait

Hello everyone,

Here is my v1 for the new helper v4l2_devm_sensor_clk_get()

Any testing of the patches is GREATLY APPRECIATED! Especially the two drivers with the special ACPI case:
1) OV8865
2) OV2680

Background
----------

A reference to the clock producer is not available to the kernel in ACPI-based platforms but the sensor drivers still need them.

Quoted 8 lines

devm_clk_get() will return an error and the probe function will fail.

Solution
--------

Introduce a generic helper for v4l2 sensor drivers on both DT- and ACPI-based platforms.

Out of curiosity: How is this problem specific to V4L2? Does one need a similar helper in other subsystems?

Best regards,
Michael

Quoted 173 lines

This helper behaves the same as clk_get_optional() except where there is no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency" ACPI _DSD property and register a fixed frequency clock with the frequency indicated in the property.

Solution for special ACPI case
------------------------------

This function also handles the special ACPI-based system case where:

1) The clock-frequency _DSD property is present.
2) A reference to the clock producer is present, where the clock is provided by a camera sensor PMIC driver (e.g. int3472/tps68470.c)

In this case try to set the clock-frequency value to the provided clock.

RFC History
-----------

RFC v4 -> RFC v5:
Suggested by Arnd Bergmann:
- removed IS_REACHABLE(CONFIG_COMMON_CLK). IS_REACHABLE() is actually
discouraged [1]. COFIG_COMMON_CLK is a bool, so IS_ENABLED() will be the
right solution here
Suggested by Hans de Goede:
- added handling for the special ACPI-based system case, where
both a reference to the clock-provider and the _DSD
clock-frequency are present.
- updated the function's kernel-doc and the commit msg
to mention this special case.
Link RFC v4: https://lore.kernel.org/linux-media/[email protected]/
[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/kbuild/kconfig-language.rst?h=next-20250513&id=700bd25bd4f47a0f4e02e0a25dde05f1a6b16eea

RFC v3 -> RFC v4:
Suggested by Laurent:
- removed the #ifdef to use IS_REACHABLE(CONFIG_COMMON_CLK)
- changed to kasprintf() to allocate the clk name when id is NULL and used the __free(kfree) scope-based cleanup helper when
defining the variable to hold the allocated name
Link v3: https://lore.kernel.org/linux-media/[email protected]/

RFC v2 -> RFC v3:
- Added #ifdef CONFIG_COMMON_CLK for the ACPI case
Link v2: https://lore.kernel.org/linux-media/[email protected]/

RFC v1 -> RFC v2:
Suggested by Sakari:
- removed clk_name
- removed the IS_ERR() check
- improved the kernel-doc comment and commit msg
Link v1: https://lore.kernel.org/linux-media/[email protected]

Mehdi Djait (55):
media: v4l2-common: Add a helper for obtaining the clock producer
Documentation: media: camera-sensor: Mention
v4l2_devm_sensor_clk_get() for obtaining the clock
media: i2c: ar0521: Use the v4l2 helper for obtaining the clock
media: i2c: ds90ub913: Use the v4l2 helper for obtaining the clock
media: i2c: ds90ub960: Use the v4l2 helper for obtaining the clock
media: i2c: et8ek8: Use the v4l2 helper for obtaining the clock
media: i2c: gc05a2: Use the v4l2 helper for obtaining the clock
media: i2c: gc08a3: Use the v4l2 helper for obtaining the clock
media: i2c: gc2145: Use the v4l2 helper for obtaining the clock
media: i2c: hi846: Use the v4l2 helper for obtaining the clock
media: i2c: imx214: Use the v4l2 helper for obtaining the clock
media: i2c: imx219: Use the v4l2 helper for obtaining the clock
media: i2c: imx283: Use the v4l2 helper for obtaining the clock
media: i2c: imx290: Use the v4l2 helper for obtaining the clock
media: i2c: imx296: Use the v4l2 helper for obtaining the clock
media: i2c: imx334: Use the v4l2 helper for obtaining the clock
media: i2c: imx335: Use the v4l2 helper for obtaining the clock
media: i2c: imx412: Use the v4l2 helper for obtaining the clock
media: i2c: imx415: Use the v4l2 helper for obtaining the clock
media: i2c: max2175: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m001: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m111: Use the v4l2 helper for obtaining the clock
media: i2c: mt9m114: Use the v4l2 helper for obtaining the clock
media: i2c: mt9p031: Use the v4l2 helper for obtaining the clock
media: i2c: mt9t112: Use the v4l2 helper for obtaining the clock
media: i2c: mt9v032: Use the v4l2 helper for obtaining the clock
media: i2c: mt9v111: Use the v4l2 helper for obtaining the clock
media: i2c: ov02a10: Use the v4l2 helper for obtaining the clock
media: i2c: ov2659: Use the v4l2 helper for obtaining the clock
media: i2c: ov2685: Use the v4l2 helper for obtaining the clock
media: i2c: ov5640: Use the v4l2 helper for obtaining the clock
media: i2c: ov5645: Use the v4l2 helper for obtaining the clock
media: i2c: ov5647: Use the v4l2 helper for obtaining the clock
media: i2c: ov5648: Use the v4l2 helper for obtaining the clock
media: i2c: ov5695: Use the v4l2 helper for obtaining the clock
media: i2c: ov64a40: Use the v4l2 helper for obtaining the clock
media: i2c: ov6650: Use the v4l2 helper for obtaining the clock
media: i2c: ov7740: Use the v4l2 helper for obtaining the clock
media: i2c: ov8856: Use the v4l2 helper for obtaining the clock
media: i2c: ov8858: Use the v4l2 helper for obtaining the clock
media: i2c: ov8865: Use the v4l2 helper for obtaining the clock
media: i2c: ov9282: Use the v4l2 helper for obtaining the clock
media: i2c: ov9640: Use the v4l2 helper for obtaining the clock
media: i2c: ov9650: Use the v4l2 helper for obtaining the clock
media: i2c: s5c73m3: Use the v4l2 helper for obtaining the clock
media: i2c: s5k5baf: Use the v4l2 helper for obtaining the clock
media: i2c: s5k6a3: Use the v4l2 helper for obtaining the clock
media: i2c: st-mipid02: Use the v4l2 helper for obtaining the clock
media: i2c: tc358743: Use the v4l2 helper for obtaining the clock
media: i2c: tc358746: Use the v4l2 helper for obtaining the clock
media: i2c: thp7312: Use the v4l2 helper for obtaining the clock
media: i2c: vd55g1: Use the v4l2 helper for obtaining the clock
media: i2c: vd56g3: Use the v4l2 helper for obtaining the clock
media: i2c: vgxy61: Use the v4l2 helper for obtaining the clock
media: i2c: ov2680: Use the v4l2 helper for obtaining the clock

 .../driver-api/media/camera-sensor.rst        |  3 +-
 drivers/media/i2c/ar0521.c                    |  2 +-
 drivers/media/i2c/ds90ub913.c                 |  2 +-
 drivers/media/i2c/ds90ub960.c                 |  2 +-
 drivers/media/i2c/et8ek8/et8ek8_driver.c      |  2 +-
 drivers/media/i2c/gc05a2.c                    |  2 +-
 drivers/media/i2c/gc08a3.c                    |  2 +-
 drivers/media/i2c/gc2145.c                    |  2 +-
 drivers/media/i2c/hi846.c                     |  2 +-
 drivers/media/i2c/imx214.c                    |  2 +-
 drivers/media/i2c/imx219.c                    |  2 +-
 drivers/media/i2c/imx283.c                    |  2 +-
 drivers/media/i2c/imx290.c                    |  2 +-
 drivers/media/i2c/imx296.c                    |  2 +-
 drivers/media/i2c/imx334.c                    |  2 +-
 drivers/media/i2c/imx335.c                    |  2 +-
 drivers/media/i2c/imx412.c                    |  2 +-
 drivers/media/i2c/imx415.c                    |  2 +-
 drivers/media/i2c/max2175.c                   |  2 +-
 drivers/media/i2c/mt9m001.c                   |  2 +-
 drivers/media/i2c/mt9m111.c                   |  2 +-
 drivers/media/i2c/mt9m114.c                   |  2 +-
 drivers/media/i2c/mt9p031.c                   |  2 +-
 drivers/media/i2c/mt9t112.c                   |  2 +-
 drivers/media/i2c/mt9v032.c                   |  2 +-
 drivers/media/i2c/mt9v111.c                   |  2 +-
 drivers/media/i2c/ov02a10.c                   |  2 +-
 drivers/media/i2c/ov2659.c                    |  2 +-
 drivers/media/i2c/ov2680.c                    | 27 +++-------
 drivers/media/i2c/ov2685.c                    |  2 +-
 drivers/media/i2c/ov5640.c                    |  2 +-
 drivers/media/i2c/ov5645.c                    |  2 +-
 drivers/media/i2c/ov5647.c                    |  2 +-
 drivers/media/i2c/ov5648.c                    |  2 +-
 drivers/media/i2c/ov5695.c                    |  2 +-
 drivers/media/i2c/ov64a40.c                   |  2 +-
 drivers/media/i2c/ov6650.c                    |  2 +-
 drivers/media/i2c/ov7740.c                    |  2 +-
 drivers/media/i2c/ov8856.c                    |  2 +-
 drivers/media/i2c/ov8858.c                    |  2 +-
 drivers/media/i2c/ov8865.c                    | 32 ++----------
 drivers/media/i2c/ov9282.c                    |  2 +-
 drivers/media/i2c/ov9640.c                    |  2 +-
 drivers/media/i2c/ov9650.c                    |  2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c      |  2 +-
 drivers/media/i2c/s5k5baf.c                   |  2 +-
 drivers/media/i2c/s5k6a3.c                    |  2 +-
 drivers/media/i2c/st-mipid02.c                |  2 +-
 drivers/media/i2c/tc358743.c                  |  2 +-
 drivers/media/i2c/tc358746.c                  |  2 +-
 drivers/media/i2c/thp7312.c                   |  2 +-
 drivers/media/i2c/vd55g1.c                    |  2 +-
 drivers/media/i2c/vd56g3.c                    |  2 +-
 drivers/media/i2c/vgxy61.c                    |  2 +-
 drivers/media/v4l2-core/v4l2-common.c         | 49 +++++++++++++++++++
 include/media/v4l2-common.h                   | 25 ++++++++++
 56 files changed, 136 insertions(+), 102 deletions(-)
maintainer
#68 lore raw

Hi,

Quoted 24 lines · Michael Riesch

Hi Mehdi,

Thanks for your work!

Quoted 19 lines · Mehdi Djait

Hello everyone,

Here is my v1 for the new helper v4l2_devm_sensor_clk_get()

Any testing of the patches is GREATLY APPRECIATED! Especially the two drivers with the special ACPI case:
1) OV8865
2) OV2680

Background
----------

A reference to the clock producer is not available to the kernel in ACPI-based platforms but the sensor drivers still need them.

devm_clk_get() will return an error and the probe function will fail.

Quoted 8 lines
Quoted 5 lines

Solution
--------

Introduce a generic helper for v4l2 sensor drivers on both DT- and ACPI-based platforms.

Out of curiosity: How is this problem specific to V4L2? Does one need a similar helper in other subsystems?

Clocks on ACPI platforms are typically managed by ACPI through either ACPI power-resources or through the _PS0 an _PS3 methods (power on/off) on the ACPI fwnode for the device.

Camera sensors are special in that the sensor driver wants to know the clock frequency to e.g. program its PLLs and that clk-freq is specified through a device-property on ACPI since the clk is otherwise typically not managed by Linux.

Most other drivers used on x86 don't really care about the clk-frequency, they simply assume the clk-freq is what the hw needs / is the default expected clk freq.

Regards,

Hans

maintainer Reviewed-by Lad Prabhakar on the v1 series
#69 lore raw
In reply to Mehdi Djait
Quoted 82 lines · Mehdi Djait

Hello everyone,

Here is my v1 for the new helper v4l2_devm_sensor_clk_get()

Any testing of the patches is GREATLY APPRECIATED! Especially the two drivers with the special ACPI case:
1) OV8865
2) OV2680

Background
----------

A reference to the clock producer is not available to the kernel in ACPI-based platforms but the sensor drivers still need them.

devm_clk_get() will return an error and the probe function will fail.

Solution
--------

Introduce a generic helper for v4l2 sensor drivers on both DT- and ACPI-based platforms.

This helper behaves the same as clk_get_optional() except where there is no clock producer like in ACPI-based platforms.

For ACPI-based platforms the function will read the "clock-frequency" ACPI _DSD property and register a fixed frequency clock with the frequency indicated in the property.

Solution for special ACPI case
------------------------------

This function also handles the special ACPI-based system case where:

1) The clock-frequency _DSD property is present.
2) A reference to the clock producer is present, where the clock is provided by a camera sensor PMIC driver (e.g. int3472/tps68470.c)

In this case try to set the clock-frequency value to the provided clock.

RFC History
-----------

RFC v4 -> RFC v5:
Suggested by Arnd Bergmann:
- removed IS_REACHABLE(CONFIG_COMMON_CLK). IS_REACHABLE() is actually
discouraged [1]. COFIG_COMMON_CLK is a bool, so IS_ENABLED() will be the
right solution here
Suggested by Hans de Goede:
- added handling for the special ACPI-based system case, where
both a reference to the clock-provider and the _DSD
clock-frequency are present.
- updated the function's kernel-doc and the commit msg
to mention this special case.
Link RFC v4: https://lore.kernel.org/linux-media/[email protected]/
[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/Documentation/kbuild/kconfig-language.rst?h=next-20250513&id=700bd25bd4f47a0f4e02e0a25dde05f1a6b16eea

RFC v3 -> RFC v4:
Suggested by Laurent:
- removed the #ifdef to use IS_REACHABLE(CONFIG_COMMON_CLK)
- changed to kasprintf() to allocate the clk name when id is NULL and used the __free(kfree) scope-based cleanup helper when
defining the variable to hold the allocated name
Link v3: https://lore.kernel.org/linux-media/[email protected]/

RFC v2 -> RFC v3:
- Added #ifdef CONFIG_COMMON_CLK for the ACPI case
Link v2: https://lore.kernel.org/linux-media/[email protected]/

RFC v1 -> RFC v2:
Suggested by Sakari:
- removed clk_name
- removed the IS_ERR() check
- improved the kernel-doc comment and commit msg
Link v1: https://lore.kernel.org/linux-media/[email protected]

Quoted 10 lines

Mehdi Djait (55):
media: v4l2-common: Add a helper for obtaining the clock producer
Documentation: media: camera-sensor: Mention
v4l2_devm_sensor_clk_get() for obtaining the clock
media: i2c: imx219: Use the v4l2 helper for obtaining the clock
media: i2c: mt9p031: Use the v4l2 helper for obtaining the clock
media: i2c: ov2659: Use the v4l2 helper for obtaining the clock
media: i2c: ov2685: Use the v4l2 helper for obtaining the clock
media: i2c: ov5640: Use the v4l2 helper for obtaining the clock
media: i2c: ov5645: Use the v4l2 helper for obtaining the clock

For all the above,

Cheers,
Prabhakar