Merge tag 'nand/for-6.1' into mtd/next
authorMiquel Raynal <miquel.raynal@bootlin.com>
Fri, 7 Oct 2022 14:56:14 +0000 (16:56 +0200)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Fri, 7 Oct 2022 14:56:14 +0000 (16:56 +0200)
Raw NAND core changes:
* Replace of_gpio_named_count() by gpiod_count()
  - Remove misguided comment of nand_get_device()
  - bbt: Use the bitmap API to allocate bitmaps

Raw NAND controller drivers changes:
* Meson:
  - Stop supporting legacy clocks
  - Refine resource getting in probe
  - Convert bindings to yaml
  - Fix clock handling and update the bindings accordingly
  - Fix bit map use in meson_nfc_ecc_correct()
* bcm47xx:
  - Fix spelling typo in comment
* STM32 FMC2:
  - Switch to using devm_fwnode_gpiod_get()
  - Fix dma_map_sg error check
* Cadence:
  - Remove an unneeded result variable
* Marvell:
  - Fix error handle regarding dma_map_sg
* Orion:
  - Use devm_clk_get_optional()
* Cafe:
  - Use correct function name in comment block
* Atmel:
  - Unmap streaming DMA mappings
* Arasan:
  - Stop using 0 as NULL pointer
* GPMI:
  - Fix typo 'the the' in comment
* BRCM:
  - Add individual glue driver selection
  - Move Kconfig to driver folder
* FSL: Fix none ECC mode
* Intel:
  - Use devm_platform_ioremap_resource_byname()
  - Remove unused clk_rate member from struct ebu_nand
  - Remove unused nand_pa member from ebu_nand_cs
  - Don't re-define NAND_DATA_IFACE_CHECK_ONLY
  - Remove undocumented compatible string
  - Fix compatible string in the bindings
  - Read the chip-select line from the correct OF node
  - Fix maximum chip select value in the bindings

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
20 files changed:
Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt [deleted file]
Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/intel,lgm-ebunand.yaml [moved from Documentation/devicetree/bindings/mtd/intel,lgm-nand.yaml with 91% similarity]
drivers/mtd/nand/bbt.c
drivers/mtd/nand/raw/Kconfig
drivers/mtd/nand/raw/arasan-nand-controller.c
drivers/mtd/nand/raw/atmel/nand-controller.c
drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
drivers/mtd/nand/raw/brcmnand/Kconfig [new file with mode: 0644]
drivers/mtd/nand/raw/brcmnand/Makefile
drivers/mtd/nand/raw/cadence-nand-controller.c
drivers/mtd/nand/raw/cafe_nand.c
drivers/mtd/nand/raw/fsl_elbc_nand.c
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/raw/intel-nand-controller.c
drivers/mtd/nand/raw/marvell_nand.c
drivers/mtd/nand/raw/meson_nand.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/nand/raw/orion_nand.c
drivers/mtd/nand/raw/stm32_fmc2_nand.c

diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
deleted file mode 100644 (file)
index 5794ab1..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
-
-This file documents the properties in addition to those available in
-the MTD NAND bindings.
-
-Required properties:
-- compatible : contains one of:
-  - "amlogic,meson-gxl-nfc"
-  - "amlogic,meson-axg-nfc"
-- clocks     :
-       A list of phandle + clock-specifier pairs for the clocks listed
-       in clock-names.
-
-- clock-names: Should contain the following:
-       "core" - NFC module gate clock
-       "device" - device clock from eMMC sub clock controller
-       "rx" - rx clock phase
-       "tx" - tx clock phase
-
-- amlogic,mmc-syscon   : Required for NAND clocks, it's shared with SD/eMMC
-                               controller port C
-
-Optional children nodes:
-Children nodes represent the available nand chips.
-
-Other properties:
-see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindings.
-
-Example demonstrate on AXG SoC:
-
-       sd_emmc_c_clkc: mmc@7000 {
-               compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
-               reg = <0x0 0x7000 0x0 0x800>;
-       };
-
-       nand-controller@7800 {
-               compatible = "amlogic,meson-axg-nfc";
-               reg = <0x0 0x7800 0x0 0x100>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-               interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
-
-               clocks = <&clkc CLKID_SD_EMMC_C>,
-                       <&sd_emmc_c_clkc CLKID_MMC_DIV>,
-                       <&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
-                       <&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
-               clock-names = "core", "device", "rx", "tx";
-               amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&nand_pins>;
-
-               nand@0 {
-                       reg = <0>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-
-                       nand-on-flash-bbt;
-               };
-       };
diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
new file mode 100644 (file)
index 0000000..28fb9a7
--- /dev/null
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/amlogic,meson-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
+
+allOf:
+  - $ref: nand-controller.yaml
+
+maintainers:
+  - liang.yang@amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson-gxl-nfc
+      - amlogic,meson-axg-nfc
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: nfc
+      - const: emmc
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 2
+
+  clock-names:
+    items:
+      - const: core
+      - const: device
+
+patternProperties:
+  "^nand@[0-7]$":
+    type: object
+    properties:
+      reg:
+        minimum: 0
+        maximum: 1
+
+      nand-ecc-mode:
+        const: hw
+
+      nand-ecc-step-size:
+        const: 1024
+
+      nand-ecc-strength:
+        enum: [8, 16, 24, 30, 40, 50, 60]
+        description: |
+          The ECC configurations that can be supported are as follows.
+            meson-gxl-nfc 8, 16, 24, 30, 40, 50, 60
+            meson-axg-nfc 8
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/axg-clkc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    nand-controller@ffe07800 {
+      compatible = "amlogic,meson-axg-nfc";
+      reg = <0xffe07800 0x100>, <0xffe07000 0x800>;
+      reg-names = "nfc", "emmc";
+      interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
+      clocks = <&clkc CLKID_SD_EMMC_C>,  <&clkc CLKID_FCLK_DIV2>;
+      clock-names = "core", "device";
+
+      pinctrl-0 = <&nand_pins>;
+      pinctrl-names = "default";
+
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      nand@0 {
+        reg = <0>;
+      };
+    };
+
+...
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/mtd/intel,lgm-nand.yaml#
+$id: http://devicetree.org/schemas/mtd/intel,lgm-ebunand.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Intel LGM SoC NAND Controller Device Tree Bindings
@@ -14,7 +14,7 @@ maintainers:
 
 properties:
   compatible:
-    const: intel,lgm-nand
+    const: intel,lgm-ebunand
 
   reg:
     maxItems: 6
@@ -51,7 +51,7 @@ patternProperties:
     properties:
       reg:
         minimum: 0
-        maximum: 7
+        maximum: 1
 
       nand-ecc-mode: true
 
@@ -75,7 +75,7 @@ additionalProperties: false
 examples:
   - |
     nand-controller@e0f00000 {
-      compatible = "intel,lgm-nand";
+      compatible = "intel,lgm-ebunand";
       reg = <0xe0f00000 0x100>,
             <0xe1000000 0x300>,
             <0xe1400000 0x8000>,
index 64af689..db4f93a 100644 (file)
@@ -24,11 +24,8 @@ int nanddev_bbt_init(struct nand_device *nand)
 {
        unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS);
        unsigned int nblocks = nanddev_neraseblocks(nand);
-       unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block,
-                                          BITS_PER_LONG);
 
-       nand->bbt.cache = kcalloc(nwords, sizeof(*nand->bbt.cache),
-                                 GFP_KERNEL);
+       nand->bbt.cache = bitmap_zalloc(nblocks * bits_per_block, GFP_KERNEL);
        if (!nand->bbt.cache)
                return -ENOMEM;
 
@@ -44,7 +41,7 @@ EXPORT_SYMBOL_GPL(nanddev_bbt_init);
  */
 void nanddev_bbt_cleanup(struct nand_device *nand)
 {
-       kfree(nand->bbt.cache);
+       bitmap_free(nand->bbt.cache);
 }
 EXPORT_SYMBOL_GPL(nanddev_bbt_cleanup);
 
index 8b6d7a5..4cd40af 100644 (file)
@@ -200,27 +200,7 @@ config MTD_NAND_TMIO
          Support for NAND flash connected to a Toshiba Mobile IO
          Controller in some PDAs, including the Sharp SL6000x.
 
