/* * Main initialization routine */ static int __init h1910_init (void) { struct nand_chip *this; const char *part_type = 0; int mtd_parts_nb = 0; struct mtd_partition *mtd_parts = 0; void __iomem *nandaddr; if (!machine_is_h1900()) return -ENODEV; nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); if (!nandaddr) { printk("Failed to ioremap nand flash.\n"); return -ENOMEM; } /* Allocate memory for MTD device structure and private data */ h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!h1910_nand_mtd) { printk("Unable to allocate h1910 NAND MTD device structure.\n"); iounmap ((void *) nandaddr); return -ENOMEM; } /* Get pointer to private data */ this = (struct nand_chip *) (&h1910_nand_mtd[1]); /* Initialize structures */ memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); memset((char *) this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ h1910_nand_mtd->priv = this; /* * Enable VPEN */ GPSR(37) = GPIO_bit(37); /* insert callbacks */ this->IO_ADDR_R = nandaddr; this->IO_ADDR_W = nandaddr; this->hwcontrol = h1910_hwcontrol; this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ /* 15 us command delay time */ this->chip_delay = 50; this->eccmode = NAND_ECC_SOFT; this->options = NAND_NO_AUTOINCR; /* Scan to find existence of the device */ if (nand_scan (h1910_nand_mtd, 1)) { printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); kfree (h1910_nand_mtd); iounmap ((void *) nandaddr); return -ENXIO; } #ifdef CONFIG_MTD_CMDLINE_PARTS mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, "h1910-nand"); if (mtd_parts_nb > 0) part_type = "command line"; else mtd_parts_nb = 0; #endif if (mtd_parts_nb == 0) { mtd_parts = partition_info; mtd_parts_nb = NUM_PARTITIONS; part_type = "static"; } /* Register the partitions */ printk(KERN_NOTICE "Using %s partition definition\n", part_type); add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); /* Return happy */ return 0; }
static int hinfc504_os_probe(struct platform_device * pltdev) { int size; int result = 0; struct hinfc_host *host; struct nand_chip *chip; struct mtd_info *mtd; struct resource *res; size = sizeof(struct hinfc_host) + sizeof(struct nand_chip) + sizeof(struct mtd_info); host = kmalloc(size, GFP_KERNEL); if (!host) { PR_BUG("failed to allocate device structure.\n"); return -ENOMEM; } memset((char *)host, 0, size); platform_set_drvdata(pltdev, host); host->dev = &pltdev->dev; host->chip = chip = (struct nand_chip *)&host[1]; host->mtd = mtd = (struct mtd_info *)&chip[1]; res = platform_get_resource_byname(pltdev, IORESOURCE_MEM, "base"); if (!res) { PR_BUG("Can't get resource.\n"); return -EIO; } host->iobase = ioremap(res->start, res->end - res->start + 1); if (!host->iobase) { PR_BUG("ioremap failed\n"); kfree(host); return -EIO; } mtd->priv = chip; mtd->owner = THIS_MODULE; mtd->name = (char*)(pltdev->name); res = platform_get_resource_byname(pltdev, IORESOURCE_MEM, "buffer"); if (!res) { PR_BUG("Can't get resource.\n"); return -EIO; } chip->IO_ADDR_R = chip->IO_ADDR_W = ioremap_nocache(res->start, res->end - res->start + 1); if (!chip->IO_ADDR_R) { PR_BUG("ioremap failed\n"); return -EIO; } host->buffer = dma_alloc_coherent(host->dev, (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE), &host->dma_buffer, GFP_KERNEL); if (!host->buffer) { PR_BUG("Can't malloc memory for NAND driver."); return -EIO; } chip->priv = host; host->chip = chip; chip->cmd_ctrl = hinfc504_cmd_ctrl; chip->dev_ready = hinfc504_dev_ready; chip->select_chip = hinfc504_select_chip; chip->read_byte = hinfc504_read_byte; chip->read_word = hinfc504_read_word; chip->write_buf = hinfc504_write_buf; chip->read_buf = hinfc504_read_buf; chip->chip_delay = HINFC504_CHIP_DELAY; chip->options = NAND_NO_AUTOINCR | NAND_SKIP_BBTSCAN; chip->ecc.layout = NULL; chip->ecc.mode = NAND_ECC_NONE; host->clk = clk_get_sys("hinfc504", NULL); if (IS_ERR(host->clk)) { PR_BUG("hinfc504 clock not found.\n"); return -EIO; } host->enable = hinfc504_os_enable; if (hinfc504_nand_init(host, chip)) { PR_BUG("failed to allocate device buffer.\n"); return -EIO; } if (nand_otp_len) { PR_MSG("Copy Nand read retry parameter from boot," " parameter length %d.\n", nand_otp_len); memcpy(host->rr_data, nand_otp, nand_otp_len); } if (nand_scan(mtd, CONFIG_HINFC504_MAX_CHIP)) { result = -ENXIO; goto fail; } register_mtd_partdev(host->mtd); if (!mtd_device_parse_register(mtd, part_probes_type, NULL, ptn_info.parts, ptn_info.parts_num)) return 0; unregister_mtd_partdev(host->mtd); result = -ENODEV; nand_release(mtd); fail: if (host->buffer) { dma_free_coherent(host->dev, (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE), host->buffer, host->dma_buffer); host->buffer = NULL; } iounmap(chip->IO_ADDR_W); iounmap(host->iobase); kfree(host); platform_set_drvdata(pltdev, NULL); return result; }
/* * Main initialization routine */ static int __devinit ams_delta_init(struct platform_device *pdev) { struct nand_chip *this; struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); void __iomem *io_base; int err = 0; if (!res) return -ENXIO; /* Allocate memory for MTD device structure and private data */ ams_delta_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!ams_delta_mtd) { printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n"); err = -ENOMEM; goto out; } ams_delta_mtd->owner = THIS_MODULE; /* Get pointer to private data */ this = (struct nand_chip *) (&ams_delta_mtd[1]); /* Initialize structures */ memset(ams_delta_mtd, 0, sizeof(struct mtd_info)); memset(this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ ams_delta_mtd->priv = this; if (!request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev))) { dev_err(&pdev->dev, "request_mem_region failed\n"); err = -EBUSY; goto out_free; } io_base = ioremap(res->start, resource_size(res)); if (io_base == NULL) { dev_err(&pdev->dev, "ioremap failed\n"); err = -EIO; goto out_release_io; } this->priv = io_base; /* Set address of NAND IO lines */ this->IO_ADDR_R = io_base + OMAP_MPUIO_INPUT_LATCH; this->IO_ADDR_W = io_base + OMAP_MPUIO_OUTPUT; this->read_byte = ams_delta_read_byte; this->write_buf = ams_delta_write_buf; this->read_buf = ams_delta_read_buf; this->verify_buf = ams_delta_verify_buf; this->cmd_ctrl = ams_delta_hwcontrol; if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) { this->dev_ready = ams_delta_nand_ready; } else { this->dev_ready = NULL; ; } /* 25 us command delay time */ this->chip_delay = 30; this->ecc.mode = NAND_ECC_SOFT; platform_set_drvdata(pdev, io_base); /* Set chip enabled, but */ ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP); /* Scan to find existence of the device */ if (nand_scan(ams_delta_mtd, 1)) { err = -ENXIO; goto out_mtd; } /* Register the partitions */ mtd_device_register(ams_delta_mtd, partition_info, ARRAY_SIZE(partition_info)); goto out; out_mtd: platform_set_drvdata(pdev, NULL); iounmap(io_base); out_release_io: release_mem_region(res->start, resource_size(res)); out_free: kfree(ams_delta_mtd); out: return err; }
/* * Initialize chip structure */ static int ndfc_chip_init(struct ndfc_controller *ndfc, struct device_node *node) { #ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_CMDLINE_PARTS static const char *part_types[] = { "cmdlinepart", NULL }; #else static const char *part_types[] = { NULL }; #endif #endif struct device_node *flash_np; struct nand_chip *chip = &ndfc->chip; int ret; chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; chip->cmd_ctrl = ndfc_hwcontrol; chip->dev_ready = ndfc_ready; chip->select_chip = ndfc_select_chip; chip->chip_delay = 50; chip->controller = &ndfc->ndfc_control; chip->read_buf = ndfc_read_buf; chip->write_buf = ndfc_write_buf; chip->verify_buf = ndfc_verify_buf; chip->ecc.correct = nand_correct_data; chip->ecc.hwctl = ndfc_enable_hwecc; chip->ecc.calculate = ndfc_calculate_ecc; chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 256; chip->ecc.bytes = 3; ndfc->mtd.priv = chip; ndfc->mtd.owner = THIS_MODULE; flash_np = of_get_next_child(node, NULL); if (!flash_np) return -ENODEV; ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), flash_np->name); if (!ndfc->mtd.name) { ret = -ENOMEM; goto err; } ret = nand_scan(&ndfc->mtd, 1); if (ret) goto err; #ifdef CONFIG_MTD_PARTITIONS ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0); if (ret < 0) goto err; #ifdef CONFIG_MTD_OF_PARTS if (ret == 0) { ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np, &ndfc->parts); if (ret < 0) goto err; } #endif if (ret > 0) ret = add_mtd_partitions(&ndfc->mtd, ndfc->parts, ret); else #endif ret = add_mtd_device(&ndfc->mtd); err: of_node_put(flash_np); if (ret) kfree(ndfc->mtd.name); return ret; }
/* * Probe for the NAND device. */ static int __init at91_nand_probe(struct platform_device *pdev) { struct at91_nand_host *host; struct mtd_info *mtd; struct nand_chip *nand_chip; int res; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *partitions = NULL; int num_partitions = 0; #endif /* Allocate memory for the device structure (and zero it) */ host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); if (!host) { printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); return -ENOMEM; } host->io_base = ioremap(pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start + 1); if (host->io_base == NULL) { printk(KERN_ERR "at91_nand: ioremap failed\n"); kfree(host); return -EIO; } mtd = &host->mtd; nand_chip = &host->nand_chip; host->board = pdev->dev.platform_data; nand_chip->priv = host; /* link the private data structures */ mtd->priv = nand_chip; mtd->owner = THIS_MODULE; /* Set address of NAND IO lines */ nand_chip->IO_ADDR_R = host->io_base; nand_chip->IO_ADDR_W = host->io_base; nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; nand_chip->dev_ready = at91_nand_device_ready; nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ nand_chip->chip_delay = 20; /* 20us command delay time */ if (host->board->bus_width_16) /* 16-bit bus width */ nand_chip->options |= NAND_BUSWIDTH_16; platform_set_drvdata(pdev, host); at91_nand_enable(host); if (host->board->det_pin) { if (at91_get_gpio_value(host->board->det_pin)) { printk ("No SmartMedia card inserted.\n"); res = ENXIO; goto out; } } /* Scan to find existance of the device */ if (nand_scan(mtd, 1)) { res = -ENXIO; goto out; } #ifdef CONFIG_MTD_PARTITIONS if (host->board->partition_info) partitions = host->board->partition_info(mtd->size, &num_partitions); if ((!partitions) || (num_partitions == 0)) { printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); res = ENXIO; goto release; } res = add_mtd_partitions(mtd, partitions, num_partitions); #else res = add_mtd_device(mtd); #endif if (!res) return res; release: nand_release(mtd); out: at91_nand_disable(host); platform_set_drvdata(pdev, NULL); iounmap(host->io_base); kfree(host); return res; }
/* * Main initialization routine */ static int __init ppchameleonevb_init(void) { struct nand_chip *this; void __iomem *ppchameleon_fio_base; void __iomem *ppchameleonevb_fio_base; /********************************* * Processor module NAND (if any) * *********************************/ /* Allocate memory for MTD device structure and private data */ ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!ppchameleon_mtd) { printk("Unable to allocate PPChameleon NAND MTD device structure.\n"); return -ENOMEM; } /* map physical address */ ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M); if (!ppchameleon_fio_base) { printk("ioremap PPChameleon NAND flash failed\n"); kfree(ppchameleon_mtd); return -EIO; } /* Get pointer to private data */ this = (struct nand_chip *)(&ppchameleon_mtd[1]); /* Initialize structures */ memset(ppchameleon_mtd, 0, sizeof(struct mtd_info)); memset(this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ ppchameleon_mtd->priv = this; ppchameleon_mtd->owner = THIS_MODULE; /* Initialize GPIOs */ /* Pin mapping for NAND chip */ /* CE GPIO_01 CLE GPIO_02 ALE GPIO_03 R/B GPIO_04 */ /* output select */ out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xC0FFFFFF); /* three-state select */ out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xC0FFFFFF); /* enable output driver */ out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN); #ifdef USE_READY_BUSY_PIN /* three-state select */ out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFF3FFFFF); /* high-impedecence */ out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_RB_GPIO_PIN)); /* input select */ out_be32((volatile unsigned *)GPIO0_ISR1H, (in_be32((volatile unsigned *)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000); #endif /* insert callbacks */ this->IO_ADDR_R = ppchameleon_fio_base; this->IO_ADDR_W = ppchameleon_fio_base; this->cmd_ctrl = ppchameleon_hwcontrol; #ifdef USE_READY_BUSY_PIN this->dev_ready = ppchameleon_device_ready; #endif this->chip_delay = NAND_BIG_DELAY_US; /* ECC mode */ this->ecc.mode = NAND_ECC_SOFT; /* Scan to find existence of the device (it could not be mounted) */ if (nand_scan(ppchameleon_mtd, 1)) { iounmap((void *)ppchameleon_fio_base); ppchameleon_fio_base = NULL; kfree(ppchameleon_mtd); goto nand_evb_init; } #ifndef USE_READY_BUSY_PIN /* Adjust delay if necessary */ if (ppchameleon_mtd->size == NAND_SMALL_SIZE) this->chip_delay = NAND_SMALL_DELAY_US; #endif ppchameleon_mtd->name = "ppchameleon-nand"; /* Register the partitions */ mtd_device_parse_register(ppchameleon_mtd, NULL, 0, ppchameleon_mtd->size == NAND_SMALL_SIZE ? partition_info_me : partition_info_hi, NUM_PARTITIONS); nand_evb_init: /**************************** * EVB NAND (always present) * ****************************/ /* Allocate memory for MTD device structure and private data */ ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!ppchameleonevb_mtd) { printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n"); if (ppchameleon_fio_base) iounmap(ppchameleon_fio_base); return -ENOMEM; } /* map physical address */ ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M); if (!ppchameleonevb_fio_base) { printk("ioremap PPChameleonEVB NAND flash failed\n"); kfree(ppchameleonevb_mtd); if (ppchameleon_fio_base) iounmap(ppchameleon_fio_base); return -EIO; } /* Get pointer to private data */ this = (struct nand_chip *)(&ppchameleonevb_mtd[1]); /* Initialize structures */ memset(ppchameleonevb_mtd, 0, sizeof(struct mtd_info)); memset(this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ ppchameleonevb_mtd->priv = this; /* Initialize GPIOs */ /* Pin mapping for NAND chip */ /* CE GPIO_14 CLE GPIO_15 ALE GPIO_16 R/B GPIO_31 */ /* output select */ out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xFFFFFFF0); out_be32((volatile unsigned *)GPIO0_OSRL, in_be32((volatile unsigned *)GPIO0_OSRL) & 0x3FFFFFFF); /* three-state select */ out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFFFFFFF0); out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0x3FFFFFFF); /* enable output driver */ out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); #ifdef USE_READY_BUSY_PIN /* three-state select */ out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0xFFFFFFFC); /* high-impedecence */ out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN)); /* input select */ out_be32((volatile unsigned *)GPIO0_ISR1L, (in_be32((volatile unsigned *)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001); #endif /* insert callbacks */ this->IO_ADDR_R = ppchameleonevb_fio_base; this->IO_ADDR_W = ppchameleonevb_fio_base; this->cmd_ctrl = ppchameleonevb_hwcontrol; #ifdef USE_READY_BUSY_PIN this->dev_ready = ppchameleonevb_device_ready; #endif this->chip_delay = NAND_SMALL_DELAY_US; /* ECC mode */ this->ecc.mode = NAND_ECC_SOFT; /* Scan to find existence of the device */ if (nand_scan(ppchameleonevb_mtd, 1)) { iounmap((void *)ppchameleonevb_fio_base); kfree(ppchameleonevb_mtd); if (ppchameleon_fio_base) iounmap(ppchameleon_fio_base); return -ENXIO; } ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; /* Register the partitions */ mtd_device_parse_register(ppchameleonevb_mtd, NULL, 0, ppchameleon_mtd->size == NAND_SMALL_SIZE ? partition_info_me : partition_info_hi, NUM_PARTITIONS); /* Return happy */ return 0; }
static int __init ams_delta_init(void) { struct nand_chip *this; int err = 0; /* Allocate memory for MTD device structure and private data */ ams_delta_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!ams_delta_mtd) { printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n"); err = -ENOMEM; goto out; } ams_delta_mtd->owner = THIS_MODULE; /* Get pointer to private data */ this = (struct nand_chip *) (&ams_delta_mtd[1]); /* Initialize structures */ memset(ams_delta_mtd, 0, sizeof(struct mtd_info)); memset(this, 0, sizeof(struct nand_chip)); /* Link the private data with the MTD structure */ ams_delta_mtd->priv = this; /* Set address of NAND IO lines */ this->IO_ADDR_R = (OMAP1_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH); this->IO_ADDR_W = (OMAP1_MPUIO_BASE + OMAP_MPUIO_OUTPUT); this->read_byte = ams_delta_read_byte; this->write_buf = ams_delta_write_buf; this->read_buf = ams_delta_read_buf; this->verify_buf = ams_delta_verify_buf; this->cmd_ctrl = ams_delta_hwcontrol; if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) { this->dev_ready = ams_delta_nand_ready; } else { this->dev_ready = NULL; printk(KERN_NOTICE "Couldn't request gpio for Delta NAND ready.\n"); } /* 25 us command delay time */ this->chip_delay = 30; this->ecc.mode = NAND_ECC_SOFT; /* Set chip enabled, but */ ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP); /* Scan to find existance of the device */ if (nand_scan(ams_delta_mtd, 1)) { err = -ENXIO; goto out_mtd; } /* Register the partitions */ add_mtd_partitions(ams_delta_mtd, partition_info, ARRAY_SIZE(partition_info)); goto out; out_mtd: kfree(ams_delta_mtd); out: return err; }
static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) { int err = 0; struct nand_chip *this; struct mtd_info *new_mtd; printk(KERN_NOTICE "Probing CS553x NAND controller CS#%d at %sIO 0x%08lx\n", cs, mmio?"MM":"P", adr); if (!mmio) { printk(KERN_NOTICE "PIO mode not yet implemented for CS553X NAND controller\n"); return -ENXIO; } /* Allocate memory for MTD device structure and private data */ new_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!new_mtd) { err = -ENOMEM; goto out; } /* Get pointer to private data */ this = (struct nand_chip *)(&new_mtd[1]); /* Link the private data with the MTD structure */ new_mtd->priv = this; new_mtd->owner = THIS_MODULE; /* map physical address */ this->IO_ADDR_R = this->IO_ADDR_W = ioremap(adr, 4096); if (!this->IO_ADDR_R) { printk(KERN_WARNING "ioremap cs553x NAND @0x%08lx failed\n", adr); err = -EIO; goto out_mtd; } this->cmd_ctrl = cs553x_hwcontrol; this->dev_ready = cs553x_device_ready; this->read_byte = cs553x_read_byte; this->read_buf = cs553x_read_buf; this->write_buf = cs553x_write_buf; this->chip_delay = 0; this->ecc.mode = NAND_ECC_HW; this->ecc.size = 256; this->ecc.bytes = 3; this->ecc.hwctl = cs_enable_hwecc; this->ecc.calculate = cs_calculate_ecc; this->ecc.correct = nand_correct_data; this->ecc.strength = 1; /* Enable the following for a flash based bad block table */ this->bbt_options = NAND_BBT_USE_FLASH; new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); if (!new_mtd->name) { err = -ENOMEM; goto out_ior; } /* Scan to find existence of the device */ if (nand_scan(new_mtd, 1)) { err = -ENXIO; goto out_free; } cs553x_mtd[cs] = new_mtd; goto out; out_free: kfree(new_mtd->name); out_ior: iounmap(this->IO_ADDR_R); out_mtd: kfree(new_mtd); out: return err; }
static int __devinit pasemi_nand_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct pci_dev *pdev; struct device_node *np = ofdev->dev.of_node; struct resource res; struct nand_chip *chip; int err = 0; err = of_address_to_resource(np, 0, &res); if (err) return -EINVAL; /* We only support one device at the moment */ if (pasemi_nand_mtd) return -ENODEV; pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end); /* Allocate memory for MTD device structure and private data */ pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!pasemi_nand_mtd) { printk(KERN_WARNING "Unable to allocate PASEMI NAND MTD device structure\n"); err = -ENOMEM; goto out; } /* Get pointer to private data */ chip = (struct nand_chip *)&pasemi_nand_mtd[1]; /* Link the private data with the MTD structure */ pasemi_nand_mtd->priv = chip; pasemi_nand_mtd->owner = THIS_MODULE; chip->IO_ADDR_R = of_iomap(np, 0); chip->IO_ADDR_W = chip->IO_ADDR_R; if (!chip->IO_ADDR_R) { err = -EIO; goto out_mtd; } pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa008, NULL); if (!pdev) { err = -ENODEV; goto out_ior; } lpcctl = pci_resource_start(pdev, 0); pci_dev_put(pdev); if (!request_region(lpcctl, 4, driver_name)) { err = -EBUSY; goto out_ior; } chip->cmd_ctrl = pasemi_hwcontrol; chip->dev_ready = pasemi_device_ready; chip->read_buf = pasemi_read_buf; chip->write_buf = pasemi_write_buf; chip->chip_delay = 0; chip->ecc.mode = NAND_ECC_SOFT; /* Enable the following for a flash based bad block table */ chip->options = NAND_NO_AUTOINCR; chip->bbt_options = NAND_BBT_USE_FLASH; /* Scan to find existance of the device */ if (nand_scan(pasemi_nand_mtd, 1)) { err = -ENXIO; goto out_lpc; } if (add_mtd_device(pasemi_nand_mtd)) { printk(KERN_ERR "pasemi_nand: Unable to register MTD device\n"); err = -ENODEV; goto out_lpc; } printk(KERN_INFO "PA Semi NAND flash at %08llx, control at I/O %x\n", res.start, lpcctl); return 0; out_lpc: release_region(lpcctl, 4); out_ior: iounmap(chip->IO_ADDR_R); out_mtd: kfree(pasemi_nand_mtd); out: return err; }
static int __devinit sharpsl_nand_probe(struct platform_device *pdev) { struct nand_chip *this; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *sharpsl_partition_info; int nr_partitions; #endif struct resource *r; int err = 0; struct sharpsl_nand *sharpsl; struct sharpsl_nand_platform_data *data = pdev->dev.platform_data; if (!data) { dev_err(&pdev->dev, "no platform data!\n"); return -EINVAL; } /* Allocate memory for MTD device structure and private data */ sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL); if (!sharpsl) { printk("Unable to allocate SharpSL NAND MTD device structure.\n"); return -ENOMEM; } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "no io memory resource defined!\n"); err = -ENODEV; goto err_get_res; } /* map physical address */ sharpsl->io = ioremap(r->start, resource_size(r)); if (!sharpsl->io) { printk("ioremap to access Sharp SL NAND chip failed\n"); err = -EIO; goto err_ioremap; } /* Get pointer to private data */ this = (struct nand_chip *)(&sharpsl->chip); /* Link the private data with the MTD structure */ sharpsl->mtd.priv = this; sharpsl->mtd.owner = THIS_MODULE; platform_set_drvdata(pdev, sharpsl); /* * PXA initialize */ writeb(readb(sharpsl->io + FLASHCTL) | FLWP, sharpsl->io + FLASHCTL); /* Set address of NAND IO lines */ this->IO_ADDR_R = sharpsl->io + FLASHIO; this->IO_ADDR_W = sharpsl->io + FLASHIO; /* Set address of hardware control function */ this->cmd_ctrl = sharpsl_nand_hwcontrol; this->dev_ready = sharpsl_nand_dev_ready; /* 15 us command delay time */ this->chip_delay = 15; /* set eccmode using hardware ECC */ this->ecc.mode = NAND_ECC_HW; this->ecc.size = 256; this->ecc.bytes = 3; this->badblock_pattern = data->badblock_pattern; this->ecc.layout = data->ecc_layout; this->ecc.hwctl = sharpsl_nand_enable_hwecc; this->ecc.calculate = sharpsl_nand_calculate_ecc; this->ecc.correct = nand_correct_data; /* Scan to find existence of the device */ err = nand_scan(&sharpsl->mtd, 1); if (err) goto err_scan; /* Register the partitions */ sharpsl->mtd.name = "sharpsl-nand"; #ifdef CONFIG_MTD_PARTITIONS nr_partitions = parse_mtd_partitions(&sharpsl->mtd, part_probes, &sharpsl_partition_info, 0); if (nr_partitions <= 0) { nr_partitions = data->nr_partitions; sharpsl_partition_info = data->partitions; } if (nr_partitions > 0) err = add_mtd_partitions(&sharpsl->mtd, sharpsl_partition_info, nr_partitions); else #endif err = add_mtd_device(&sharpsl->mtd); if (err) goto err_add; /* Return happy */ return 0; err_add: nand_release(&sharpsl->mtd); err_scan: platform_set_drvdata(pdev, NULL); iounmap(sharpsl->io); err_ioremap: err_get_res: kfree(sharpsl); return err; }