Ejemplo n.º 1
0
static void ak98_sdio_start_command(struct ak98_mci_host *host, struct mmc_command *cmd)
{
	unsigned int c;
	void __iomem *base = host->base;

	PK1("%s: op %i arg 0x%08x flags 0x%08x\n",
	       __func__, cmd->opcode, cmd->arg, cmd->flags);

	if (readl(base + AK98MCICOMMAND) & MCI_CPSM_ENABLE) {
		writel(0, base + AK98MCICOMMAND);
		udelay(1);
	}

	c = MCI_CPSM_CMD(cmd->opcode) | MCI_CPSM_ENABLE;
	if (cmd->flags & MMC_RSP_PRESENT) {
		c |= MCI_CPSM_RESPONSE;
		if (cmd->flags & MMC_RSP_136)
			c |= MCI_CPSM_LONGRSP;
	}

	if (cmd->data)
		c |= MCI_CPSM_WITHDATA;

	host->cmd = cmd;

	writel(cmd->arg, base + AK98MCIARGUMENT);
	writel(readl(base + AK98MCIMASK) | MCI_CMDIRQMASKS, base + AK98MCIMASK);
	PK("ENABLE CMD IRQ\n");
	PK("irqmask: 0x%08x\n", readl(base+AK98MCIMASK));
	writel(c, base + AK98MCICOMMAND);
}
Ejemplo n.º 2
0
static void ak98_sdio_stop_data(struct ak98_mci_host *host)
{
	u32 masks;

	PK1("%s\n", __func__);

	writel(0, host->base + AK98MCIDMACTRL);
	writel(0, host->base + AK98MCIDATACTRL);
	masks = readl(host->base + AK98MCIMASK);
	masks &= ~(MCI_DATAIRQMASKS|MCI_FIFOFULLMASK|MCI_FIFOEMPTYMASK);
	writel(masks, host->base + AK98MCIMASK);
	PK("DISABLE DATA IRQ\n"); 
     
#ifdef MCI_USE_L2FIFO_DMA
	if (host->data->flags & MMC_DATA_WRITE) {
		dma_sync_sg_for_cpu(mmc_dev(host->mmc), host->data->sg, host->data->sg_len, DMA_TO_DEVICE);
		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->data->sg_len, DMA_TO_DEVICE);
	} else {
		dma_sync_sg_for_cpu(mmc_dev(host->mmc), host->data->sg, host->data->sg_len, DMA_FROM_DEVICE);
		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->data->sg_len, DMA_FROM_DEVICE);
	}
#endif

	host->data = NULL; 
	
}
Ejemplo n.º 3
0
static void ak98_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct ak98_mci_host *host = mmc_priv(mmc);	

	PK1("%s: CMD%i\n", __func__, mrq->cmd->opcode);
	
	host->mrq = mrq;	

    if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
        printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
               mmc_hostname(mmc), mrq->data->blksz);
        mrq->cmd->error = -EINVAL;
        mmc_request_done(mmc, mrq);
        return;
    }

    if (ak98_mci_get_cd(mmc) == 0)
    {
        printk("%s: no medium present\n", __func__);
		host->mrq->cmd->error = -ENOMEDIUM;
		mmc_request_done(mmc, mrq);        
    }
    else
    {
        ak98_mci_send_request(mmc); 
    }	
	
}
Ejemplo n.º 4
0
static void ak98_mci_request_end(struct ak98_mci_host *host, struct mmc_request *mrq)
{
    int not_retry = 0;
    PK1("%s\n", __func__);

	writel(0, host->base + AK98MCICOMMAND);
	   
	BUG_ON(host->data);

	host->mrq = NULL;
	host->cmd = NULL;

    if(l2_mci_bufid != BUF_NULL)
    {
        ak98_l2_free(ADDR_MMC_SD);
        l2_mci_bufid = BUF_NULL;
    }

	if (mrq->data)
		mrq->data->bytes_xfered = host->data_xfered;
	
	/*
	 * Need to drop the host lock here; mmc_request_done may call
	 * back into the driver...
	 */
	spin_unlock(&host->lock);
	
    not_retry = (!mrq->cmd->error) || ((mrq->cmd->error && (mrq->cmd->retries == 0)));
    mmc_request_done(host->mmc, mrq);
    
#ifdef CONFIG_MTD_NAND_AK98

    /*if request fail,then mmc_request_done send request again, 
        * ak98_mci_send_request not down nand_lock in interrupt,so not to up nand_lock.
        */
    if (not_retry) 
    {           
        up(&nand_lock);
    }
#endif

#ifdef CONFIG_CPU_FREQ
	 /*if request fail,then mmc_request_done send request again, 
	   * ak98_mci_send_request not down freq_lock in interrupt,so not to unlock freq_lock.
	   */

	 if (not_retry) 
	 {					   
		 up(&host->freq_lock);
	 }	  
#endif

	spin_lock(&host->lock);
}
Ejemplo n.º 5
0
static void ak98_sdio_data_irq(struct ak98_mci_host *host, struct mmc_data *data,
		  unsigned int status)
{
	if (status & MCI_DATABLOCKEND) {
		PK("BLOCKEND\n");
#ifdef AKMCI_L2FIFO_PIO
        if (data->flags & MMC_DATA_WRITE)
        {
            ak98_l2_clr_status(l2_sdio_bufid);
        }
		if (host->size > 0)
			mci_xfer(host);
		
#endif
	}
	if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT)) {
		PK1("DATA ERROR: 0x%08x\n", status);

		if (status & MCI_DATACRCFAIL )
			data->error = -EILSEQ;
		else if (status & MCI_DATATIMEOUT)
			data->error = -ETIMEDOUT;
		status |= MCI_DATAEND;
		/*
		 * We hit an error condition.  Ensure that any data
		 * partially written to a page is properly coherent.
		 */
		if (host->sg_len && data->flags & MMC_DATA_READ)
			flush_dcache_page(sg_page(host->sg_ptr));
	}
	if (status & MCI_DATAEND) {
		ak98_sdio_stop_data(host);

		//dump_data(data);

		if (!data->stop) {
			ak98_sdio_request_end(host, data->mrq);
		} else {
			ak98_sdio_start_command(host, data->stop);
		}
	}
}
Ejemplo n.º 6
0
static void ak98_sdio_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct ak98_mci_host *host = mmc_priv(mmc);	

	PK1("%s: CMD%i\n", __func__, mrq->cmd->opcode);
	
	host->mrq = mrq;	

    if (ak98_sdio_get_cd(mmc) == 0)
    {
        printk("%s: no medium present\n", __func__);
		host->mrq->cmd->error = -ENOMEDIUM;
		mmc_request_done(mmc, mrq);        
    }
    else
    {
        ak98_sdio_send_request(mmc); 
    }	
	
}