Example #1
0
static int __init lba_probe(struct platform_device *pdev)
{
	struct lba_data *data;
	struct resource *r;
	struct gpmi_perchip_data *g;
	int err;

	/* Allocate memory for the device structure (and zero it) */
	data = kzalloc(sizeof(*data) + sizeof(struct gpmi_perchip_data),
		       GFP_KERNEL);
	if (!data) {
		dev_err(&pdev->dev, "failed to allocate gpmi_nand_data\n");
		err = -ENOMEM;
		goto out1;
	}
	g_data = data;
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "failed to get resource\n");
		err = -ENXIO;
		goto out2;
	}
	data->io_base = ioremap(r->start, r->end - r->start + 1);
	if (!data->io_base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -EIO;
		goto out2;
	}

	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!r) {
		err = -EIO;
		dev_err(&pdev->dev, "can't get IRQ resource\n");
		goto out3;
	}
	data->irq = r->start;

	platform_set_drvdata(pdev, data);
	err = gpmi_init_hw(pdev, 1);
	if (err)
		goto out3;


	err = request_irq(data->irq,
			  gpmi_irq, 0, dev_name(&pdev->dev), data);
	if (err) {
		dev_err(&pdev->dev, "can't request GPMI IRQ\n");
		goto out4;
	}

	g = data->nand;

	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!r) {
		dev_err(&pdev->dev, "can't get DMA resource\n");
		goto out_res;
	}
	g->cs = 0;
	g->dma_ch = r->start;

	err = stmp3xxx_dma_request(g->dma_ch, NULL, dev_name(&pdev->dev));
	if (err) {
		dev_err(&pdev->dev, "can't request DMA channel 0x%x\n",
			g->dma_ch);
		goto out_res;
	}

	err = stmp3xxx_dma_make_chain(g->dma_ch, &g->chain,
				      g->d, ARRAY_SIZE(g->d));
	if (err) {
		dev_err(&pdev->dev, "can't setup DMA chain\n");
		stmp3xxx_dma_release(g->dma_ch);
		goto out_res;
	}

	g->cmd_buffer_size = GPMI_CMD_BUF_SZ;
	g->cmdtail_buffer_size = GPMI_CMD_BUF_SZ;
	g->write_buffer_size = GPMI_WRITE_BUF_SZ;
	g->data_buffer_size = GPMI_DATA_BUF_SZ;
	g->oob_buffer_size = GPMI_OOB_BUF_SZ;

	err = gpmi_alloc_buffers(pdev, g);
	if (err) {
		dev_err(&pdev->dev, "can't setup buffers\n");
		stmp3xxx_dma_free_chain(&g->chain);
		stmp3xxx_dma_release(g->dma_ch);
		goto out_res;
	}

	g->dev = pdev;
	g->chip.priv = g;
	g->index = 0;
	g->timing = gpmi_safe_timing;

	g->cmd_buffer_sz =
		g->write_buffer_sz =
		g->data_buffer_sz =
		0;
	g->valid = !0;	/* mark the data as valid */


	lba_core_init(data);

	return 0;

out_res:
	free_irq(data->irq, data);
out4:
	gpmi_release_hw(pdev);
out3:
	platform_set_drvdata(pdev, NULL);
	iounmap(data->io_base);
out2:
	kfree(data);
out1:
	return err;
}
/* Allocate and initialize rx and tx DMA chains */
static inline int stmp_appuart_dma_init(struct stmp_appuart_port *s)
{
	int err = 0;
	struct stmp3xxx_dma_descriptor *t = &s->tx_desc;
#ifndef RX_CHAIN
	struct stmp3xxx_dma_descriptor *r = &s->rx_desc;
#else
	int i;
#endif

	err = stmp3xxx_dma_request(s->dma_rx, s->dev, s->dev->bus_id);
	if (err)
		goto out;
	err = stmp3xxx_dma_request(s->dma_tx, s->dev, s->dev->bus_id);
	if (err)
		goto out1;

#ifndef RX_CHAIN
	err = stmp3xxx_dma_allocate_command(s->dma_rx, r);
	if (err)
		goto out2;
#endif
	err = stmp3xxx_dma_allocate_command(s->dma_tx, t);
	if (err)
		goto out3;
	t->virtual_buf_ptr = dma_alloc_coherent(s->dev,
					   TX_BUFFER_SIZE,
					   &t->command->buf_ptr,
					   GFP_DMA);
	if (!t->virtual_buf_ptr)
		goto out4;
#ifdef DEBUG
	memset(t->virtual_buf_ptr, 0x4B, TX_BUFFER_SIZE);
#endif

#ifndef RX_CHAIN
	r->virtual_buf_ptr = dma_alloc_coherent(s->dev,
					   RX_BUFFER_SIZE,
					   &r->command->buf_ptr,
					   GFP_DMA);
	if (!r->virtual_buf_ptr)
		goto out5;
#ifdef DEBUG
	memset(r->virtual_buf_ptr, 0x4C, RX_BUFFER_SIZE);
#endif
#else
	stmp3xxx_dma_make_chain(s->dma_rx, &s->rx_chain, s->rxd, RX_CHAIN);
	for (i = 0; i < RX_CHAIN; i++) {
		struct stmp3xxx_dma_descriptor *r = s->rxd + i;

		r->command->cmd =
			BF_APBX_CHn_CMD_XFER_COUNT(RX_BUFFER_SIZE) |
			BF_APBX_CHn_CMD_CMDWORDS(1) |
			BM_APBX_CHn_CMD_WAIT4ENDCMD |
			BM_APBX_CHn_CMD_SEMAPHORE |
			BM_APBX_CHn_CMD_IRQONCMPLT |
			BM_APBX_CHn_CMD_CHAIN |
			BF_APBX_CHn_CMD_COMMAND(
				BV_APBX_CHn_CMD_COMMAND__DMA_WRITE);
		r->virtual_buf_ptr = dma_alloc_coherent(s->dev,
					   RX_BUFFER_SIZE,
					   &r->command->buf_ptr,
					   GFP_DMA);
		r->command->pio_words[0] = /* BM_UARTAPP_CTRL0_RUN | */
			BF_UARTAPP_CTRL0_XFER_COUNT(RX_BUFFER_SIZE)|
			BM_UARTAPP_CTRL0_RXTO_ENABLE |
			BF_UARTAPP_CTRL0_RXTIMEOUT(3);
	}
#endif
	return 0;

	/*
	 * would be necessary on other error paths

	dma_free_coherent( s->dev, RX_BUFFER_SIZE, r->virtual_buf_ptr,
			   r->command->buf_ptr);
	*/
out5:
	dma_free_coherent(s->dev, TX_BUFFER_SIZE, t->virtual_buf_ptr,
			   t->command->buf_ptr);
out4:
	stmp3xxx_dma_free_command(s->dma_tx, t);
out3:
#ifndef RX_CHAIN
	stmp3xxx_dma_free_command(s->dma_rx, r);
#endif
out2:
	stmp3xxx_dma_release(s->dma_tx);
out1:
	stmp3xxx_dma_release(s->dma_rx);
out:
	WARN_ON(err);
	return err;
}