diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
index f6bfeba009e8..3088f247d927 100644
--- a/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2021 Samuel Holland <samuel@sholland.org>
 //
 
+#include <linux/auxiliary_bus.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
@@ -11,8 +12,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#include <linux/clk/sunxi-ng.h>
-
 #include "ccu_common.h"
 
 #include "ccu_div.h"
@@ -44,6 +43,8 @@
 #define DCXO_CTRL_REG			0x160
 #define DCXO_CTRL_CLK16M_RC_EN		BIT(0)
 
+#define SUN6I_RTC_AUX_ID(_name)		"rtc_sun6i." #_name
+
 struct sun6i_rtc_match_data {
 	bool				have_ext_osc32k		: 1;
 	bool				have_iosc_calibration	: 1;
@@ -349,14 +350,18 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = {
 };
 MODULE_DEVICE_TABLE(of, sun6i_rtc_ccu_match);
 
-int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
+static int sun6i_rtc_ccu_probe(struct auxiliary_device *adev,
+			       const struct auxiliary_device_id *id)
 {
 	const struct sun6i_rtc_match_data *data;
 	struct clk *ext_osc32k_clk = NULL;
 	const struct of_device_id *match;
+	struct device *dev = &adev->dev;
+	void __iomem *reg = dev->platform_data;
+	struct device *parent = dev->parent;
 
 	/* This driver is only used for newer variants of the hardware. */
-	match = of_match_device(sun6i_rtc_ccu_match, dev);
+	match = of_match_device(sun6i_rtc_ccu_match, parent);
 	if (!match)
 		return 0;
 
@@ -367,9 +372,9 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
 		const char *fw_name;
 
 		/* ext-osc32k was the only input clock in the old binding. */
-		fw_name = of_property_present(dev->of_node, "clock-names")
+		fw_name = of_property_present(parent->of_node, "clock-names")
 			? "ext-osc32k" : NULL;
-		ext_osc32k_clk = devm_clk_get_optional(dev, fw_name);
+		ext_osc32k_clk = devm_clk_get_optional(parent, fw_name);
 		if (IS_ERR(ext_osc32k_clk))
 			return PTR_ERR(ext_osc32k_clk);
 	}
@@ -392,6 +397,18 @@ int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg)
 	return devm_sunxi_ccu_probe(dev, reg, &sun6i_rtc_ccu_desc);
 }
 
+static const struct auxiliary_device_id sun6i_ccu_rtc_ids[] = {
+	{ .name = SUN6I_RTC_AUX_ID(sun6i) },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, sun6i_ccu_rtc_ids);
+
+static struct auxiliary_driver sun6i_ccu_rtc_driver = {
+	.probe = sun6i_rtc_ccu_probe,
+	.id_table = sun6i_ccu_rtc_ids,
+};
+module_auxiliary_driver(sun6i_ccu_rtc_driver);
+
 MODULE_IMPORT_NS("SUNXI_CCU");
 MODULE_DESCRIPTION("Support for the Allwinner H616/R329 RTC CCU");
 MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index e5e6013d080e..b4489e0a09ce 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -11,9 +11,9 @@
  * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com>
  */
 
+#include <linux/auxiliary_bus.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/clk/sunxi-ng.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/fs.h>
@@ -141,6 +141,11 @@ struct sun6i_rtc_clk_data {
 
 #define RTC_LINEAR_DAY	BIT(0)
 
+struct sun6i_rtc_match_data {
+	const char *adev_name;
+	unsigned long flags;
+};
+
 struct sun6i_rtc_dev {
 	struct rtc_device *rtc;
 	const struct sun6i_rtc_clk_data *data;
@@ -745,8 +750,10 @@ static void sun6i_rtc_bus_clk_cleanup(void *data)
 
 static int sun6i_rtc_probe(struct platform_device *pdev)
 {
+	const struct sun6i_rtc_match_data *data;
 	struct sun6i_rtc_dev *chip = sun6i_rtc;
 	struct device *dev = &pdev->dev;
+	struct auxiliary_device *adev;
 	struct clk *bus_clk;
 	int ret;
 
@@ -765,6 +772,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	data = of_device_get_match_data(&pdev->dev);
+
 	if (!chip) {
 		chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 		if (!chip)
@@ -776,16 +785,17 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 		if (IS_ERR(chip->base))
 			return PTR_ERR(chip->base);
 
-		if (IS_REACHABLE(CONFIG_SUN6I_RTC_CCU)) {
-			ret = sun6i_rtc_ccu_probe(dev, chip->base);
-			if (ret)
-				return ret;
+		if (data && data->adev_name) {
+			adev = devm_auxiliary_device_create(dev, data->adev_name, chip->base);
+			if (!adev)
+				return -ENODEV;
 		}
 	}
 
 	platform_set_drvdata(pdev, chip);
 
-	chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev);
+	if (data)
+		chip->flags = data->flags;
 
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0)
@@ -850,6 +860,11 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun6i_rtc_match_data sun6i_rtc_match_data = {
+	.adev_name = "sun6i",
+	.flags = RTC_LINEAR_DAY,
+};
+
 /*
  * As far as RTC functionality goes, all models are the same. The
  * datasheets claim that different models have different number of
@@ -865,9 +880,9 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun50i-h5-rtc" },
 	{ .compatible = "allwinner,sun50i-h6-rtc" },
 	{ .compatible = "allwinner,sun50i-h616-rtc",
-		.data = (void *)RTC_LINEAR_DAY },
+		.data = &sun6i_rtc_match_data },
 	{ .compatible = "allwinner,sun50i-r329-rtc",
-		.data = (void *)RTC_LINEAR_DAY },
+		.data = &sun6i_rtc_match_data },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
diff --git a/include/linux/clk/sunxi-ng.h b/include/linux/clk/sunxi-ng.h
index 57c8ec44ab4e..cf32123b39f5 100644
--- a/include/linux/clk/sunxi-ng.h
+++ b/include/linux/clk/sunxi-ng.h
@@ -9,6 +9,4 @@
 int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode);
 int sunxi_ccu_get_mmc_timing_mode(struct clk *clk);
 
-int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg);
-
 #endif
