Skip to content

Commit

Permalink
Merge tag 'nand/for-5.18' into mtd/next
Browse files Browse the repository at this point in the history
Raw NAND core changes:
* Rework of_get_nand_bus_width()
* Remove of_get_nand_on_flash_bbt() wrapper
* Protect access to rawnand devices while in suspend
* bindings: Document the wp-gpios property

Rax NAND controller driver changes:
* atmel: Fix refcount issue in atmel_nand_controller_init
* nandsim:
  - Add NS_PAGE_BYTE_SHIFT macro to replace the repeat pattern
  - Merge repeat codes in ns_switch_state
  - Replace overflow check with kzalloc to single kcalloc
* rockchip: Fix platform_get_irq.cocci warning
* stm32_fmc2: Add NAND Write Protect support
* pl353: Set the nand chip node as the flash node
* brcmnand: Fix sparse warnings in bcma_nand
* omap_elm: Remove redundant variable 'errors'
* gpmi:
  - Support fast edo timings for mx28
  - Validate controller clock rate
  - Fix controller timings setting
* brcmnand:
  - Add BCMA shim
  - BCMA controller uses command shift of 0
  - Allow platform data instantation
  - Add platform data structure for BCMA
  - Allow working without interrupts
  - Move OF operations out of brcmnand_init_cs()
  - Avoid pdev in brcmnand_init_cs()
  - Allow SoC to provide I/O operations
  - Assign soc as early as possible

Onenand changes:
* Check for error irq

Signed-off-by: Miquel Raynal <[email protected]>
  • Loading branch information
miquelraynal committed Mar 23, 2022
2 parents 4e371d9 + fecbd4a commit 6cadd42
Show file tree
Hide file tree
Showing 20 changed files with 467 additions and 139 deletions.
7 changes: 7 additions & 0 deletions Documentation/devicetree/bindings/mtd/nand-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ patternProperties:
Ready/Busy pins. Active state refers to the NAND ready state and
should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted.

wp-gpios:
description:
Contains one GPIO descriptor for the Write Protect pin.
Active state refers to the NAND Write Protect state and should be
set to GPIOD_ACTIVE_LOW unless the signal is inverted.
maxItems: 1

required:
- reg

Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -4026,6 +4026,7 @@ L: [email protected]
L: [email protected]
S: Maintained
F: drivers/mtd/nand/raw/brcmnand/
F: include/linux/platform_data/brcmnand.h

BROADCOM STB PCIE DRIVER
M: Jim Quinlan <[email protected]>
Expand Down
20 changes: 19 additions & 1 deletion drivers/bcma/driver_chipcommon_nflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@

#include "bcma_private.h"

#include <linux/bitops.h>
#include <linux/platform_device.h>
#include <linux/platform_data/brcmnand.h>
#include <linux/bcma/bcma.h>

/* Alternate NAND controller driver name in order to allow both bcm47xxnflash
* and bcma_brcmnand to be built into the same kernel image.
*/
static const char *bcma_nflash_alt_name = "bcma_brcmnand";

struct platform_device bcma_nflash_dev = {
.name = "bcma_nflash",
.num_resources = 0,
};

static const char *probes[] = { "bcm47xxpart", NULL };

/* Initialize NAND flash access */
int bcma_nflash_init(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
u32 reg;

if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
cc->core->id.rev != 38) {
Expand All @@ -33,8 +43,16 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)

cc->nflash.present = true;
if (cc->core->id.rev == 38 &&
(cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT))
(cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) {
cc->nflash.boot = true;
/* Determine the chip select that is being used */
reg = bcma_cc_read32(cc, BCMA_CC_NAND_CS_NAND_SELECT) & 0xff;
cc->nflash.brcmnand_info.chip_select = ffs(reg) - 1;
cc->nflash.brcmnand_info.part_probe_types = probes;
cc->nflash.brcmnand_info.ecc_stepsize = 512;
cc->nflash.brcmnand_info.ecc_strength = 1;
bcma_nflash_dev.name = bcma_nflash_alt_name;
}

/* Prepare platform device, but don't register it yet. It's too early,
* malloc (required by device_private_init) is not available yet. */
Expand Down
7 changes: 6 additions & 1 deletion drivers/mtd/nand/onenand/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ static int generic_onenand_probe(struct platform_device *pdev)
}

info->onenand.mmcontrol = pdata ? pdata->mmcontrol : NULL;
info->onenand.irq = platform_get_irq(pdev, 0);

err = platform_get_irq(pdev, 0);
if (err < 0)
goto out_iounmap;

info->onenand.irq = err;

info->mtd.dev.parent = &pdev->dev;
info->mtd.priv = &info->onenand;
Expand Down
13 changes: 13 additions & 0 deletions drivers/mtd/nand/raw/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,19 @@ config MTD_NAND_BRCMNAND
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

