static irqreturn_t stmp_appuart_irq_rx(int irq, void *context)
{
	struct stmp_appuart_port *s = context;
	int count = -1;

	stmp3xxx_dma_clear_interrupt(s->dma_rx);
	dev_dbg(s->dev, "%s(%d), count = %d\n", __func__, irq, count);

#ifndef RX_CHAIN
	stmp_appuart_rx(s, s->rx_desc.virtual_buf_ptr, count);
	stmp_appuart_submit_rx(s);
#else
	if (circ_advance_cooked(&s->rx_chain) == 0) {
		BUG();
		return IRQ_HANDLED;
	}

	circ_advance_active(&s->rx_chain, 1);
	while (s->rx_chain.cooked_count) {
		stmp_appuart_rx(s,
			stmp3xxx_dma_circ_get_cooked_head(&s->rx_chain)->
				virtual_buf_ptr, -1);
		circ_advance_free(&s->rx_chain, 1);
	}
#endif
	return IRQ_HANDLED;
}
예제 #2
0
/**
 * queue_run - run the chain
 *
 * @priv:	 private data.
 */
int queue_run(void *priv)
{
	struct gpmi_perchip_data *g = priv;

	if (!g->d_tail)
		return 0;
	stmp3xxx_dma_reset_channel(g->dma_ch);
	stmp3xxx_dma_clear_interrupt(g->dma_ch);
	stmp3xxx_dma_enable_interrupt(g->dma_ch);

	g->d[g->d_tail-1].command->cmd &= ~(BM_APBH_CHn_CMD_NANDLOCK |
				       BM_APBH_CHn_CMD_CHAIN);
	g->d[g->d_tail-1].command->cmd |= BM_APBH_CHn_CMD_IRQONCMPLT ;

	g->d[g->d_tail-1].command->pio_words[0] &= ~BM_GPMI_CTRL0_LOCK_CS;

#ifdef DEBUG
	/*stmp37cc_dma_print_chain(&g->chain);*/
#endif

	init_completion(&g->done);
	stmp3xxx_dma_go(g->dma_ch, g->d, 1);
	wait_for_completion(&g->done);

	g->d_tail = 0;

	return 0;

}
예제 #3
0
/* Allocate and initialise the DMA chains */
static int stmp3xxx_mmc_dma_init(struct stmp3xxx_mmc_host *host, int reset)
{
	int ret;

	if (!reset) {
		/* Allocate DMA channel */
		ret = stmp3xxx_dma_request(host->dmach,
					   host->dev, "STMP37XX MMC/SD");
		if (ret) {
			dev_err(host->dev, "Unable to request DMA channel\n");
			return ret;
		}

		host->dma_buf = dma_alloc_coherent(host->dev, SSP_BUFFER_SIZE,
						   &host->dma_buf_phys,
						   GFP_DMA);
		if (host->dma_buf == NULL) {
			dev_err(host->dev, "Unable to allocate DMA memory\n");
			ret = -ENOMEM;
			goto out_mem;
		}

		ret = stmp3xxx_dma_allocate_command(host->dmach,
						    &host->dma_desc);
		if (ret) {
			dev_err(host->dev,
				"Unable to allocate DMA descriptor\n");
			goto out_cmd;
		}

		host->dma_desc.command->next = (u32) host->dma_desc.handle;
		host->dma_desc.command->buf_ptr = (u32) host->dma_buf_phys;
		host->dma_desc.virtual_buf_ptr = host->dma_buf;
	}

	/* Reset DMA channel */
	stmp3xxx_dma_reset_channel(host->dmach);

	/* Enable DMA interrupt */
	stmp3xxx_dma_clear_interrupt(host->dmach);
	stmp3xxx_dma_enable_interrupt(host->dmach);

	return 0;

out_cmd:
	dma_free_coherent(host->dev, SSP_BUFFER_SIZE, host->dma_buf,
			  host->dma_buf_phys);
out_mem:
	stmp3xxx_dma_release(host->dmach);

	return ret;
}
/**
 * gpmi_irq - IRQ handler
 *
 * @irq:	irq no
 * @context:	IRQ context, pointer to gpmi_nand_data
 */
