Date:2011-05-29 17:06:05 (11 years 4 months ago)
Author:Maarten ter Huurne
Commit:3ed7d0461571cd54ed3450d910370614d0db13be
Message:MTD: NAND: JZ4740: Finished multi-bank support and added autodetection

The platform data can now specify which external memory banks to probe
for NAND chips, and in which order. Banks that contain a NAND are used
and the other banks are freed.

Thanks to Paul Cercueil <paul@crapouillou.net> for the initial patch that
performed autodetection.

Additionally, the following problems were tackled:
- add_mtd_device returns 0/1 instead of an error code
- the mmio resource should be released if probe fails
- avoid freeing non-existing busy gpio
Files: drivers/mtd/nand/jz4740_nand.c (9 diffs)

Change Details

drivers/mtd/nand/jz4740_nand.c
5757#define JZ_NAND_MEM_CMD_OFFSET 0x08000
5858#define JZ_NAND_MEM_ADDR_OFFSET 0x10000
5959
60#define JZ_NAND_NUM_BANKS 4
61
6062struct jz_nand {
6163    struct mtd_info mtd;
6264    struct nand_chip chip;
6365    void __iomem *base;
6466    struct resource *mem;
6567
66    void __iomem *bank_base[4];
67    struct resource *bank_mem[4];
68    unsigned char banks[JZ_NAND_NUM_BANKS];
69    void __iomem *bank_base[JZ_NAND_NUM_BANKS];
70    struct resource *bank_mem[JZ_NAND_NUM_BANKS];
6871
6972    int selected_bank;
7073
...... 
9093    if (chipnr == -1) {
9194        banknr = -1;
9295    } else {
93        banknr = nand->pdata->banks[chipnr] - 1;
96        banknr = nand->banks[chipnr] - 1;
9497        chip->IO_ADDR_R = nand->bank_base[banknr];
9598        chip->IO_ADDR_W = nand->bank_base[banknr];
9699    }
...... 
327330    release_mem_region(res->start, resource_size(res));
328331}
329332
330static void jz_nand_iounmap_banks(
331    struct jz_nand *nand, unsigned char *banks, size_t num_banks)
332{
333    int i;
333static int __devinit jz_nand_detect_bank(struct platform_device *pdev, struct jz_nand *nand, unsigned char bank, size_t chipnr, uint8_t *nand_maf_id, uint8_t *nand_dev_id) {
334    int ret;
335    int gpio;
336    char gpio_name[9];
337    char res_name[6];
338    uint32_t ctrl;
339    struct mtd_info *mtd = &nand->mtd;
340    struct nand_chip *chip = &nand->chip;
334341
335    for (i = 0; i < num_banks; ++i) {
336        unsigned char bank = banks[i];
337        jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
338                     nand->bank_base[bank - 1]);
342    /* Request GPIO port. */
343    gpio = JZ_GPIO_MEM_CS0 + bank - 1;
344    sprintf(gpio_name, "NAND CS%d", bank);
345    ret = gpio_request(gpio, gpio_name);
346    if (ret) {
347        dev_warn(&pdev->dev,
348            "Failed to request %s gpio %d: %d\n",
349            gpio_name, gpio, ret);
350        goto notfound_gpio;
339351    }
340}
341352
342static int jz_nand_ioremap_banks(struct platform_device *pdev,
343    struct jz_nand *nand, unsigned char *banks, size_t num_banks)
344{
345    int ret;
346    char name[6];
347    int i;
353    /* Request I/O resource. */
354    sprintf(res_name, "bank%d", bank);
355    ret = jz_nand_ioremap_resource(pdev, res_name,
356                    &nand->bank_mem[bank - 1],
357                    &nand->bank_base[bank - 1]);
358    if (ret)
359        goto notfound_resource;
348360
349    for (i = 0; i < num_banks; ++i) {
350        unsigned char bank = banks[i];
351        sprintf(name, "bank%d", bank);
361    /* Enable chip in bank. */
362    jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
363    ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
364    ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
365    writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
352366
353        ret = jz_nand_ioremap_resource(pdev, name,
354                           &nand->bank_mem[bank - 1],
355                           &nand->bank_base[bank - 1]);
356        if (ret) {
357            jz_nand_iounmap_banks(nand, banks, i);
358            return ret;
367    if (chipnr == 0) {
368        /* Detect first chip. */
369        ret = nand_scan_ident(mtd, 1, NULL);
370        if (ret)
371            goto notfound_id;
372
373        /* Retrieve the IDs from the first chip. */
374        chip->select_chip(mtd, 0);
375        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
376        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
377        *nand_maf_id = chip->read_byte(mtd);
378        *nand_dev_id = chip->read_byte(mtd);
379    } else {
380        /* Detect additional chip. */
381        chip->select_chip(mtd, chipnr);
382        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
383        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
384        if (*nand_maf_id != chip->read_byte(mtd)
385         || *nand_dev_id != chip->read_byte(mtd)) {
386            ret = -ENODEV;
387            goto notfound_id;
359388        }
389
390        /* Update size of the MTD. */
391        chip->numchips++;
392        mtd->size += chip->chipsize;
360393    }
361394
395    dev_info(&pdev->dev, "Found chip %i on bank %i\n", chipnr, bank);
362396    return 0;
397
398notfound_id:
399    dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
400    ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
401    writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
402    jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
403    jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
404                 nand->bank_base[bank - 1]);
405notfound_resource:
406    gpio_free(gpio);
407notfound_gpio:
408    return ret;
363409}
364410
365411static int __devinit jz_nand_probe(struct platform_device *pdev)
...... 
373419    struct mtd_partition *partition_info;
374420    int num_partitions = 0;
375421#endif
376    size_t num_banks;
377    unsigned char bank;
378    uint32_t ctrl;
422    size_t chipnr, bank_idx;
423    uint8_t nand_maf_id = 0, nand_dev_id = 0;
379424
380425    nand = kzalloc(sizeof(*nand), GFP_KERNEL);
381426    if (!nand) {
...... 
423468    nand->pdata = pdata;
424469    platform_set_drvdata(pdev, nand);
425470
426    if (pdata->banks[0] == 0)
427        pdata->banks[0] = 1;
428
429    ctrl = 0;
430    for (num_banks = 0; num_banks < 4 ; ++num_banks) {
431        int gpio;
432        char name[9];
433
434        bank = pdata->banks[num_banks];
471    /* We are going to autodetect NAND chips in the banks specified in the
472     * platform data. Although nand_scan_ident() can detect multiple chips,
473     * it requires those chips to be numbered consecuitively, which is not
474     * always the case for external memory banks. And a fixed chip-to-bank
475     * mapping is not practical either, since for example Dingoo units
476     * produced at different times have NAND chips in different banks.
477     */
478    chipnr = 0;
479    for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) {
480        unsigned char bank;
481
482        /* If there is no platform data, look for NAND in bank 1,
483         * which is the most likely bank since it is the only one
484         * that can be booted from.
485         */
486        bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1;
435487        if (bank == 0)
436488            break;
437        if (bank > 4) {
438            dev_err(&pdev->dev, "Non-existing bank: %d\n", bank);
439            ret = -EINVAL;
440            goto err_gpio_free;
489        if (bank > JZ_NAND_NUM_BANKS) {
490            dev_warn(&pdev->dev,
491                "Skipping non-existing bank: %d\n", bank);
492            continue;
441493        }
442
443        sprintf(name, "NAND CS%d", bank);
444        gpio = JZ_GPIO_MEM_CS0 + bank - 1;
445        ret = gpio_request(gpio, name);
446        if (ret) {
447            dev_err(&pdev->dev,
448                "Failed to request %s gpio %d: %d\n",
449                name, gpio, ret);
450            goto err_gpio_free;
451        }
452        jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
453
454        ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
494        /* The detection routine will directly or indirectly call
495         * jz_nand_select_chip(), so nand->banks has to contain the
496         * bank we're checking.
497         */
498        nand->banks[chipnr] = bank;
499        if (jz_nand_detect_bank(pdev, nand, bank, chipnr,
500                    &nand_maf_id, &nand_dev_id) == 0)
501            chipnr++;
502        else
503            nand->banks[chipnr] = 0;
455504    }
456
457    ret = jz_nand_ioremap_banks(pdev, nand, pdata->banks, num_banks);
458    if (ret)
459        goto err_gpio_free;
460
461    chip->IO_ADDR_R = nand->bank_base[pdata->banks[0] - 1];
462    chip->IO_ADDR_W = nand->bank_base[pdata->banks[0] - 1];
463
464    writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
465
466    ret = nand_scan_ident(mtd, num_banks, NULL);
467    if (ret) {
468        dev_err(&pdev->dev, "Failed to scan nand\n");
469        goto err_iounmap_banks;
505    if (chipnr == 0) {
506        dev_err(&pdev->dev, "No NAND chips found\n");
507        goto err_gpio_busy;
470508    }
471509
472510    if (pdata && pdata->ident_callback) {
...... 
476514
477515    ret = nand_scan_tail(mtd);
478516    if (ret) {
479        dev_err(&pdev->dev, "Failed to scan nand\n");
480        goto err_iounmap_banks;
517        dev_err(&pdev->dev, "Failed to scan NAND\n");
518        goto err_unclaim_banks;
481519    }
482520
483521#ifdef CONFIG_MTD_PARTITIONS
...... 
494532        ret = add_mtd_partitions(mtd, partition_info, num_partitions);
495533    else
496534#endif
497    ret = add_mtd_device(mtd);
535    ret = add_mtd_device(mtd) ? -ENODEV : 0;
498536
499537    if (ret) {
500538        dev_err(&pdev->dev, "Failed to add mtd device\n");
...... 
506544    return 0;
507545
508546err_nand_release:
509    nand_release(&nand->mtd);
510err_iounmap_banks:
511    jz_nand_iounmap_banks(nand, pdata->banks, num_banks);
512err_gpio_free:
513    platform_set_drvdata(pdev, NULL);
514    gpio_free(pdata->busy_gpio);
515    while (num_banks--) {
516        bank = pdata->banks[num_banks];
547    nand_release(mtd);
548err_unclaim_banks:
549    while (chipnr--) {
550        unsigned char bank = nand->banks[chipnr];
517551        gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
552        jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
553                     nand->bank_base[bank - 1]);
518554    }
555    writel(0, nand->base + JZ_REG_NAND_CTRL);
556err_gpio_busy:
557    if (pdata && gpio_is_valid(pdata->busy_gpio))
558        gpio_free(pdata->busy_gpio);
559    platform_set_drvdata(pdev, NULL);
519560err_iounmap_mmio:
520    iounmap(nand->base);
561    jz_nand_iounmap_resource(nand->mem, nand->base);
521562err_free:
522563    kfree(nand);
523564    return ret;
...... 
527568{
528569    struct jz_nand *nand = platform_get_drvdata(pdev);
529570    struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
530    int i;
571    size_t i;
531572
532573    nand_release(&nand->mtd);
533574
534575    /* Deassert and disable all chips */
535576    writel(0, nand->base + JZ_REG_NAND_CTRL);
536577
537    for (i = 0; i < 4; ++i)
538        if (nand->bank_base[i] != 0) {
539            jz_nand_iounmap_resource(nand->bank_mem[i],
540                         nand->bank_base[i]);
541            gpio_free(JZ_GPIO_MEM_CS0 + i);
578    for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) {
579        unsigned char bank = nand->banks[i];
580        if (bank != 0) {
581            jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
582                         nand->bank_base[bank - 1]);
583            gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
542584        }
543    gpio_free(pdata->busy_gpio);
585    }
586    if (pdata && gpio_is_valid(pdata->busy_gpio))
587        gpio_free(pdata->busy_gpio);
544588
545589    jz_nand_iounmap_resource(nand->mem, nand->base);
546590

Archive Download the corresponding diff file



interactive