-config MTD_NAND_BRCMNAND
-       tristate "Broadcom STB NAND controller"
-       depends on ARM || ARM64 || MIPS || COMPILE_TEST
-       depends on HAS_IOMEM
-       help
-         Enables the Broadcom NAND controller driver. The controller was
-         originally designed for Set-Top Box but is used on various BCM7xxx,
-         BCM3xxx, BCM63xxx, iProc/Cygnus and more.
-
-if MTD_NAND_BRCMNAND
-
-config MTD_NAND_BRCMNAND_BCMA
-       tristate "Broadcom BCMA NAND controller"
-       depends on BCMA_NFLASH
-       depends on BCMA
-       help
-         Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs.
-         The glue driver will take care of performing the low-level I/O
-         operations to interface the BRCMNAND controller over the BCMA bus.
-
-endif # MTD_NAND_BRCMNAND
+source "drivers/mtd/nand/raw/brcmnand/Kconfig"
 
 config MTD_NAND_BCM47XXNFLASH
        tristate "BCM4706 BCMA NAND controller"
@@ -410,7 +390,7 @@ config MTD_NAND_STM32_FMC2
 
 config MTD_NAND_MESON
        tristate "Support for NAND controller on Amlogic's Meson SoCs"
-       depends on ARCH_MESON || COMPILE_TEST
+       depends on COMMON_CLK && (ARCH_MESON || COMPILE_TEST)
        select MFD_SYSCON
        help
          Enables support for NAND controller on Amlogic's Meson SoCs.
index 296fb16..ec7e6ee 100644 (file)
@@ -915,7 +915,7 @@ static int anfc_check_op(struct nand_chip *chip,
                        if (instr->ctx.data.len > ANFC_MAX_CHUNK_SIZE)
                                return -ENOTSUPP;
 
-                       if (anfc_pkt_len_config(instr->ctx.data.len, 0, 0))
+                       if (anfc_pkt_len_config(instr->ctx.data.len, NULL, NULL))
                                return -ENOTSUPP;
 
                        break;
index c9ac3ba..41c6bd6 100644 (file)
@@ -405,6 +405,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
 
        dma_async_issue_pending(nc->dmac);
        wait_for_completion(&finished);
+       dma_unmap_single(nc->dev, buf_dma, len, dir);
 
        return 0;
 
index 8bb17c5..6487dfc 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/bcma/bcma.h>
 
 /* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has
- * shown ~1000 retries as maxiumum. */
+ * shown ~1000 retries as maximum. */
 #define NFLASH_READY_RETRIES           10000
 
 #define NFLASH_SECTOR_SIZE             512
diff --git a/drivers/mtd/nand/raw/brcmnand/Kconfig b/drivers/mtd/nand/raw/brcmnand/Kconfig
new file mode 100644 (file)
index 0000000..4bc51bf
--- /dev/null
@@ -0,0 +1,49 @@
+config MTD_NAND_BRCMNAND
+       tristate "Broadcom STB NAND controller"
+       depends on ARM || ARM64 || MIPS || COMPILE_TEST
+       depends on HAS_IOMEM
+       help
+         Enables the Broadcom NAND controller driver. The controller was
+         originally designed for Set-Top Box but is used on various BCM7xxx,
+         BCM3xxx, BCM63xxx, iProc/Cygnus and more.
+
+if MTD_NAND_BRCMNAND
+
+config MTD_NAND_BRCMNAND_BCM63XX
+       tristate "Broadcom BCM63xx NAND controller glue"
+       default BCM63XX
+       help
+         Enables the BRCMNAND glue driver to register the NAND controller
+         on Broadcom BCM63xx MIPS-based DSL platforms.
+
+config MTD_NAND_BRCMNAND_BCMA
+       tristate "Broadcom BCMA NAND controller"
+       depends on BCMA_NFLASH
+       depends on BCMA
+       help
+         Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs.
+         The glue driver will take care of performing the low-level I/O
+         operations to interface the BRCMNAND controller over the BCMA bus.
+
+config MTD_NAND_BRCMNAND_BCMBCA
+       tristate "Broadcom BCMBCA NAND controller glue"
+       default ARCH_BCMBCA
+       help
+         Enables the BRCMNAND glue driver to register the NAND controller
+         on Broadcom BCA platforms.
+
+config MTD_NAND_BRCMNAND_BRCMSTB
+       tristate "Broadcom STB Nand controller glue"
+       default ARCH_BRCMSTB
+       help
+         Enables the BRCMNAND glue driver to register the NAND controller
+         on Broadcom STB platforms.
+
+config MTD_NAND_BRCMNAND_IPROC
+       tristate "Broadcom iProc NAND controller glue"
+       default ARCH_BCM_IPROC
+       help
+         Enables the BRCMNAND controller glue driver to register the NAND
+         controller on Broadcom iProc platforms.
+
+endif # MTD_NAND_BRCMNAND
index 16dc725..9907e3e 100644 (file)
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
 # link order matters; don't link the more generic brcmstb_nand.o before the
 # more specific iproc_nand.o, for instance
-obj-$(CONFIG_MTD_NAND_BRCMNAND)                += iproc_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND)                += bcm63138_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND)                += bcm6368_nand.o
-obj-$(CONFIG_MTD_NAND_BRCMNAND)                += brcmstb_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_IPROC)  += iproc_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMBCA) += bcm63138_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCM63XX)        += bcm6368_nand.o
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BRCMSTB)        += brcmstb_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)                += brcmnand.o
 
 obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA)   += bcma_nand.o