static irqreturn_t gpmi_irq(int irq, void *context)
{
	struct lba_data *data = context;
	int i;

	for (i = 0; i < max_chips; i++) {
		if (stmp3xxx_dma_is_interrupt(data->nand[i].dma_ch)) {
			stmp3xxx_dma_clear_interrupt(data->nand[i].dma_ch);
			complete(&data->nand[i].done);
		}

	}
	HW_GPMI_CTRL1_CLR(BM_GPMI_CTRL1_DEV_IRQ | BM_GPMI_CTRL1_TIMEOUT_IRQ);
	return IRQ_HANDLED;
}
static irqreturn_t stmp_appuart_irq_tx(int irq, void *context)
{
	struct stmp_appuart_port *s = context;
	struct uart_port *u = &s->port;
	int bytes;

	stmp3xxx_dma_clear_interrupt(s->dma_tx);
	dev_dbg(s->dev, "%s(%d)\n", __func__, irq);

	bytes = stmp_appuart_copy_tx(u, s->tx_desc.virtual_buf_ptr,
			TX_BUFFER_SIZE);
	if (bytes > 0) {
		dev_dbg(s->dev, "Sending %d bytes\n", bytes);
		stmp_appuart_submit_tx(s, bytes);
	}
	return IRQ_HANDLED;
}
예제 #6
0
/* SSP DMA interrupt handler */
static irqreturn_t mmc_irq_handler(int irq, void *dev_id)
{
	struct stmp3xxx_mmc_host *host = dev_id;
	u32 c1;

	c1 = __raw_readl(host->ssp_base + HW_SSP_CTRL1);
	__raw_writel(c1 & STMP3XXX_MMC_IRQ_BITS,
			host->ssp_base + HW_SSP_CTRL1_CLR);
	if (irq == host->dmairq)
		stmp3xxx_dma_clear_interrupt(host->dmach);
	host->status =
	    __raw_readl(host->ssp_base + HW_SSP_STATUS);

	if (host->cmd)		/* else it is a bogus interrupt */
		complete(&host->dma_done);

	return IRQ_HANDLED;
}
예제 #7
0
int stmp3xxx_lcdif_dma_init(struct device *dev, dma_addr_t phys, int memsize,
			    int lcd_master)
{
	int ret = 0;

	stmp378x_lcd_master = lcd_master;
	if (lcd_master) {
		stmp3xxx_setl(BM_LCDIF_CTRL_LCDIF_MASTER,
			      REGS_LCDIF_BASE + HW_LCDIF_CTRL);

		__raw_writel(phys, REGS_LCDIF_BASE + HW_LCDIF_CUR_BUF);
		__raw_writel(phys, REGS_LCDIF_BASE + HW_LCDIF_NEXT_BUF);
	} else {
		ret =
		    stmp3xxx_dma_request(STMP3XXX_DMA
					 (LCD_DMA_CHANNEL, STMP3XXX_BUS_APBH),
					 dev, "lcdif");
		if (ret) {
			dev_err(dev,
				"stmp3xxx_dma_request failed: error %d\n", ret);
			goto out;
		}

		stmp3xxx_dma_reset_channel(STMP3XXX_DMA
					   (LCD_DMA_CHANNEL,
					    STMP3XXX_BUS_APBH));

		stmp3xxx_dma_clear_interrupt(STMP3XXX_DMA
					     (LCD_DMA_CHANNEL,
					      STMP3XXX_BUS_APBH));
		stmp3xxx_dma_enable_interrupt(STMP3XXX_DMA
					      (LCD_DMA_CHANNEL,
					       STMP3XXX_BUS_APBH));

		dotclk_dma_chain_init(memsize, phys, video_dma_descriptor,
				      dma_chain_info, &dma_chain_info_pos);
	}
out:
	return ret;
}