static int __devinit brcmnanddrv_probe(struct platform_device *pdev) { struct brcmnand_platform_data *cfg = pdev->dev.platform_data; //struct flash_platform_data *pdata = pdev->dev.platform_data; //struct resource *res = pdev->resource; //unsigned long size = res->end - res->start + 1; int err = 0; gPageBuffer = NULL; info = kmalloc(sizeof(struct brcmnand_info), GFP_KERNEL); if (!info) return -ENOMEM; memset(info, 0, sizeof(struct brcmnand_info)); #ifndef CONFIG_MTD_BRCMNAND_EDU gPageBuffer = kmalloc(sizeof(struct nand_buffers), GFP_KERNEL); info->brcmnand.buffers = (struct nand_buffers*) gPageBuffer; #else /* Align on 32B boundary for efficient DMA transfer */ gPageBuffer = kmalloc(sizeof(struct nand_buffers) + 31, GFP_DMA); info->brcmnand.buffers = (struct nand_buffers*) (((unsigned int) gPageBuffer+31) & (~31)); #endif if (!info->brcmnand.buffers) { kfree(info); return -ENOMEM; } memset(info->brcmnand.buffers, 0, sizeof(struct nand_buffers)); memset(gNandCS, 0, MAX_NAND_CS); gNumNand = 1; gNandCS[0] = cfg->chip_select; info->brcmnand.numchips = 1; // For now, we only support 1 chip info->brcmnand.chip_shift = 0; // Only 1 chip //info->brcmnand.regs = pdev->resource[0].start; info->brcmnand.priv = &info->mtd; //info->brcmnand.mmcontrol = NULL; // THT: Sync Burst Read TBD. pdata->mmcontrol; info->mtd.name = dev_name(&pdev->dev); info->mtd.priv = &info->brcmnand; info->mtd.owner = THIS_MODULE; /* Enable the following for a flash based bad block table */ info->brcmnand.options |= NAND_USE_FLASH_BBT; //printk("brcmnand_scan\n"); if (brcmnand_scan(&info->mtd, gNumNand)) { err = -ENXIO; goto out_free_info; } printk(" numchips=%d, size=%llx\n", info->brcmnand.numchips, device_size(&(info->mtd))); #ifdef CONFIG_MTD_PARTITIONS /* allow cmdlineparts to override the default map */ err = parse_mtd_partitions(&info->mtd, part_probe_types, &info->parts, 0); if (err > 0) { info->nr_parts = err; } else { info->parts = cfg->nr_parts ? cfg->parts : NULL; info->nr_parts = cfg->nr_parts; } if (info->nr_parts) add_mtd_partitions(&info->mtd, info->parts, info->nr_parts); else add_mtd_device(&info->mtd); #else add_mtd_device(&info->mtd); #endif //printk(" dev_set_drvdata\n"); dev_set_drvdata(&pdev->dev, info); //printk("<-- brcmnanddrv_probe\n"); return 0; out_free_info: if (gPageBuffer) kfree(gPageBuffer); kfree(info); return err; }
static int __devinit brcmnanddrv_probe(struct platform_device *pdev) { struct brcmnand_platform_data *cfg = pdev->dev.platform_data; static int csi; // Index into dev/nandInfo array int cs = cfg->chip_select; // Chip Select //int i; int err = 0; //static int numCSProcessed = 0; //int lastChip; struct brcmnand_info* info; //extern int dev_debug, gdebug; /* FOr now all devices share the same buffer */ if (!gPageBuffer) { #ifndef CONFIG_MTD_BRCMNAND_EDU gPageBuffer = kmalloc(sizeof(struct nand_buffers), GFP_KERNEL); #else /* Align on 32B boundary for efficient DMA transfer */ gPageBuffer = kmalloc(sizeof(struct nand_buffers) + 31, GFP_DMA); #endif } if (!gPageBuffer) { return -ENOMEM; } //gPageBuffer = NULL; info = kmalloc(sizeof(struct brcmnand_info), GFP_KERNEL); if (!info) return -ENOMEM; gNandInfo[csi] = info; memset(info, 0, sizeof(struct brcmnand_info)); /* * Since platform_data does not send us the number of NAND chips, * (until it's too late to be useful), we have to count it */ #ifdef BCHP_NAND_CS_NAND_SELECT { uint32_t nandSelect; /* Set NAND_CS_NAND_SELECT if not already set by CFE */ nandSelect = BDEV_RD(BCHP_NAND_CS_NAND_SELECT); nandSelect |= 0x100 << cs; BDEV_WR(BCHP_NAND_CS_NAND_SELECT, nandSelect); if (0 == gNumNand) { /* First CS */ brcmnand_sort_chipSelects(&info->brcmnand); gNumNand = info->brcmnand.numchips; } else { /* Subsequent CS */ brcmnand_sort_chipSelects(&info->brcmnand); info->brcmnand.numchips = gNumNand; } } #else /* Version 1.0 and earlier */ info->brcmnand.numchips = gNumNand = 1; #endif info->brcmnand.csi = csi; /* FOr now all devices share the same buffer */ #ifndef CONFIG_MTD_BRCMNAND_EDU info->brcmnand.buffers = (struct nand_buffers*) gPageBuffer; #else /* Align on 32B boundary for efficient DMA transfer */ info->brcmnand.buffers = (struct nand_buffers*) (((unsigned int) gPageBuffer+31) & (~31)); #endif info->brcmnand.numchips = gNumNand; info->brcmnand.chip_shift = 0; // Only 1 chip info->brcmnand.priv = &info->mtd; info->mtd.name = dev_name(&pdev->dev); info->mtd.priv = &info->brcmnand; info->mtd.owner = THIS_MODULE; /* Enable the following for a flash based bad block table */ info->brcmnand.options |= NAND_USE_FLASH_BBT; //cs = cfg->chip_select; //brcmnand_sort_chipSelects(&info->brcmnand); // Each chip now will have its own BBT (per mtd handle) // Problem is we don't know how many CS's we get, until its too late if (brcmnand_scan(&info->mtd, cs, gNumNand)) { err = -ENXIO; goto out_free_info; } PRINTK("Master size=%08llx\n", info->mtd.size); #ifdef CONFIG_MTD_PARTITIONS /* allow cmdlineparts to override the default map */ err = parse_mtd_partitions(&info->mtd, part_probe_types, &info->parts, 0); if (err > 0) { info->nr_parts = err; } else { info->parts = cfg->nr_parts ? cfg->parts : NULL; info->nr_parts = cfg->nr_parts; } // Add MTD partition have a dependency on the BBT if (info->nr_parts) // Primary mtd brcmnand_add_mtd_partitions(&info->mtd, info->parts, info->nr_parts); else // subsequent NAND only hold 1 partition, and is a brand new mtd device brcmnand_add_mtd_device(&info->mtd, csi); #else brcmnand_add_mtd_device(&info->mtd, csi); #endif PRINTK("After add_partitions: Master size=%08llx\n", info->mtd.size); dev_set_drvdata(&pdev->dev, info); csi++; return 0; out_free_info: if (gPageBuffer) kfree(gPageBuffer); kfree(info); return err; }