static int __init init_bcm947xx_map(void) { ulong flags; uint coreidx; chipcregs_t *cc; uint32 fltype; uint window_addr = 0, window_size = 0; size_t size; int ret = 0; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *parts; #endif spin_lock_irqsave(&sih_lock, flags); coreidx = si_coreidx(sih); /* Check strapping option if chipcommon exists */ if ((cc = si_setcore(sih, CC_CORE_ID, 0))) { fltype = readl(&cc->capabilities) & CC_CAP_FLASH_MASK; if (fltype == PFLASH) { bcm947xx_map.map_priv_2 = 1; window_addr = 0x1c000000; bcm947xx_map.size = window_size = 32 * 1024 * 1024; if ((readl(&cc->flash_config) & CC_CFG_DS) == 0) bcm947xx_map.bankwidth = 1; } } else { fltype = PFLASH; bcm947xx_map.map_priv_2 = 0; window_addr = WINDOW_ADDR; bcm947xx_map.size = window_size = WINDOW_SIZE; } si_setcoreidx(sih, coreidx); spin_unlock_irqrestore(&sih_lock, flags); if (fltype != PFLASH) { printk(KERN_ERR "pflash: found no supported devices\n"); ret = -ENODEV; goto fail; } bcm947xx_map.virt = ioremap(window_addr, window_size); if (bcm947xx_map.virt == NULL) { printk(KERN_ERR "pflash: ioremap failed\n"); ret = -EIO; goto fail; } if ((bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map)) == NULL) { printk(KERN_ERR "pflash: cfi_probe failed\n"); ret = -ENXIO; goto fail; } bcm947xx_mtd->owner = THIS_MODULE; /* Allow size override for testing */ size = flash ? : bcm947xx_mtd->size; printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr); #ifdef CONFIG_MTD_PARTITIONS parts = init_mtd_partitions(bcm947xx_mtd, size); ret = add_mtd_partitions(bcm947xx_mtd, parts, 4); if (ret) { printk(KERN_ERR "pflash: add_mtd_partitions failed\n"); goto fail; } #endif return 0; fail: if (bcm947xx_mtd) map_destroy(bcm947xx_mtd); if (bcm947xx_map.map_priv_1) iounmap((void *) bcm947xx_map.map_priv_1); bcm947xx_map.map_priv_1 = 0; return ret; }
mod_init_t sflash_mtd_init(void) { struct pci_dev *pdev; int ret = 0; struct sflash *info; uint i; #ifdef CONFIG_MTD_PARTITIONS struct mtd_partition *parts; #endif if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_CC, NULL))) { printk(KERN_ERR "sflash: chipcommon not found\n"); return -ENODEV; } memset(&sflash, 0, sizeof(struct sflash_mtd)); init_MUTEX(&sflash.lock); /* attach to the backplane */ if (!(sflash.sbh = sb_kattach(SB_OSH))) { printk(KERN_ERR "sflash: error attaching to backplane\n"); ret = -EIO; goto fail; } /* Map registers and flash base */ if (!(sflash.cc = ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)))) { printk(KERN_ERR "sflash: error mapping registers\n"); ret = -EIO; goto fail; } /* Initialize serial flash access */ if (!(info = sflash_init(sflash.sbh, sflash.cc))) { printk(KERN_ERR "sflash: found no supported devices\n"); ret = -ENODEV; goto fail; } printk(KERN_INFO "sflash: found serial flash; blocksize=%dKB, numblocks=%d, size=%dKB\n",info->blocksize/1024,info->numblocks,info->size/1024); /* Setup region info */ sflash.region.offset = 0; sflash.region.erasesize = info->blocksize; sflash.region.numblocks = info->numblocks; if (sflash.region.erasesize > sflash.mtd.erasesize) sflash.mtd.erasesize = sflash.region.erasesize; sflash.mtd.size = info->size; sflash.mtd.numeraseregions = 1; /* Register with MTD */ sflash.mtd.name = "sflash"; sflash.mtd.type = MTD_NORFLASH; sflash.mtd.flags = MTD_CAP_NORFLASH; sflash.mtd.eraseregions = &sflash.region; sflash.mtd.module = THIS_MODULE; sflash.mtd.erase = sflash_mtd_erase; sflash.mtd.read = sflash_mtd_read; sflash.mtd.write = sflash_mtd_write; sflash.mtd.priv = &sflash; #ifdef CONFIG_MTD_PARTITIONS parts = init_mtd_partitions(&sflash.mtd, sflash.mtd.size); for (i = 0; parts[i].name; i++); ret = add_mtd_partitions(&sflash.mtd, parts, i); #else ret = add_mtd_device(&sflash.mtd); #endif if (ret) { printk(KERN_ERR "sflash: add_mtd failed\n"); goto fail; } return 0; fail: if (sflash.cc) iounmap((void *) sflash.cc); if (sflash.sbh) sb_detach(sflash.sbh); return ret; }