예제 #1
0
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;
}
예제 #2
0
파일: sflash.c 프로젝트: Cribstone/linino
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;
}