index 0d72672..9dac3ca 100644 (file)
@@ -1979,7 +1979,6 @@ static int cadence_nand_force_byte_access(struct nand_chip *chip,
                                          bool force_8bit)
 {
        struct cdns_nand_ctrl *cdns_ctrl = to_cdns_nand_ctrl(chip->controller);
-       int status;
 
        /*
         * Callers of this function do not verify if the NAND is using a 16-bit
@@ -1990,9 +1989,7 @@ static int cadence_nand_force_byte_access(struct nand_chip *chip,
        if (!(chip->options & NAND_BUSWIDTH_16))
                return 0;
 
-       status = cadence_nand_set_access_width16(cdns_ctrl, !force_8bit);
-
-       return status;
+       return cadence_nand_set_access_width16(cdns_ctrl, !force_8bit);
 }
 
 static int cadence_nand_cmd_opcode(struct nand_chip *chip,
index af119e3..66385c4 100644 (file)
@@ -358,7 +358,7 @@ static int cafe_nand_read_oob(struct nand_chip *chip, int page)
        return nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
 }
 /**
- * cafe_nand_read_page_syndrome - [REPLACEABLE] hardware ecc syndrome based page read
+ * cafe_nand_read_page - [REPLACEABLE] hardware ecc syndrome based page read
  * @chip:      nand chip info structure
  * @buf:       buffer to store read data
  * @oob_required:      caller expects OOB data read to chip->oob_poi
index aab93b9..a18d121 100644 (file)
@@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
        struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
        unsigned int al;
 
-       switch (chip->ecc.engine_type) {
        /*
         * if ECC was not chosen in DT, decide whether to use HW or SW ECC from
         * CS Base Register
         */
-       case NAND_ECC_ENGINE_TYPE_NONE:
+       if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) {
                /* If CS Base Register selects full hardware ECC then use it */
                if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
                    BR_DECC_CHK_GEN) {
-                       chip->ecc.read_page = fsl_elbc_read_page;
-                       chip->ecc.write_page = fsl_elbc_write_page;
-                       chip->ecc.write_subpage = fsl_elbc_write_subpage;
-
                        chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
-                       mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
-                       chip->ecc.size = 512;
-                       chip->ecc.bytes = 3;
-                       chip->ecc.strength = 1;
                } else {
                        /* otherwise fall back to default software ECC */
                        chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
                        chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
                }