config MTD_NAND_BCM47XXNFLASH
tristate "BCM4706 BCMA NAND controller"
depends on BCMA_NFLASH
Expand Down
14 changes: 11 additions & 3 deletions drivers/mtd/nand/raw/atmel/nand-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -2060,24 +2060,32 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
nc->mck = of_clk_get(dev->parent->of_node, 0);
if (IS_ERR(nc->mck)) {
dev_err(dev, "Failed to retrieve MCK clk\n");
return PTR_ERR(nc->mck);
ret = PTR_ERR(nc->mck);
goto out_release_dma;
}

np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0);
if (!np) {
dev_err(dev, "Missing or invalid atmel,smc property\n");
return -EINVAL;
ret = -EINVAL;
goto out_release_dma;
}

nc->smc = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR(nc->smc)) {
ret = PTR_ERR(nc->smc);
dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret);
return ret;
goto out_release_dma;
}

return 0;

out_release_dma:
if (nc->dmac)
dma_release_channel(nc->dmac);

return ret;
}

static int
Expand Down
2 changes: 2 additions & 0 deletions drivers/mtd/nand/raw/brcmnand/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ 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) += brcmnand.o

obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA) += bcma_nand.o
132 changes: 132 additions & 0 deletions drivers/mtd/nand/raw/brcmnand/bcma_nand.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright © 2021 Broadcom
*/
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_driver_chipcommon.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include "brcmnand.h"

struct brcmnand_bcma_soc {
struct brcmnand_soc soc;
struct bcma_drv_cc *cc;
};

static inline bool brcmnand_bcma_needs_swapping(u32 offset)
{
switch (offset) {
case BCMA_CC_NAND_SPARE_RD0:
case BCMA_CC_NAND_SPARE_RD4:
case BCMA_CC_NAND_SPARE_RD8:
case BCMA_CC_NAND_SPARE_RD12:
case BCMA_CC_NAND_SPARE_WR0:
case BCMA_CC_NAND_SPARE_WR4:
case BCMA_CC_NAND_SPARE_WR8:
case BCMA_CC_NAND_SPARE_WR12:
case BCMA_CC_NAND_DEVID:
case BCMA_CC_NAND_DEVID_X:
case BCMA_CC_NAND_SPARE_RD16:
case BCMA_CC_NAND_SPARE_RD20:
case BCMA_CC_NAND_SPARE_RD24:
case BCMA_CC_NAND_SPARE_RD28:
return true;
}

return false;
}

static inline struct brcmnand_bcma_soc *to_bcma_soc(struct brcmnand_soc *soc)
{
return container_of(soc, struct brcmnand_bcma_soc, soc);
}

static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset)
{
struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
u32 val;

/* Offset into the NAND block and deal with the flash cache separately */
if (offset == BRCMNAND_NON_MMIO_FC_ADDR)
offset = BCMA_CC_NAND_CACHE_DATA;
else
offset += BCMA_CC_NAND_REVISION;

val = bcma_cc_read32(sc->cc, offset);

/* Swap if necessary */
if (brcmnand_bcma_needs_swapping(offset))
val = be32_to_cpu((__force __be32)val);
return val;
}

static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val,
u32 offset)
{
struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);

/* Offset into the NAND block */
if (offset == BRCMNAND_NON_MMIO_FC_ADDR)
offset = BCMA_CC_NAND_CACHE_DATA;
else
offset += BCMA_CC_NAND_REVISION;

/* Swap if necessary */
if (brcmnand_bcma_needs_swapping(offset))
val = (__force u32)cpu_to_be32(val);

bcma_cc_write32(sc->cc, offset, val);
}

static struct brcmnand_io_ops brcmnand_bcma_io_ops = {
.read_reg = brcmnand_bcma_read_reg,
.write_reg = brcmnand_bcma_write_reg,
};

static void brcmnand_bcma_prepare_data_bus(struct brcmnand_soc *soc, bool prepare,
bool is_param)
{
struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);

/* Reset the cache address to ensure we are already accessing the
* beginning of a sub-page.
*/
bcma_cc_write32(sc->cc, BCMA_CC_NAND_CACHE_ADDR, 0);
}

static int brcmnand_bcma_nand_probe(struct platform_device *pdev)
{
struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
struct brcmnand_bcma_soc *soc;

soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
if (!soc)
return -ENOMEM;

soc->cc = container_of(nflash, struct bcma_drv_cc, nflash);
soc->soc.prepare_data_bus = brcmnand_bcma_prepare_data_bus;
soc->soc.ops = &brcmnand_bcma_io_ops;

if (soc->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
dev_err(&pdev->dev, "Use bcm47xxnflash for 4706!\n");
return -ENODEV;
}

return brcmnand_probe(pdev, &soc->soc);
}

static struct platform_driver brcmnand_bcma_nand_driver = {
.probe = brcmnand_bcma_nand_probe,
.remove = brcmnand_remove,
.driver = {
.name = "bcma_brcmnand",
.pm = &brcmnand_pm_ops,
}
};
module_platform_driver(brcmnand_bcma_nand_driver);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Broadcom");
MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips");
Loading

0 comments on commit 6cadd42

Please sign in to comment.