mtd: rawnand: marvell: Fix clock resource by adding a register clock
authorGregory CLEMENT <gregory.clement@bootlin.com>
Tue, 13 Mar 2018 10:30:16 +0000 (11:30 +0100)
committerBoris Brezillon <boris.brezillon@bootlin.com>
Thu, 29 Mar 2018 07:38:10 +0000 (09:38 +0200)
On Armada 7K/8K we need to explicitly enable the register clock. This
clock is optional because not all the SoCs using this IP need it but at
least for Armada 7K/8K it is actually mandatory.

The binding documentation is updated accordingly.

Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Documentation/devicetree/bindings/mtd/marvell-nand.txt
drivers/mtd/nand/raw/marvell_nand.c

index c08fb477b3c6fd4a8cdd46d40be8a036da7870fd..e0c790706b9b10646363548f432c92bf51fe48b5 100644 (file)
@@ -14,7 +14,10 @@ Required properties:
 - #address-cells: shall be set to 1. Encode the NAND CS.
 - #size-cells: shall be set to 0.
 - interrupts: shall define the NAND controller interrupt.
-- clocks: shall reference the NAND controller clock.
+- clocks: shall reference the NAND controller clocks, the second one is
+  is only needed for the Armada 7K/8K SoCs
+- clock-names: mandatory if there is a second clock, in this case there
+  should be one clock named "core" and another one named "reg"
 - marvell,system-controller: Set to retrieve the syscon node that handles
   NAND controller related registers (only required with the
   "marvell,armada-8k-nand[-controller]" compatibles).
index 528a8e0342bd4d1efa2a7766a88acbab3acd28bb..3d84f4252af4a74a17d15f74f3c9bd9c0c34e62d 100644 (file)
@@ -308,6 +308,7 @@ struct marvell_nfc_caps {
  * @dev:               Parent device (used to print error messages)
  * @regs:              NAND controller registers
  * @ecc_clk:           ECC block clock, two times the NAND controller clock
+ * @reg_clk:           Regiters clock
  * @complete:          Completion object to wait for NAND controller events
  * @assigned_cs:       Bitmask describing already assigned CS lines
  * @chips:             List containing all the NAND chips attached to
@@ -321,6 +322,7 @@ struct marvell_nfc {
        struct device *dev;
        void __iomem *regs;
        struct clk *ecc_clk;
+       struct clk *reg_clk;
        struct completion complete;
        unsigned long assigned_cs;
        struct list_head chips;
@@ -2757,7 +2759,12 @@ static int marvell_nfc_probe(struct platform_device *pdev)
                return irq;
        }
 
-       nfc->ecc_clk = devm_clk_get(&pdev->dev, NULL);
+       nfc->ecc_clk = devm_clk_get(&pdev->dev, "core");
+
+       /* Managed the legacy case (when the first clock was not named) */
+       if (nfc->ecc_clk == ERR_PTR(-ENOENT))
+               nfc->ecc_clk = devm_clk_get(&pdev->dev, NULL);
+
        if (IS_ERR(nfc->ecc_clk))
                return PTR_ERR(nfc->ecc_clk);
 
@@ -2765,12 +2772,24 @@ static int marvell_nfc_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
+       nfc->reg_clk = devm_clk_get(&pdev->dev, "reg");
+       if (PTR_ERR(nfc->reg_clk) != -ENOENT) {
+               if (!IS_ERR(nfc->reg_clk)) {
+                       ret = clk_prepare_enable(nfc->reg_clk);
+                       if (ret)
+                               goto unprepare_ecc_clk;
+               } else {
+                       ret = PTR_ERR(nfc->reg_clk);
+                       goto unprepare_ecc_clk;
+               }
+       }
+
        marvell_nfc_disable_int(nfc, NDCR_ALL_INT);
        marvell_nfc_clear_int(nfc, NDCR_ALL_INT);
        ret = devm_request_irq(dev, irq, marvell_nfc_isr,
                               0, "marvell-nfc", nfc);
        if (ret)
-               goto unprepare_clk;
+               goto unprepare_reg_clk;
 
        /* Get NAND controller capabilities */
        if (pdev->id_entry)
@@ -2781,23 +2800,25 @@ static int marvell_nfc_probe(struct platform_device *pdev)
        if (!nfc->caps) {
                dev_err(dev, "Could not retrieve NFC caps\n");
                ret = -EINVAL;
-               goto unprepare_clk;
+               goto unprepare_reg_clk;
        }
 
        /* Init the controller and then probe the chips */
        ret = marvell_nfc_init(nfc);
        if (ret)
-               goto unprepare_clk;
+               goto unprepare_reg_clk;
 
        platform_set_drvdata(pdev, nfc);
 
        ret = marvell_nand_chips_init(dev, nfc);
        if (ret)
-               goto unprepare_clk;
+               goto unprepare_reg_clk;
 
        return 0;
 
-unprepare_clk:
+unprepare_reg_clk:
+       clk_disable_unprepare(nfc->reg_clk);
+unprepare_ecc_clk:
        clk_disable_unprepare(nfc->ecc_clk);
 
        return ret;
@@ -2814,6 +2835,7 @@ static int marvell_nfc_remove(struct platform_device *pdev)
                dma_release_channel(nfc->dma_chan);
        }
 
+       clk_disable_unprepare(nfc->reg_clk);
        clk_disable_unprepare(nfc->ecc_clk);
 
        return 0;