예제 #1
0
파일: ndfc.c 프로젝트: 3null/linux
static int ndfc_probe(struct platform_device *ofdev)
{
	struct ndfc_controller *ndfc;
	const __be32 *reg;
	u32 ccr;
	u32 cs;
	int err, len;

	/* Read the reg property to get the chip select */
	reg = of_get_property(ofdev->dev.of_node, "reg", &len);
	if (reg == NULL || len != 12) {
		dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
		return -ENOENT;
	}

	cs = be32_to_cpu(reg[0]);
	if (cs >= NDFC_MAX_CS) {
		dev_err(&ofdev->dev, "invalid CS number (%d)\n", cs);
		return -EINVAL;
	}

	ndfc = &ndfc_ctrl[cs];
	ndfc->chip_select = cs;

	spin_lock_init(&ndfc->ndfc_control.lock);
	init_waitqueue_head(&ndfc->ndfc_control.wq);
	ndfc->ofdev = ofdev;
	dev_set_drvdata(&ofdev->dev, ndfc);

	ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);
	if (!ndfc->ndfcbase) {
		dev_err(&ofdev->dev, "failed to get memory\n");
		return -EIO;
	}

	ccr = NDFC_CCR_BS(ndfc->chip_select);

	/* It is ok if ccr does not exist - just default to 0 */
	reg = of_get_property(ofdev->dev.of_node, "ccr", NULL);
	if (reg)
		ccr |= be32_to_cpup(reg);

	out_be32(ndfc->ndfcbase + NDFC_CCR, ccr);

	/* Set the bank settings if given */
	reg = of_get_property(ofdev->dev.of_node, "bank-settings", NULL);
	if (reg) {
		int offset = NDFC_BCFG0 + (ndfc->chip_select << 2);
		out_be32(ndfc->ndfcbase + offset, be32_to_cpup(reg));
	}

	err = ndfc_chip_init(ndfc, ofdev->dev.of_node);
	if (err) {
		iounmap(ndfc->ndfcbase);
		return err;
	}

	return 0;
}
예제 #2
0
static int __devinit ndfc_probe(struct of_device *ofdev,
				const struct of_device_id *match)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	const u32 *reg;
	u32 ccr;
	int err, len;

	spin_lock_init(&ndfc->ndfc_control.lock);
	init_waitqueue_head(&ndfc->ndfc_control.wq);
	ndfc->ofdev = ofdev;
	dev_set_drvdata(&ofdev->dev, ndfc);

	
	reg = of_get_property(ofdev->node, "reg", &len);
	if (reg == NULL || len != 12) {
		dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
		return -ENOENT;
	}
	ndfc->chip_select = reg[0];

	ndfc->ndfcbase = of_iomap(ofdev->node, 0);
	if (!ndfc->ndfcbase) {
		dev_err(&ofdev->dev, "failed to get memory\n");
		return -EIO;
	}

	ccr = NDFC_CCR_BS(ndfc->chip_select);

	
	reg = of_get_property(ofdev->node, "ccr", NULL);
	if (reg)
		ccr |= *reg;

	out_be32(ndfc->ndfcbase + NDFC_CCR, ccr);

	
	reg = of_get_property(ofdev->node, "bank-settings", NULL);
	if (reg) {
		int offset = NDFC_BCFG0 + (ndfc->chip_select << 2);
		out_be32(ndfc->ndfcbase + offset, *reg);
	}

	err = ndfc_chip_init(ndfc, ofdev->node);
	if (err) {
		iounmap(ndfc->ndfcbase);
		return err;
	}

	return 0;
}
예제 #3
0
static int ndfc_chip_probe(struct platform_device *pdev)
{
	struct platform_nand_chip *nc = pdev->dev.platform_data;
	struct ndfc_chip_settings *settings = nc->priv;
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	struct ndfc_nand_mtd *nandmtd;

	if (nc->chip_offset >= NDFC_MAX_BANKS || nc->nr_chips > NDFC_MAX_BANKS)
		return -EINVAL;

	/* Set the bank settings */
	__raw_writel(settings->bank_settings,
		     ndfc->ndfcbase + NDFC_BCFG0 + (nc->chip_offset << 2));

	nandmtd = &ndfc_mtd[pdev->id];
	if (nandmtd->pl_chip)
		return -EBUSY;

	nandmtd->pl_chip = nc;
	ndfc_chip_init(nandmtd);

	/* Scan for chips */
	if (nand_scan(&nandmtd->mtd, nc->nr_chips)) {
		nandmtd->pl_chip = NULL;
		return -ENODEV;
	}

#ifdef CONFIG_MTD_PARTITIONS
	printk("Number of partitions %d\n", nc->nr_partitions);
	if (nc->nr_partitions) {
		/* Add the full device, so complete dumps can be made */
		add_mtd_device(&nandmtd->mtd);
		add_mtd_partitions(&nandmtd->mtd, nc->partitions,
				   nc->nr_partitions);

	} else
#else
		add_mtd_device(&nandmtd->mtd);
#endif

	atomic_inc(&ndfc->childs_active);
	return 0;
}