clk: sunxi-ng: Use of_device_get_match_data()

Message ID 20260519003950.626727-1-rosenp@gmail.com (mailing list archive)
State New
Headers
Series clk: sunxi-ng: Use of_device_get_match_data() |

Commit Message

Rosen Penev May 19, 2026, 12:39 a.m. UTC
Use of_device_get_match_data() to fetch the RTC CCU match data directly
instead of open-coding an of_match_device() lookup.

This also lets the driver drop the of_device.h include.

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--
2.54.0
  

Comments

sashiko-bot@kernel.org May 19, 2026, 12:53 a.m. UTC | #1
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Replacing of_match_device() with of_device_get_match_data() fetches match data from the parent RTC driver, leading to an invalid pointer dereference and a kernel panic.
- [High] Bypassing the local CCU match table breaks device-specific configuration and introduces dead code.
--

commit 64f27933b5ce1d6dc6bf932d297fcbf5ea1680b5
Author: Rosen Penev <rosenp@gmail.com>

clk: sunxi-ng: Use of_device_get_match_data()

This commit changes sun6i_rtc_ccu_probe() to use of_device_get_match_data()
instead of explicitly calling of_match_device() with sun6i_rtc_ccu_match.
This allows dropping the linux/of_device.h include.

> diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> index f6bfeba009e8e..a3cf0dde05bed 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c

[ ... ]

> @@ -353,14 +352,12 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
>  {
>  	const struct sun6i_rtc_match_data *data;
>  	struct clk *ext_osc32k_clk = NULL;
> -	const struct of_device_id *match;
>  
>  	/* This driver is only used for newer variants of the hardware. */
> -	match = of_match_device(sun6i_rtc_ccu_match, dev);
> -	if (!match)
> +	data = of_device_get_match_data(dev);

Does this cause an invalid pointer dereference?

Since sun6i_rtc_ccu_probe() is called by the main RTC driver in
drivers/rtc/rtc-sun6i.c, the dev passed here is bound to that driver. Calling
of_device_get_match_data(dev) retrieves the match data from the main RTC
driver's match table (sun6i_rtc_dt_ids), not the local sun6i_rtc_ccu_match
table.

The main RTC driver stores integer flags in its match data:

    .data = (void *)RTC_LINEAR_DAY

Will this result in the data pointer evaluating to an integer like 0x1?

Additionally, does bypassing the local CCU match table break device-specific
configurations?

The sun6i_rtc_ccu_match array contains specialized CCU parameters for devices
like allwinner,sun55i-a523-rtc. Relying on the main RTC driver's match table
means the lookup will fall back to generic settings, such as those for the
r329, instead of applying the specific settings required for the a523.

Does removing the reference to sun6i_rtc_ccu_match also leave the array
entirely unused, turning it into dead code?

> +	if (!data)
>  		return 0;
>  
> -	data = match->data;
>  	have_iosc_calibration = data->have_iosc_calibration;

If data points to an invalid address like 0x1, won't dereferencing it here
cause a kernel panic on newer SoCs?
  
Brian Masney May 19, 2026, 2:16 p.m. UTC | #2
Hi Rosen,

On Mon, May 18, 2026 at 05:39:50PM -0700, Rosen Penev wrote:
> Use of_device_get_match_data() to fetch the RTC CCU match data directly
> instead of open-coding an of_match_device() lookup.
> 
> This also lets the driver drop the of_device.h include.
> 
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
>  drivers/clk/sunxi-ng/ccu-sun6i-rtc.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> index f6bfeba009e8..a3cf0dde05be 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
> @@ -9,7 +9,6 @@
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> -#include <linux/of_device.h>
> 
>  #include <linux/clk/sunxi-ng.h>
> 
> @@ -353,14 +352,12 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
>  {
>  	const struct sun6i_rtc_match_data *data;
>  	struct clk *ext_osc32k_clk = NULL;
> -	const struct of_device_id *match;
> 
>  	/* This driver is only used for newer variants of the hardware. */
> -	match = of_match_device(sun6i_rtc_ccu_match, dev);
> -	if (!match)
> +	data = of_device_get_match_data(dev);

sun6i_rtc_ccu_match becomes unused after this change. It'll use the
table associated the dev from drivers/rtc/rtc-sun6i.c.

Brian


> +	if (!data)
>  		return 0;
> 
> -	data = match->data;
>  	have_iosc_calibration = data->have_iosc_calibration;
> 
>  	if (data->have_ext_osc32k) {
> --
> 2.54.0
>
  

Patch

diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index f6bfeba009e8..a3cf0dde05be 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -9,7 +9,6 @@ 
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/of_device.h>

 #include <linux/clk/sunxi-ng.h>

@@ -353,14 +352,12 @@  int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
 {
 	const struct sun6i_rtc_match_data *data;
 	struct clk *ext_osc32k_clk = NULL;
-	const struct of_device_id *match;

 	/* This driver is only used for newer variants of the hardware. */
-	match = of_match_device(sun6i_rtc_ccu_match, dev);
-	if (!match)
+	data = of_device_get_match_data(dev);
+	if (!data)
 		return 0;

-	data = match->data;
 	have_iosc_calibration = data->have_iosc_calibration;

 	if (data->have_ext_osc32k) {