rtc: ac100: Fix ac100 determine rate bug
PATCH 1/1 rtc: ac100: Fix ac100 determine rate bug
This patch fixes a bug, that prevents the Allwinner A83T and the A80 from a successful boot. You can find the shortend trace below:
Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = (ptrval) [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 PID: 49 Comm: kworker/0:1 Not tainted 4.15.0-10190-gb89e32ccd1be #2 Hardware name: Allwinner sun8i Family Workqueue: events deferred_probe_work_func PC is at clk_hw_get_rate+0x0/0x34 LR is at ac100_clkout_determine_rate+0x48/0x19c
[ ... ]
(clk_hw_get_rate) from (ac100_clkout_determine_rate+0x48/0x19c) (ac100_clkout_determine_rate) from (clk_core_set_rate_nolock+0x3c/0x1a0) (clk_core_set_rate_nolock) from (clk_set_rate+0x30/0x88) (clk_set_rate) from (of_clk_set_defaults+0x200/0x364) (of_clk_set_defaults) from (platform_drv_probe+0x18/0xb0)
To fix that bug, we first check if the return of the clk_hw_get_parent_by_index is non zero. If it is zero we skip that clock parent.
The BUG report could be found here: https://lkml.org/lkml/2018/2/10/198
--- drivers/rtc/rtc-ac100.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/rtc/rtc-ac100.c +6 -1
@@ -183,7 +183,12 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,for (i =0 ; i < num_parents; i++) {struct clk_hw *parent =clk_hw_get_parent_by_index (hw, i); -unsigned long tmp, prate =clk_hw_get_rate (parent); +unsigned long tmp, prate; + +if (!parent) +continue ; + + prate =clk_hw_get_rate (parent); tmp =ac100_clkout_round_rate (hw, req->rate, prate);
Signature · 1 line
2.11.0
Quoted 23 lines · Philipp Rossak
This patch fixes a bug, that prevents the Allwinner A83T and the A80 from a successful boot. You can find the shortend trace below:
Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = (ptrval) [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 PID: 49 Comm: kworker/0:1 Not tainted 4.15.0-10190-gb89e32ccd1be #2 Hardware name: Allwinner sun8i Family Workqueue: events deferred_probe_work_func PC is at clk_hw_get_rate+0x0/0x34 LR is at ac100_clkout_determine_rate+0x48/0x19c[ ... ]
(
clk_hw_get_rate) from (ac100_clkout_determine_rate+0x48/0x19c) (ac100_clkout_determine_rate) from (clk_core_set_rate_nolock+0x3c/0x1a0) (clk_core_set_rate_nolock) from (clk_set_rate+0x30/0x88) (clk_set_rate) from (of_clk_set_defaults+0x200/0x364) (of_clk_set_defaults) from (platform_drv_probe+0x18/0xb0)
Quoted 6 lines
To fix that bug, we first check if the return of the
clk_hw_get_parent_by_indexis non zero. If it is zero we skip that clock parent.The BUG report could be found here: https://lkml.org/lkml/2018/2/10/198
Please add the tag:
Quoted 10 lines
Signed-off-by Philipp Rossak <[email protected]>--- drivers/rtc/rtc-ac100.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)drivers/rtc/rtc-ac100.c +0
-0
drivers/rtc/rtc-ac100.c static int ac100_clkout_determine_rate(struct clk_hw *hw, · line 189
Quoted 8 lines
drivers/rtc/rtc-ac100.c +4
-1@@ -183,7 +183,12 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,for (i =0 ; i < num_parents; i++) {struct clk_hw *parent =clk_hw_get_parent_by_index (hw, i); -unsigned long tmp, prate =clk_hw_get_rate (parent); +unsigned long tmp, prate; + +if (!parent) +continue ;
There should be a comment on why this is happening, i.e. we purposefully left open the possibility of the clock from the codec side missing. Otherwise I think the clk subsystem doesn't expect this to happen, which is why there are no checks like this anywhere.
ChenYu
Quoted 8 lines
drivers/rtc/rtc-ac100.c +2
-1+ + prate =clk_hw_get_rate (parent); tmp =ac100_clkout_round_rate (hw, req->rate, prate); --2.11.0