Skip to content

Commit 5c23b3f

Browse files
0xB0Dmiquelraynal
authored andcommitted
mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe()
Interacting with a NAND chip on an IPQ6018 I found that the qcomsmem NAND partition parser was returning -EPROBE_DEFER waiting for the main smem driver to load. This caused the board to reset. Playing about with the probe() function shows that the problem lies in the core clock being switched off before the nandc_unalloc() routine has completed. If we look at how qcom_nandc_remove() tears down allocated resources we see the expected order is qcom_nandc_unalloc(nandc); clk_disable_unprepare(nandc->aon_clk); clk_disable_unprepare(nandc->core_clk); dma_unmap_resource(&pdev->dev, nandc->base_dma, resource_size(res), DMA_BIDIRECTIONAL, 0); Tweaking probe() to both bring up and tear-down in that order removes the reset if we end up deferring elsewhere. Fixes: c76b78d ("mtd: nand: Qualcomm NAND controller driver") Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Reviewed-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20220103030316.58301-2-bryan.odonoghue@linaro.org
1 parent ba1b71b commit 5c23b3f

1 file changed

Lines changed: 6 additions & 8 deletions

File tree

drivers/mtd/nand/raw/qcom_nandc.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
/*
33
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
44
*/
5-
65
#include <linux/clk.h>
76
#include <linux/slab.h>
87
#include <linux/bitops.h>
@@ -3073,10 +3072,6 @@ static int qcom_nandc_probe(struct platform_device *pdev)
30733072
if (dma_mapping_error(dev, nandc->base_dma))
30743073
return -ENXIO;
30753074

3076-
ret = qcom_nandc_alloc(nandc);
3077-
if (ret)
3078-
goto err_nandc_alloc;
3079-
30803075
ret = clk_prepare_enable(nandc->core_clk);
30813076
if (ret)
30823077
goto err_core_clk;
@@ -3085,6 +3080,10 @@ static int qcom_nandc_probe(struct platform_device *pdev)
30853080
if (ret)
30863081
goto err_aon_clk;
30873082

3083+
ret = qcom_nandc_alloc(nandc);
3084+
if (ret)
3085+
goto err_nandc_alloc;
3086+
30883087
ret = qcom_nandc_setup(nandc);
30893088
if (ret)
30903089
goto err_setup;
@@ -3096,15 +3095,14 @@ static int qcom_nandc_probe(struct platform_device *pdev)
30963095
return 0;
30973096

30983097
err_setup:
3098+
qcom_nandc_unalloc(nandc);
3099+
err_nandc_alloc:
30993100
clk_disable_unprepare(nandc->aon_clk);
31003101
err_aon_clk:
31013102
clk_disable_unprepare(nandc->core_clk);
31023103
err_core_clk:
3103-
qcom_nandc_unalloc(nandc);
3104-
err_nandc_alloc:
31053104
dma_unmap_resource(dev, res->start, resource_size(res),
31063105
DMA_BIDIRECTIONAL, 0);
3107-
31083106
return ret;
31093107
}
31103108

0 commit comments

Comments
 (0)