rtc: sun6i: Expose internal oscillator through device tree
authorChen-Yu Tsai <wens@csie.org>
Mon, 3 Dec 2018 14:58:19 +0000 (22:58 +0800)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Thu, 6 Dec 2018 17:13:46 +0000 (18:13 +0100)
The bindings have been updated to expose the RTC's internal oscillator,
for some SoCs that have it directly feeding the PRCM block. The changes
include the index 2 for the clock outputs, as well as the clock output
names.

This patch adds the internal oscillator to the list of clocks exposed
through of_clk_add_hw_provider(), and also have the driver optionally
fetch the name of the clock from the device tree if it's available.

Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/rtc/rtc-sun6i.c

index 46609ae56ffdc4f3d09d6620e04742d8d6381084..11f56de521791720409b10645b22e490a5a353e5 100644 (file)
@@ -136,6 +136,7 @@ struct sun6i_rtc_clk_data {
        unsigned int fixed_prescaler : 16;
        unsigned int has_prescaler : 1;
        unsigned int has_out_clk : 1;
+       unsigned int export_iosc : 1;
 };
 
 struct sun6i_rtc_dev {
@@ -220,6 +221,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
                .ops            = &sun6i_rtc_osc_ops,
                .name           = "losc",
        };
+       const char *iosc_name = "rtc-int-osc";
        const char *clkout_name = "osc32k-out";
        const char *parents[2];
 
@@ -228,7 +230,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
                return;
 
        rtc->data = data;
-       clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
+       clk_data = kzalloc(struct_size(clk_data, hws, 3), GFP_KERNEL);
        if (!clk_data) {
                kfree(rtc);
                return;
@@ -253,8 +255,13 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
        if (!of_get_property(node, "clocks", NULL))
                goto err;
 
+       /* Only read IOSC name from device tree if it is exported */
+       if (rtc->data->export_iosc)
+               of_property_read_string_index(node, "clock-output-names", 2,
+                                             &iosc_name);
+
        rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
-                                                               "rtc-int-osc",
+                                                               iosc_name,
                                                                NULL, 0,
                                                                rtc->data->rc_osc_rate,
                                                                300000000);
@@ -293,6 +300,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,
        clk_data->num = 2;
        clk_data->hws[0] = &rtc->hw;
        clk_data->hws[1] = __clk_get_hw(rtc->ext_losc);
+       if (rtc->data->export_iosc) {
+               clk_data->hws[2] = rtc->int_osc;
+               clk_data->num = 3;
+       }
        of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
        return;
 
@@ -330,6 +341,7 @@ static const struct sun6i_rtc_clk_data sun8i_h3_rtc_data = {
        .fixed_prescaler = 32,
        .has_prescaler = 1,
        .has_out_clk = 1,
+       .export_iosc = 1,
 };
 
 static void __init sun8i_h3_rtc_clk_init(struct device_node *node)