Commit 63c30d70 authored by Miquel Raynal's avatar Miquel Raynal

Merge tag 'nand/for-6.1' into mtd/next

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: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parents 095bb6e4 ba47a6ac
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;
};
};
# 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>;
};
};
...
# 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>,
......
......@@ -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);
......
......@@ -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.
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
......
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
# 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
......@@ -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,
......
......@@ -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
......
......@@ -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;
}
......
......@@ -1361,7 +1361,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this)
/*
* 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)
......
......@@ -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>
......@@ -99,15 +100,12 @@
#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" },
{}
};
......
......@@ -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;
}
......
......@@ -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 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
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)
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment