clocksource/drivers/clksrc-probe: Introduce init functions with return code
authorDaniel Lezcano <daniel.lezcano@linaro.org>
Tue, 31 May 2016 14:25:59 +0000 (16:25 +0200)
committerDaniel Lezcano <daniel.lezcano@linaro.org>
Tue, 28 Jun 2016 08:19:17 +0000 (10:19 +0200)
Currently, the clksrc-probe is not able to handle any error from the init
functions. There are different issues with the current code:
 - the code is duplicated in the init functions by writing error
 - every driver tends to panic in its own init function
 - counting the number of clocksources is not reliable

This patch adds another table to store the functions returning an error.
The table is temporary while we convert all the drivers to return an error
and will disappear.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
drivers/clocksource/clksrc-probe.c
include/asm-generic/vmlinux.lds.h
include/linux/clocksource.h

index 7cb6c923a836f141dd5424c34039fe11a8cbe81e..5fa6a555b35cd56fbbe309042b0d7c038edbd1e3 100644 (file)
 #include <linux/clocksource.h>
 
 extern struct of_device_id __clksrc_of_table[];
+extern struct of_device_id __clksrc_ret_of_table[];
 
 static const struct of_device_id __clksrc_of_table_sentinel
        __used __section(__clksrc_of_table_end);
 
+static const struct of_device_id __clksrc_ret_of_table_sentinel
+       __used __section(__clksrc_ret_of_table_end);
+
 void __init clocksource_probe(void)
 {
        struct device_node *np;
        const struct of_device_id *match;
        of_init_fn_1 init_func;
+       of_init_fn_1_ret init_func_ret;
        unsigned clocksources = 0;
+       int ret;
 
        for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
                if (!of_device_is_available(np))
@@ -40,6 +46,22 @@ void __init clocksource_probe(void)
                clocksources++;
        }
 
+       for_each_matching_node_and_match(np, __clksrc_ret_of_table, &match) {
+               if (!of_device_is_available(np))
+                       continue;
+
+               init_func_ret = match->data;
+
+               ret = init_func_ret(np);
+               if (ret) {
+                       pr_err("Failed to initialize '%s': %d",
+                              of_node_full_name(np), ret);
+                       continue;
+               }
+
+               clocksources++;
+       }
+
        clocksources += acpi_probe_device_table(clksrc);
 
        if (!clocksources)
index 6a67ab94b553363934bc9c2e07eb12d6c8a977f7..8c6c626285c05fe12e8ceb6f3b353229e1f4b46e 100644 (file)
        *(__##name##_of_table_end)
 
 #define CLKSRC_OF_TABLES()     OF_TABLE(CONFIG_CLKSRC_OF, clksrc)
+#define CLKSRC_RET_OF_TABLES() OF_TABLE(CONFIG_CLKSRC_OF, clksrc_ret)
 #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip)
 #define CLK_OF_TABLES()                OF_TABLE(CONFIG_COMMON_CLK, clk)
 #define IOMMU_OF_TABLES()      OF_TABLE(CONFIG_OF_IOMMU, iommu)
        CLK_OF_TABLES()                                                 \
        RESERVEDMEM_OF_TABLES()                                         \
        CLKSRC_OF_TABLES()                                              \
+       CLKSRC_RET_OF_TABLES()                                          \
        IOMMU_OF_TABLES()                                               \
        CPU_METHOD_OF_TABLES()                                          \
        CPUIDLE_METHOD_OF_TABLES()                                      \
index 44a1aff225666108c91a8d9f61081315b75d0617..15c3839850f4afebf68cb8dfedc9558347a6c7ac 100644 (file)
@@ -246,6 +246,9 @@ extern int clocksource_i8253_init(void);
 #define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \
        OF_DECLARE_1(clksrc, name, compat, fn)
 
+#define CLOCKSOURCE_OF_DECLARE_RET(name, compat, fn) \
+       OF_DECLARE_1_RET(clksrc_ret, name, compat, fn)
+
 #ifdef CONFIG_CLKSRC_PROBE
 extern void clocksource_probe(void);
 #else