Skip to content

Commit

Permalink
mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe()
Browse files Browse the repository at this point in the history
commit 5c23b3f upstream.

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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
0xB0D authored and gregkh committed Feb 23, 2022
1 parent 8c84874 commit 1a49b1b
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions drivers/mtd/nand/raw/qcom_nandc.c
Expand Up @@ -2,7 +2,6 @@
/*
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*/

#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/bitops.h>
Expand Down Expand Up @@ -2968,10 +2967,6 @@ static int qcom_nandc_probe(struct platform_device *pdev)
if (!nandc->base_dma)
return -ENXIO;

ret = qcom_nandc_alloc(nandc);
if (ret)
goto err_nandc_alloc;

ret = clk_prepare_enable(nandc->core_clk);
if (ret)
goto err_core_clk;
Expand All @@ -2980,6 +2975,10 @@ static int qcom_nandc_probe(struct platform_device *pdev)
if (ret)
goto err_aon_clk;

ret = qcom_nandc_alloc(nandc);
if (ret)
goto err_nandc_alloc;

ret = qcom_nandc_setup(nandc);
if (ret)
goto err_setup;
Expand All @@ -2991,15 +2990,14 @@ static int qcom_nandc_probe(struct platform_device *pdev)
return 0;

err_setup:
qcom_nandc_unalloc(nandc);
err_nandc_alloc:
clk_disable_unprepare(nandc->aon_clk);
err_aon_clk:
clk_disable_unprepare(nandc->core_clk);
err_core_clk:
qcom_nandc_unalloc(nandc);
err_nandc_alloc:
dma_unmap_resource(dev, res->start, resource_size(res),
DMA_BIDIRECTIONAL, 0);

return ret;
}

Expand Down

0 comments on commit 1a49b1b

Please sign in to comment.