+       }
+
+       switch (chip->ecc.engine_type) {
+       /* if HW ECC was chosen, setup ecc and oob layout */
+       case NAND_ECC_ENGINE_TYPE_ON_HOST:
+               chip->ecc.read_page = fsl_elbc_read_page;
+               chip->ecc.write_page = fsl_elbc_write_page;
+               chip->ecc.write_subpage = fsl_elbc_write_subpage;
+               mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
+               chip->ecc.size = 512;
+               chip->ecc.bytes = 3;
+               chip->ecc.strength = 1;
                break;
 
-       /* if SW ECC was chosen in DT, we do not need to set anything here */
+       /* if none or SW ECC was chosen, we do not need to set anything here */
+       case NAND_ECC_ENGINE_TYPE_NONE:
        case NAND_ECC_ENGINE_TYPE_SOFT:
+       case NAND_ECC_ENGINE_TYPE_ON_DIE:
                break;
 
-       /* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */
        default:
                return -EINVAL;
        }
index 93da236..01ccbde 100644 (file)
@@ -1361,7 +1361,7 @@ error_alloc:
 /*
  * Handles block mark swapping.
  * It can be called in swapping the block mark, or swapping it back,
- * because the the operations are the same.
+ * because the operations are the same.
  */
 static void block_mark_swapping(struct gpmi_nand_data *this,
                                void *payload, void *auxiliary)
index e91b879..d4a0987 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/nand.h>
 
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 
 #define HSNAND_ECC_OFFSET      0x008
 
-#define NAND_DATA_IFACE_CHECK_ONLY     -1
-
 #define MAX_CS 2
 
 #define USEC_PER_SEC   1000000L
 
 struct ebu_nand_cs {
        void __iomem *chipaddr;
-       dma_addr_t nand_pa;
        u32 addr_sel;
 };
 
@@ -120,7 +118,6 @@ struct ebu_nand_controller {
        struct dma_chan *dma_tx;
        struct dma_chan *dma_rx;
        struct completion dma_access_complete;
-       unsigned long clk_rate;
        struct clk *clk;
        u32 nd_para0;
        u8 cs_num;
@@ -580,6 +577,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct ebu_nand_controller *ebu_host;
+       struct device_node *chip_np;
        struct nand_chip *nand;
        struct mtd_info *mtd;
        struct resource *res;
@@ -594,17 +592,20 @@ static int ebu_nand_probe(struct platform_device *pdev)
        ebu_host->dev = dev;
        nand_controller_init(&ebu_host->controller);
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebunand");
-       ebu_host->ebu = devm_ioremap_resource(&pdev->dev, res);
+       ebu_host->ebu = devm_platform_ioremap_resource_byname(pdev, "ebunand");
        if (IS_ERR(ebu_host->ebu))
                return PTR_ERR(ebu_host->ebu);
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsnand");
-       ebu_host->hsnand = devm_ioremap_resource(&pdev->dev, res);
+       ebu_host->hsnand = devm_platform_ioremap_resource_byname(pdev, "hsnand");
        if (IS_ERR(ebu_host->hsnand))
                return PTR_ERR(ebu_host->hsnand);
 
-       ret = device_property_read_u32(dev, "reg", &cs);
+       chip_np = of_get_next_child(dev->of_node, NULL);
+       if (!chip_np)
+               return dev_err_probe(dev, -EINVAL,
+                                    "Could not find child node for the NAND chip\n");
+
+       ret = of_property_read_u32(chip_np, "reg", &cs);
        if (ret) {
                dev_err(dev, "failed to get chip select: %d\n", ret);
                return ret;
@@ -617,11 +618,10 @@ static int ebu_nand_probe(struct platform_device *pdev)
        ebu_host->cs_num = cs;
 
        resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
-       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
-       ebu_host->cs[cs].chipaddr = devm_ioremap_resource(dev, res);
+       ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
+                                                                         resname);
        if (IS_ERR(ebu_host->cs[cs].chipaddr))
                return PTR_ERR(ebu_host->cs[cs].chipaddr);
-       ebu_host->cs[cs].nand_pa = res->start;
 
        ebu_host->clk = devm_clk_get(dev, NULL);
        if (IS_ERR(ebu_host->clk))
@@ -633,7 +633,6 @@ static int ebu_nand_probe(struct platform_device *pdev)
                dev_err(dev, "failed to enable clock: %d\n", ret);
                return ret;
        }
