Commit 9ce47e43 authored by Miquel Raynal's avatar Miquel Raynal

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

Raw NAND core:
* Export nand_read_page_hwecc_oob_first()

GPMC memory controller for OMAP2 NAND controller:
* GPMC:
  - Add support for AM64 SoC and allow build on K3 platforms
  - Use a compatible match table when checking for NAND controller
  - Use platform_get_irq() to get the interrupt

Raw NAND controller drivers:
* OMAP2 NAND controller:
  - Document the missing 'rb-gpios' DT property
  - Drop unused variable
  - Fix force_8bit flag behaviour for DMA mode
  - Move to exec_op interface
  - Use platform_get_irq() to get the interrupt
* Renesas:
  - Add new NAND controller driver with its bindings and MAINTAINERS entry
* Onenand:
  - Remove redundant variable ooblen
* MPC5121:
  - Remove unused variable in ads5121_select_chip()
* GPMI:
  - Add ERR007117 protection for nfc_apply_timings
  - Remove explicit default gpmi clock setting for i.MX6
  - Use platform_get_irq_byname() to get the interrupt
  - Remove unneeded variable
* Ingenic:
  - JZ4740 needs 'oob_first' read page function
* Davinci:
  - Rewrite function description
  - Avoid duplicated page read
  - Don't calculate ECC when reading page
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parents bee38713 2997e487
......@@ -23,13 +23,20 @@ properties:
items:
- enum:
- ti,am3352-gpmc
- ti,am64-gpmc
- ti,omap2420-gpmc
- ti,omap2430-gpmc
- ti,omap3430-gpmc
- ti,omap4430-gpmc
reg:
maxItems: 1
minItems: 1
maxItems: 2
reg-names:
items:
- const: cfg
- const: data
interrupts:
maxItems: 1
......@@ -44,6 +51,9 @@ properties:
items:
- const: fck
power-domains:
maxItems: 1
dmas:
items:
- description: DMA channel for GPMC NAND prefetch
......@@ -133,6 +143,17 @@ required:
- "#address-cells"
- "#size-cells"
allOf:
- if:
properties:
compatible:
contains:
const: ti,am64-gpmc
then:
required:
- reg-names
- power-domains
additionalProperties: false
examples:
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mtd/renesas-nandc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R-Car Gen3 & RZ/N1x NAND flash controller device tree bindings
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
allOf:
- $ref: "nand-controller.yaml"
properties:
compatible:
oneOf:
- items:
- enum:
- renesas,r9a06g032-nandc
- const: renesas,rzn1-nandc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: APB host controller clock
- description: External NAND bus clock
clock-names:
items:
- const: hclk
- const: eclk
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/r9a06g032-sysctrl.h>
nand-controller@40102000 {
compatible = "renesas,r9a06g032-nandc", "renesas,rzn1-nandc";
reg = <0x40102000 0x2000>;
interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sysctrl R9A06G032_HCLK_NAND>, <&sysctrl R9A06G032_CLK_NAND>;
clock-names = "hclk", "eclk";
#address-cells = <1>;
#size-cells = <0>;
};
......@@ -16,7 +16,10 @@ description:
properties:
compatible:
const: ti,omap2-nand
items:
- enum:
- ti,am64-nand
- ti,omap2-nand
reg:
maxItems: 1
......@@ -53,6 +56,11 @@ properties:
enum: [8, 16]
default: 8
rb-gpios:
description:
GPIO connection to R/B signal from NAND chip
maxItems: 1
patternProperties:
"@[0-9a-f]+$":
$ref: "/schemas/mtd/partitions/partition.yaml"
......
......@@ -16275,6 +16275,14 @@ S: Supported
F: Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml
F: drivers/iio/adc/rzg2l_adc.c
RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER
M: Miquel Raynal <miquel.raynal@bootlin.com>
L: linux-mtd@lists.infradead.org
L: linux-renesas-soc@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
F: drivers/mtd/nand/raw/renesas-nand-controller.c
RESET CONTROLLER FRAMEWORK
M: Philipp Zabel <p.zabel@pengutronix.de>
S: Maintained
......
......@@ -237,6 +237,7 @@ struct gpmc_device {
struct omap3_gpmc_regs context;
int nirqs;
unsigned int is_suspended:1;
struct resource *data;
};
static struct irq_domain *gpmc_irq_domain;
......@@ -1456,12 +1457,18 @@ static void gpmc_mem_exit(void)
}
}
static void gpmc_mem_init(void)
static void gpmc_mem_init(struct gpmc_device *gpmc)
{
int cs;
gpmc_mem_root.start = GPMC_MEM_START;
gpmc_mem_root.end = GPMC_MEM_END;
if (!gpmc->data) {
/* All legacy devices have same data IO window */
gpmc_mem_root.start = GPMC_MEM_START;
gpmc_mem_root.end = GPMC_MEM_END;
} else {
gpmc_mem_root.start = gpmc->data->start;
gpmc_mem_root.end = gpmc->data->end;
}
/* Reserve all regions that has been set up by bootloader */
for (cs = 0; cs < gpmc_cs_num; cs++) {
......@@ -1888,6 +1895,7 @@ static const struct of_device_id gpmc_dt_ids[] = {
{ .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
{ .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
{ .compatible = "ti,am3352-gpmc" }, /* am335x devices */
{ .compatible = "ti,am64-gpmc" },
{ }
};
......@@ -2175,7 +2183,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
}
}
if (of_device_is_compatible(child, "ti,omap2-nand")) {
if (of_match_node(omap_nand_ids, child)) {
/* NAND specific setup */
val = 8;
of_property_read_u32(child, "nand-bus-width", &val);
......@@ -2502,21 +2510,29 @@ static int gpmc_probe(struct platform_device *pdev)
gpmc->dev = &pdev->dev;
platform_set_drvdata(pdev, gpmc);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
gpmc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(gpmc_base))
return PTR_ERR(gpmc_base);
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
if (!res) {
dev_err(&pdev->dev, "Failed to get resource: irq\n");
return -ENOENT;
/* legacy DT */
gpmc_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(gpmc_base))
return PTR_ERR(gpmc_base);
} else {
gpmc_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(gpmc_base))
return PTR_ERR(gpmc_base);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "data");
if (!res) {
dev_err(&pdev->dev, "couldn't get data reg resource\n");
return -ENOENT;
}
gpmc->data = res;
}
gpmc->irq = res->start;
gpmc->irq = platform_get_irq(pdev, 0);
if (gpmc->irq < 0)
return gpmc->irq;
gpmc_l3_clk = devm_clk_get(&pdev->dev, "fck");
if (IS_ERR(gpmc_l3_clk)) {
......@@ -2562,7 +2578,7 @@ static int gpmc_probe(struct platform_device *pdev)
dev_info(gpmc->dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
GPMC_REVISION_MINOR(l));
gpmc_mem_init();
gpmc_mem_init(gpmc);
rc = gpmc_gpio_init(gpmc);
if (rc)
goto gpio_init_failed;
......
......@@ -60,7 +60,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
int i, j, numblocks, len, scanlen;
int startblock;
loff_t from;
size_t readlen, ooblen;
size_t readlen;
struct mtd_oob_ops ops;
int rgn;
......@@ -69,7 +69,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
len = 2;
/* We need only read few bytes from the OOB area */
scanlen = ooblen = 0;
scanlen = 0;
readlen = bd->len;
/* chip == -1 case only */
......
......@@ -40,8 +40,9 @@ config MTD_NAND_AMS_DELTA
config MTD_NAND_OMAP2
tristate "OMAP2, OMAP3, OMAP4 and Keystone NAND controller"
depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST
depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
depends on HAS_IOMEM
select OMAP_GPMC if ARCH_K3
help
Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4
and Keystone platforms.
......@@ -461,6 +462,13 @@ config MTD_NAND_PL35X
Enables support for PrimeCell SMC PL351 and PL353 NAND
controller found on Zynq7000.
config MTD_NAND_RENESAS
tristate "Renesas R-Car Gen3 & RZ/N1 NAND controller"
depends on ARCH_RENESAS || COMPILE_TEST
help
Enables support for the NAND controller found on Renesas R-Car
Gen3 and RZ/N1 SoC families.
comment "Misc"
config MTD_SM_COMMON
......
......@@ -58,6 +58,7 @@ obj-$(CONFIG_MTD_NAND_ARASAN) += arasan-nand-controller.o
obj-$(CONFIG_MTD_NAND_INTEL_LGM) += intel-nand-controller.o
obj-$(CONFIG_MTD_NAND_ROCKCHIP) += rockchip-nand-controller.o
obj-$(CONFIG_MTD_NAND_PL35X) += pl35x-nand-controller.o
obj-$(CONFIG_MTD_NAND_RENESAS) += renesas-nand-controller.o
nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
nand-objs += nand_onfi.o
......
......@@ -371,77 +371,6 @@ static int nand_davinci_correct_4bit(struct nand_chip *chip, u_char *data,
return corrected;
}
/**
* nand_read_page_hwecc_oob_first - hw ecc, read oob first
* @chip: nand chip info structure
* @buf: buffer to store read data
* @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* Hardware ECC for large page chips, require OOB to be read first. For this
* ECC mode, the write_page method is re-used from ECC_HW. These methods
* read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with
* multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from
* the data area, by overwriting the NAND manufacturer bad block markings.
*/
static int nand_davinci_read_page_hwecc_oob_first(struct nand_chip *chip,
uint8_t *buf,
int oob_required, int page)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int i, eccsize = chip->ecc.size, ret;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
uint8_t *p = buf;
uint8_t *ecc_code = chip->ecc.code_buf;
uint8_t *ecc_calc = chip->ecc.calc_buf;
unsigned int max_bitflips = 0;
/* Read the OOB area first */
ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
if (ret)
return ret;
ret = nand_read_page_op(chip, page, 0, NULL, 0);
if (ret)
return ret;
ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
chip->ecc.total);
if (ret)
return ret;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
int stat;
chip->ecc.hwctl(chip, NAND_ECC_READ);
ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret)
return ret;
chip->ecc.calculate(chip, p, &ecc_calc[i]);
stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL);
if (stat == -EBADMSG &&
(chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
/* check for empty pages with bitflips */
stat = nand_check_erased_ecc_chunk(p, eccsize,
&ecc_code[i],
eccbytes, NULL, 0,
chip->ecc.strength);
}
if (stat < 0) {
mtd->ecc_stats.failed++;
} else {
mtd->ecc_stats.corrected += stat;
max_bitflips = max_t(unsigned int, max_bitflips, stat);
}
}
return max_bitflips;
}
/*----------------------------------------------------------------------*/
/* An ECC layout for using 4-bit ECC with small-page flash, storing
......@@ -651,7 +580,7 @@ static int davinci_nand_attach_chip(struct nand_chip *chip)
} else if (chunks == 4 || chunks == 8) {
mtd_set_ooblayout(mtd,
nand_get_large_page_ooblayout());
chip->ecc.read_page = nand_davinci_read_page_hwecc_oob_first;
chip->ecc.read_page = nand_read_page_hwecc_oob_first;
} else {
return -EIO;
}
......
......@@ -713,14 +713,32 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this,
(use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0);
}
static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
static int gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
{
struct gpmi_nfc_hardware_timing *hw = &this->hw;
struct resources *r = &this->resources;
void __iomem *gpmi_regs = r->gpmi_regs;
unsigned int dll_wait_time_us;
int ret;
/* Clock dividers do NOT guarantee a clean clock signal on its output
* during the change of the divide factor on i.MX6Q/UL/SX. On i.MX7/8,
* all clock dividers provide these guarantee.
*/
if (GPMI_IS_MX6Q(this) || GPMI_IS_MX6SX(this))
clk_disable_unprepare(r->clock[0]);
clk_set_rate(r->clock[0], hw->clk_rate);
ret = clk_set_rate(r->clock[0], hw->clk_rate);
if (ret) {
dev_err(this->dev, "cannot set clock rate to %lu Hz: %d\n", hw->clk_rate, ret);
return ret;
}
if (GPMI_IS_MX6Q(this) || GPMI_IS_MX6SX(this)) {
ret = clk_prepare_enable(r->clock[0]);
if (ret)
return ret;
}
writel(hw->timing0, gpmi_regs + HW_GPMI_TIMING0);
writel(hw->timing1, gpmi_regs + HW_GPMI_TIMING1);
......@@ -739,6 +757,8 @@ static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this)
/* Wait for the DLL to settle. */
udelay(dll_wait_time_us);
return 0;
}
static int gpmi_setup_interface(struct nand_chip *chip, int chipnr,
......@@ -971,16 +991,13 @@ static int acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h)
{
struct platform_device *pdev = this->pdev;
const char *res_name = GPMI_NAND_BCH_INTERRUPT_RES_NAME;
struct resource *r;
int err;
r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
if (!r) {
dev_err(this->dev, "Can't get resource for %s\n", res_name);
return -ENODEV;
}
err = platform_get_irq_byname(pdev, res_name);
if (err < 0)
return err;
err = devm_request_irq(this->dev, r->start, irq_h, 0, res_name, this);
err = devm_request_irq(this->dev, err, irq_h, 0, res_name, this);
if (err)
dev_err(this->dev, "error requesting BCH IRQ\n");
......@@ -1032,15 +1049,6 @@ static int gpmi_get_clks(struct gpmi_nand_data *this)
r->clock[i] = clk;
}
if (GPMI_IS_MX6(this))
/*
* Set the default value for the gpmi clock.
*
* If you want to use the ONFI nand which is in the
* Synchronous Mode, you should change the clock as you need.
*/
clk_set_rate(r->clock[0], 22000000);
return 0;
err_clock:
......@@ -1425,7 +1433,6 @@ static int gpmi_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
struct mtd_info *mtd = nand_to_mtd(chip);
struct gpmi_nand_data *this = nand_get_controller_data(chip);
struct bch_geometry *nfc_geo = &this->bch_geometry;
int ret;
dev_dbg(this->dev, "ecc write page.\n");
......@@ -1445,9 +1452,7 @@ static int gpmi_ecc_write_page(struct nand_chip *chip, const uint8_t *buf,
this->auxiliary_virt);
}
ret = nand_prog_page_op(chip, page, 0, buf, nfc_geo->page_size);
return ret;
return nand_prog_page_op(chip, page, 0, buf, nfc_geo->page_size);
}
/*
......@@ -2278,7 +2283,9 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip,
*/
if (this->hw.must_apply_timings) {
this->hw.must_apply_timings = false;
gpmi_nfc_apply_timings(this);
ret = gpmi_nfc_apply_timings(this);
if (ret)
return ret;
}
dev_dbg(this->dev, "%s: %d instructions\n", __func__, op->ninstrs);
......
......@@ -32,6 +32,7 @@ struct jz_soc_info {
unsigned long addr_offset;
unsigned long cmd_offset;
const struct mtd_ooblayout_ops *oob_layout;
bool oob_first;
};
struct ingenic_nand_cs {
......@@ -240,6 +241,9 @@ static int ingenic_nand_attach_chip(struct nand_chip *chip)
if (chip->bbt_options & NAND_BBT_USE_FLASH)
chip->bbt_options |= NAND_BBT_NO_OOB;
if (nfc->soc_info->oob_first)
chip->ecc.read_page = nand_read_page_hwecc_oob_first;
/* For legacy reasons we use a different layout on the qi,lb60 board. */
if (of_machine_is_compatible("qi,lb60"))
mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops);
......@@ -534,6 +538,7 @@ static const struct jz_soc_info jz4740_soc_info = {
.data_offset = 0x00000000,
.cmd_offset = 0x00008000,
.addr_offset = 0x00010000,
.oob_first = true,
};
static const struct jz_soc_info jz4725b_soc_info = {
......
......@@ -291,7 +291,6 @@ static int ads5121_chipselect_init(struct mtd_info *mtd)
/* Control chips select signal on ADS5121 board */
static void ads5121_select_chip(struct nand_chip *nand, int chip)
{
struct mtd_info *mtd = nand_to_mtd(nand);
struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand);
u8 v;
......
......@@ -3163,6 +3163,73 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf,
return max_bitflips;
}
/**
* nand_read_page_hwecc_oob_first - Hardware ECC page read with ECC
* data read from OOB area
* @chip: nand chip info structure
* @buf: buffer to store read data
* @oob_required: caller requires OOB data read to chip->oob_poi
* @page: page number to read
*
* Hardware ECC for large page chips, which requires the ECC data to be
* extracted from the OOB before the actual data is read.
*/
int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf,
int oob_required, int page)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int i, eccsize = chip->ecc.size, ret;
int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps;
uint8_t *p = buf;
uint8_t *ecc_code = chip->ecc.code_buf;
unsigned int max_bitflips = 0;
/* Read the OOB area first */
ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize);
if (ret)
return ret;
/* Move read cursor to start of page */
ret = nand_change_read_column_op(chip, 0, NULL, 0, false);
if (ret)
return ret;
ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
chip->ecc.total);
if (ret)
return ret;
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
int stat;
chip->ecc.hwctl(chip, NAND_ECC_READ);
ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret)
return ret;
stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL);
if (stat == -EBADMSG &&
(chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
/* check for empty pages with bitflips */
stat = nand_check_erased_ecc_chunk(p, eccsize,
&ecc_code[i],
eccbytes, NULL, 0,
chip->ecc.strength);
}
if (stat < 0) {
mtd->ecc_stats.failed++;
} else {
mtd->ecc_stats.corrected += stat;
max_bitflips = max_t(unsigned int, max_bitflips, stat);
}
}
return max_bitflips;
}
EXPORT_SYMBOL_GPL(nand_read_page_hwecc_oob_first);
/**
* nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read
* @chip: nand chip info structure
......
This diff is collapsed.
......@@ -384,8 +384,8 @@ static irqreturn_t elm_isr(int this_irq, void *dev_id)
static int elm_probe(struct platform_device *pdev)
{
int ret = 0;
struct resource *irq;
struct elm_info *info;
int irq;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info)
......@@ -393,20 +393,18 @@ static int elm_probe(struct platform_device *pdev)
info->dev = &pdev->dev;
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
dev_err(&pdev->dev, "no irq resource defined\n");
return -ENODEV;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
info->elm_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->elm_base))
return PTR_ERR(info->elm_base);
ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0,
pdev->name, info);
ret = devm_request_irq(&pdev->dev, irq, elm_isr, 0,
pdev->name, info);
if (ret) {
dev_err(&pdev->dev, "failure requesting %pr\n", irq);
dev_err(&pdev->dev, "failure requesting %d\n", irq);
return ret;
}
......
This diff is collapsed.
......@@ -1539,6 +1539,8 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
bool force_8bit, bool check_only);
int nand_write_data_op(struct nand_chip *chip, const void *buf,
unsigned int len, bool force_8bit);
int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf,
int oob_required, int page);
/* Scan and identify a NAND device */
int nand_scan_with_ids(struct nand_chip *chip, unsigned int max_chips,
......
......@@ -7,6 +7,7 @@
#define _MTD_NAND_OMAP2_H
#include <linux/mtd/partitions.h>
#include <linux/mod_devicetable.h>
#define GPMC_BCH_NUM_REMAINDER 8
......@@ -61,4 +62,11 @@ struct gpmc_nand_regs {
void __iomem *gpmc_bch_result5[GPMC_BCH_NUM_REMAINDER];
void __iomem *gpmc_bch_result6[GPMC_BCH_NUM_REMAINDER];
};
#endif
static const struct of_device_id omap_nand_ids[] = {
{ .compatible = "ti,omap2-nand", },
{ .compatible = "ti,am64-nand", },
{},
};
#endif /* _MTD_NAND_OMAP2_H */
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