Ejemplo n.º 1
0
void __init stx5206_configure_pata(struct stx5206_pata_config *config)
{
	unsigned long bank_base;

	if (!config) {
		BUG();
		return;
	}

	BUG_ON(config->emi_bank < 0 || config->emi_bank >= EMI_BANKS);
	BUG_ON(stx5206_emi_bank_configured[config->emi_bank]);
	stx5206_emi_bank_configured[config->emi_bank] = 1;

	bank_base = emi_bank_base(config->emi_bank);

	stx5206_pata_resources[0].start += bank_base;
	stx5206_pata_resources[0].end += bank_base;
	stx5206_pata_resources[1].start += bank_base;
	stx5206_pata_resources[1].end += bank_base;
	stx5206_pata_resources[2].start = config->irq;
	stx5206_pata_resources[2].end = config->irq;

	emi_config_pata(config->emi_bank, config->pc_mode);

	platform_device_register(&stx5206_pata_device);
}
Ejemplo n.º 2
0
static int __init db641_init(void)
{
	smsc_lan9117.resource[0].start = emi_bank_base(STEM_CS0_BANK)
			+ STEM_CS0_OFFSET;
	smsc_lan9117.resource[0].end = smsc_lan9117.resource[0].start + 0xff;
	
	smsc_lan9117.resource[1].start = STEM_INTR0_IRQ;
	smsc_lan9117.resource[1].end = smsc_lan9117.resource[1].start;

	emi_bank_configure(STEM_CS0_BANK, (unsigned long[4]){ 0x041086f1,
			0x0e024400, 0x0e024400, 0 });
/*
 * Probe for the NAND device.
 */
static int __init stm_nand_emi_probe(struct platform_device *pdev)
{
	struct platform_nand_data *pdata = pdev->dev.platform_data;
	struct plat_stmnand_data *stmdata = pdata->ctrl.priv;

	struct stm_nand_emi *data;
	struct nand_timing_data *tm;

	int res = 0;

	/* Allocate memory for the driver structure (and zero it) */
	data = kzalloc(sizeof(struct stm_nand_emi), GFP_KERNEL);
	if (!data) {
		printk(KERN_ERR NAME
		       ": Failed to allocate device structure.\n");
		return -ENOMEM;
	}

	/* Get EMI Bank base address */
	data->emi_bank = pdev->id;
	data->emi_base = emi_bank_base(data->emi_bank) +
		stmdata->emi_withinbankoffset;
	data->emi_size = (1 << 18) + 1;

	/* Configure EMI Bank */
	if (nand_config_emi(data->emi_bank, stmdata->timing_data) != 0) {
		printk(KERN_ERR NAME ": Failed to configure EMI bank "
		       "for NAND device\n");
		goto out1;
	}

	/* Request IO Memory */
	if (!request_mem_region(data->emi_base, data->emi_size, pdev->name)) {
		printk(KERN_ERR NAME ": Request mem 0x%x region failed\n",
		       data->emi_base);
		res = -ENODEV;
		goto out1;
	}

	/* Map base address */
	data->io_base = ioremap_nocache(data->emi_base, 4096);
	if (!data->io_base) {
		printk(KERN_ERR NAME ": ioremap failed for io_base 0x%08x\n",
		       data->emi_base);
		res = -ENODEV;
		goto out2;
	}

#ifdef CONFIG_STM_NAND_EMI_CACHED
	/* Map data address through cache line */
	data->io_data = ioremap_cache(data->emi_base + 4096, 4096);
	if (!data->io_data) {
		printk(KERN_ERR NAME ": ioremap failed for io_data 0x%08x\n",
		       data->emi_base + 4096);
		res = -ENOMEM;
		goto out3;
	}
#else
	data->io_data = data->io_base;
#endif
	/* Map cmd and addr addresses (emi_addr_17 and emi_addr_18) */
	data->io_cmd = ioremap_nocache(data->emi_base | (1 << 17), 1);
	if (!data->io_cmd) {
		printk(KERN_ERR NAME ": ioremap failed for io_cmd 0x%08x\n",
		       data->emi_base | (1 << 17));
		res = -ENOMEM;
		goto out4;
	}

	data->io_addr = ioremap_nocache(data->emi_base | (1 << 18), 1);
	if (!data->io_addr) {
		printk(KERN_ERR NAME ": ioremap failed for io_addr 0x%08x\n",
		       data->emi_base | (1 << 18));
		res = -ENOMEM;
		goto out5;
	}

	data->chip.priv = data;
	data->mtd.priv = &data->chip;
	data->mtd.owner = THIS_MODULE;

	/* Assign more sensible name (default is string from nand_ids.c!) */
	data->mtd.name = pdev->dev.bus_id;

	tm = stmdata->timing_data;

	data->chip.IO_ADDR_R = data->io_base;
	data->chip.IO_ADDR_W = data->io_base;
	data->chip.chip_delay = tm->chip_delay;
	data->chip.cmd_ctrl = nand_cmd_ctrl_emi;

	/* Do we have access to NAND_RBn? */
	if (stmdata->rbn_port >= 0) {
		data->rbn = stpio_request_pin(stmdata->rbn_port,
					      stmdata->rbn_pin,
					      "nand_RBn", STPIO_IN);
		if (data->rbn) {
			data->chip.dev_ready = nand_device_ready;
		} else {
			printk(KERN_INFO NAME ": nand_rbn unavailable. "
			       "Falling back to chip_delay\n");
			/* Set a default delay if not previosuly specified */
			if (data->chip.chip_delay == 0)
				data->chip.chip_delay = 30;
		}
	}

	/* Set IO routines for acessing NAND pages */
#if defined(CONFIG_STM_NAND_EMI_FDMA)
	data->chip.read_buf = nand_read_buf_dma;
	data->chip.write_buf = nand_write_buf_dma;
	data->dma_chan = -1;
	data->init_fdma_jiffies = 0;
	init_fdma_nand_ratelimit(data);
	data->nand_phys_addr = data->emi_base;

#elif defined(CONFIG_STM_NAND_EMI_LONGSL)
	data->chip.read_buf = nand_readsl_buf;
	data->chip.write_buf = nand_writesl_buf;

#elif defined(CONFIG_STM_NAND_EMI_CACHED)
	data->chip.read_buf = nand_read_buf_cached_block;
	data->chip.write_buf = nand_write_buf_cached_block;

#elif defined(CONFIG_STM_NAND_EMI_BYTE)
	/* Default byte orientated routines */
#else
#error "Must specify CONFIG_STM_NAND_EMI_xxxx mode"
#endif

	data->chip.ecc.mode = NAND_ECC_SOFT;

	/* Copy chip options from platform data */
	data->chip.options = pdata->chip.options;

	platform_set_drvdata(pdev, data);

	/* Scan to find existance of the device */
	if (nand_scan(&data->mtd, 1)) {
		printk(KERN_ERR NAME ": nand_scan failed\n");
		res = -ENXIO;
		goto out6;
	}

#ifdef CONFIG_MTD_PARTITIONS
	res = parse_mtd_partitions(&data->mtd, part_probes, &data->parts, 0);
	if (res > 0) {
		add_mtd_partitions(&data->mtd, data->parts, res);
		return 0;
	}
	if (pdata->chip.partitions) {
		data->parts = pdata->chip.partitions;
		res = add_mtd_partitions(&data->mtd, data->parts,
					 pdata->chip.nr_partitions);
	} else
#endif
		res = add_mtd_device(&data->mtd);
	if (!res)
		return res;

	/* Release resources on error */
 out6:

	nand_release(&data->mtd);
	if (data->rbn)
		stpio_free_pin(data->rbn);
	platform_set_drvdata(pdev, NULL);
	iounmap(data->io_addr);
 out5:
	iounmap(data->io_cmd);
 out4:
#ifdef CONFIG_STM_NAND_EMI_CACHED
	iounmap(data->io_data);
 out3:
#endif
	iounmap(data->io_base);
 out2:
	release_mem_region(data->emi_base, data->emi_size);
 out1:
	kfree(data);
	return res;
}