-       ebu_host->clk_rate = clk_get_rate(ebu_host->clk);
 
        ebu_host->dma_tx = dma_request_chan(dev, "tx");
        if (IS_ERR(ebu_host->dma_tx)) {
@@ -660,7 +659,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
        writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
               ebu_host->ebu + EBU_ADDR_SEL(cs));
 
-       nand_set_flash_node(&ebu_host->chip, dev->of_node);
+       nand_set_flash_node(&ebu_host->chip, chip_np);
 
        mtd = nand_to_mtd(&ebu_host->chip);
        if (!mtd->name) {
@@ -716,7 +715,6 @@ static int ebu_nand_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id ebu_nand_match[] = {
-       { .compatible = "intel,nand-controller" },
        { .compatible = "intel,lgm-ebunand" },
        {}
 };
index 2455a58..d9f2f1d 100644 (file)
@@ -865,13 +865,19 @@ static int marvell_nfc_xfer_data_dma(struct marvell_nfc *nfc,
        marvell_nfc_enable_dma(nfc);
        /* Prepare the DMA transfer */
        sg_init_one(&sg, nfc->dma_buf, dma_len);
-       dma_map_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+       ret = dma_map_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
+       if (!ret) {
+               dev_err(nfc->dev, "Could not map DMA S/G list\n");
+               return -ENXIO;
+       }
+
        tx = dmaengine_prep_slave_sg(nfc->dma_chan, &sg, 1,
                                     direction == DMA_FROM_DEVICE ?
                                     DMA_DEV_TO_MEM : DMA_MEM_TO_DEV,
                                     DMA_PREP_INTERRUPT);
        if (!tx) {
                dev_err(nfc->dev, "Could not prepare DMA S/G list\n");
+               dma_unmap_sg(nfc->dma_chan->device->dev, &sg, 1, direction);
                return -ENXIO;
        }
 
index 829b76b..5ee0123 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mfd/syscon.h>
@@ -56,6 +57,9 @@
 
 #define NFC_RB_IRQ_EN          BIT(21)
 
+#define CLK_DIV_SHIFT          0
+#define CLK_DIV_WIDTH          6
+
 #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)      \
        (                                                               \
                (cmd_dir)                       |                       \
@@ -151,15 +155,15 @@ struct meson_nfc {
        struct nand_controller controller;
        struct clk *core_clk;
        struct clk *device_clk;
-       struct clk *phase_tx;
-       struct clk *phase_rx;
+       struct clk *nand_clk;
+       struct clk_divider nand_divider;
 
        unsigned long clk_rate;
        u32 bus_timing;
 
        struct device *dev;
        void __iomem *reg_base;
-       struct regmap *reg_clk;
+       void __iomem *reg_clk;
        struct completion completion;
        struct list_head chips;
        const struct meson_nfc_data *data;
@@ -235,7 +239,7 @@ static void meson_nfc_select_chip(struct nand_chip *nand, int chip)
        nfc->timing.tbers_max = meson_chip->tbers_max;
 
        if (nfc->clk_rate != meson_chip->clk_rate) {
-               ret = clk_set_rate(nfc->device_clk, meson_chip->clk_rate);
+               ret = clk_set_rate(nfc->nand_clk, meson_chip->clk_rate);
                if (ret) {
                        dev_err(nfc->dev, "failed to set clock rate\n");
                        return;
@@ -454,7 +458,7 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips,
                if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) {
                        mtd->ecc_stats.corrected += ECC_ERR_CNT(*info);
                        *bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info));
-                       *correct_bitmap |= 1 >> i;
+                       *correct_bitmap |= BIT_ULL(i);
                        continue;
                }
                if ((nand->options & NAND_NEED_SCRAMBLING) &&
@@ -800,7 +804,7 @@ static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf,
                        u8 *data = buf + i * ecc->size;
                        u8 *oob = nand->oob_poi + i * (ecc->bytes + 2);
 
-                       if (correct_bitmap & (1 << i))
+                       if (correct_bitmap & BIT_ULL(i))
                                continue;
                        ret = nand_check_erased_ecc_chunk(data, ecc->size,
                                                          oob, ecc->bytes + 2,
@@ -987,6 +991,8 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
 
 static int meson_nfc_clk_init(struct meson_nfc *nfc)
 {
+       struct clk_parent_data nfc_divider_parent_data[1];
+       struct clk_init_data init = {0};
        int ret;
 
        /* request core clock */
@@ -1002,21 +1008,28 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
                return PTR_ERR(nfc->device_clk);
        }
 
-       nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
-       if (IS_ERR(nfc->phase_tx)) {
-               dev_err(nfc->dev, "failed to get TX clk\n");
-               return PTR_ERR(nfc->phase_tx);
-       }
-
-       nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
-       if (IS_ERR(nfc->phase_rx)) {
-               dev_err(nfc->dev, "failed to get RX clk\n");
-               return PTR_ERR(nfc->phase_rx);
-       }
+       init.name = devm_kasprintf(nfc->dev,
+                                  GFP_KERNEL, "%s#div",
+                                  dev_name(nfc->dev));
+       init.ops = &clk_divider_ops;
+       nfc_divider_parent_data[0].fw_name = "device";
+       init.parent_data = nfc_divider_parent_data;
+       init.num_parents = 1;
+       nfc->nand_divider.reg = nfc->reg_clk;
+       nfc->nand_divider.shift = CLK_DIV_SHIFT;
+       nfc->nand_divider.width = CLK_DIV_WIDTH;
+       nfc->nand_divider.hw.init = &init;
+       nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
+                                 CLK_DIVIDER_ROUND_CLOSEST |
+                                 CLK_DIVIDER_ALLOW_ZERO;
+
+       nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
+       if (IS_ERR(nfc->nand_clk))
+               return PTR_ERR(nfc->nand_clk);
 
        /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
-       regmap_update_bits(nfc->reg_clk,
-                          0, CLK_SELECT_NAND, CLK_SELECT_NAND);
+       writel(CLK_SELECT_NAND | readl(nfc->reg_clk),
+              nfc->reg_clk);
 
        ret = clk_prepare_enable(nfc->core_clk);
        if (ret) {
@@ -1030,29 +1043,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
                goto err_device_clk;
        }
 
-       ret = clk_prepare_enable(nfc->phase_tx);
+       ret = clk_prepare_enable(nfc->nand_clk);
        if (ret) {
-               dev_err(nfc->dev, "failed to enable TX clock\n");
-               goto err_phase_tx;
+               dev_err(nfc->dev, "pre enable NFC divider fail\n");
+               goto err_nand_clk;
        }
 
-       ret = clk_prepare_enable(nfc->phase_rx);
-       if (ret) {
-               dev_err(nfc->dev, "failed to enable RX clock\n");
-               goto err_phase_rx;
-       }
-
-       ret = clk_set_rate(nfc->device_clk, 24000000);
+       ret = clk_set_rate(nfc->nand_clk, 24000000);
        if (ret)
-               goto err_disable_rx;
+               goto err_disable_clk;
 
        return 0;
 
-err_disable_rx:
-       clk_disable_unprepare(nfc->phase_rx);
-err_phase_rx:
-       clk_disable_unprepare(nfc->phase_tx);
-err_phase_tx:
+err_disable_clk:
+       clk_disable_unprepare(nfc->nand_clk);
+err_nand_clk:
        clk_disable_unprepare(nfc->device_clk);
 err_device_clk:
        clk_disable_unprepare(nfc->core_clk);
@@ -1061,8 +1066,7 @@ err_device_clk:
 
 static void meson_nfc_disable_clk(struct meson_nfc *nfc)
 {
-       clk_disable_unprepare(nfc->phase_rx);
-       clk_disable_unprepare(nfc->phase_tx);
+       clk_disable_unprepare(nfc->nand_clk);
        clk_disable_unprepare(nfc->device_clk);
        clk_disable_unprepare(nfc->core_clk);
 }
@@ -1368,7 +1372,6 @@ static int meson_nfc_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct meson_nfc *nfc;
-       struct resource *res;
        int ret, irq;
 
        nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
@@ -1385,18 +1388,13 @@ static int meson_nfc_probe(struct platform_device *pdev)
 
        nfc->dev = dev;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       nfc->reg_base = devm_ioremap_resource(dev, res);
+       nfc->reg_base = devm_platform_ioremap_resource_byname(pdev, "nfc");
        if (IS_ERR(nfc->reg_base))
                return PTR_ERR(nfc->reg_base);
 
-       nfc->reg_clk =
-               syscon_regmap_lookup_by_phandle(dev->of_node,
-                                               "amlogic,mmc-syscon");
-       if (IS_ERR(nfc->reg_clk)) {
-               dev_err(dev, "Failed to lookup clock base\n");
+       nfc->reg_clk = devm_platform_ioremap_resource_byname(pdev, "emmc");
+       if (IS_ERR(nfc->reg_clk))
                return PTR_ERR(nfc->reg_clk);
-       }
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
index 3e20de1..33f2c98 100644 (file)
@@ -335,8 +335,6 @@ static int nand_isbad_bbm(struct nand_chip *chip, loff_t ofs)
  * @chip: NAND chip structure
  *
  * Lock the device and its controller for exclusive access
- *
- * Return: -EBUSY if the chip has been suspended, 0 otherwise
  */
 static void nand_get_device(struct nand_chip *chip)
 {
@@ -5341,11 +5339,10 @@ static int of_get_nand_secure_regions(struct nand_chip *chip)
 int rawnand_dt_parse_gpio_cs(struct device *dev, struct gpio_desc ***cs_array,
                             unsigned int *ncs_array)
 {
-       struct device_node *np = dev->of_node;
        struct gpio_desc **descs;
        int ndescs, i;
 
-       ndescs = of_gpio_named_count(np, "cs-gpios");
+       ndescs = gpiod_count(dev, "cs");
        if (ndescs < 0) {
                dev_dbg(dev, "No valid cs-gpios property\n");
                return 0;
index 2c87c7d..1bfecf5 100644 (file)
@@ -170,18 +170,11 @@ static int __init orion_nand_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, info);
 
-       /* Not all platforms can gate the clock, so it is not
-          an error if the clock does not exists. */
-       info->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(info->clk)) {
-               ret = PTR_ERR(info->clk);
-               if (ret == -ENOENT) {
-                       info->clk = NULL;
-               } else {
-                       dev_err(&pdev->dev, "failed to get clock!\n");
-                       return ret;
-               }
-       }
+       /* Not all platforms can gate the clock, so it is optional. */
+       info->clk = devm_clk_get_optional(&pdev->dev, NULL);
+       if (IS_ERR(info->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
+                                    "failed to get clock!\n");
 
        ret = clk_prepare_enable(info->clk);
        if (ret) {
index 87c1c7d..5d62704 100644 (file)
@@ -862,8 +862,8 @@ static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf,
 
        ret = dma_map_sg(nfc->dev, nfc->dma_data_sg.sgl,
                         eccsteps, dma_data_dir);
-       if (ret < 0)
-               return ret;
+       if (!ret)
+               return -EIO;
 
        desc_data = dmaengine_prep_slave_sg(dma_ch, nfc->dma_data_sg.sgl,
                                            eccsteps, dma_transfer_dir,
@@ -893,8 +893,10 @@ static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf,
 
                ret = dma_map_sg(nfc->dev, nfc->dma_ecc_sg.sgl,
                                 eccsteps, dma_data_dir);
-               if (ret < 0)
+               if (!ret) {
+                       ret = -EIO;
                        goto err_unmap_data;
+               }
 
                desc_ecc = dmaengine_prep_slave_sg(nfc->dma_ecc_ch,
                                                   nfc->dma_ecc_sg.sgl,
@@ -1799,9 +1801,8 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
                nand->cs_used[i] = cs;
        }
 
-       nand->wp_gpio = devm_gpiod_get_from_of_node(nfc->dev, dn,
-                                                   "wp-gpios", 0,
-                                                   GPIOD_OUT_HIGH, "wp");
+       nand->wp_gpio = devm_fwnode_gpiod_get(nfc->dev, of_fwnode_handle(dn),
+                                             "wp", GPIOD_OUT_HIGH, "wp");
        if (IS_ERR(nand->wp_gpio)) {
                ret = PTR_ERR(nand->wp_gpio);
                if (ret != -ENOENT)