X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmmc%2Fhost%2Fau1xmmc.c;h=92c4d0dfee434d4d09eb5183314b2a1c3d09d9ed;hb=be0192aae1aed3fbf172e3f9a22ec75392c1b175;hp=b7156a4555b594b5cb036f3f68f987a24d1824e2;hpb=5c34202b8bf942da411b6599668a76b07449bbfd;p=linux-2.6-omap-h63xx.git diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index b7156a4555b..92c4d0dfee4 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -1,5 +1,5 @@ /* - * linux/drivers/mmc/au1xmmc.c - AU1XX0 MMC driver + * linux/drivers/mmc/host/au1xmmc.c - AU1XX0 MMC driver * * Copyright (c) 2005, Advanced Micro Devices, Inc. * @@ -76,8 +76,7 @@ const struct { #endif }; -#define AU1XMMC_CONTROLLER_COUNT \ - (sizeof(au1xmmc_card_table) / sizeof(au1xmmc_card_table[0])) +#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table)) /* This array stores pointers for the hosts (used by the IRQ handler) */ struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT]; @@ -187,9 +186,8 @@ static void au1xmmc_tasklet_finish(unsigned long param) } static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, - struct mmc_command *cmd) + struct mmc_command *cmd, struct mmc_data *data) { - u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); switch (mmc_resp_type(cmd)) { @@ -210,27 +208,21 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, default: printk(KERN_INFO "au1xmmc: unhandled response type %02x\n", mmc_resp_type(cmd)); - return MMC_ERR_INVALID; + return -EINVAL; } - switch(cmd->opcode) { - case MMC_READ_SINGLE_BLOCK: - case SD_APP_SEND_SCR: - mmccmd |= SD_CMD_CT_2; - break; - case MMC_READ_MULTIPLE_BLOCK: - mmccmd |= SD_CMD_CT_4; - break; - case MMC_WRITE_BLOCK: - mmccmd |= SD_CMD_CT_1; - break; - - case MMC_WRITE_MULTIPLE_BLOCK: - mmccmd |= SD_CMD_CT_3; - break; - case MMC_STOP_TRANSMISSION: - mmccmd |= SD_CMD_CT_7; - break; + if (data) { + if (flags & MMC_DATA_READ) { + if (data->blocks > 1) + mmccmd |= SD_CMD_CT_4; + else + mmccmd |= SD_CMD_CT_2; + } else if (flags & MMC_DATA_WRITE) { + if (data->blocks > 1) + mmccmd |= SD_CMD_CT_3; + else + mmccmd |= SD_CMD_CT_1; + } } au_writel(cmd->arg, HOST_CMDARG(host)); @@ -263,7 +255,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, IRQ_ON(host, SD_CONFIG_CR); } - return MMC_ERR_NONE; + return 0; } static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) @@ -288,7 +280,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) status = au_readl(HOST_STATUS(host)); - data->error = MMC_ERR_NONE; + data->error = 0; dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); /* Process any errors */ @@ -298,14 +290,14 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) crc |= ((status & 0x07) == 0x02) ? 0 : 1; if (crc) - data->error = MMC_ERR_BADCRC; + data->error = -EILSEQ; /* Clear the CRC bits */ au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); data->bytes_xfered = 0; - if (data->error == MMC_ERR_NONE) { + if (!data->error) { if (host->flags & HOST_F_DMA) { u32 chan = DMA_CHANNEL(host); @@ -485,7 +477,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) return; cmd = mrq->cmd; - cmd->error = MMC_ERR_NONE; + cmd->error = 0; if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { @@ -522,11 +514,11 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) /* Figure out errors */ if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC)) - cmd->error = MMC_ERR_BADCRC; + cmd->error = -EILSEQ; trans = host->flags & (HOST_F_XMIT | HOST_F_RECV); - if (!trans || cmd->error != MMC_ERR_NONE) { + if (!trans || cmd->error) { IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF); tasklet_schedule(&host->finish_task); @@ -599,7 +591,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) data->sg_len, host->dma.dir); if (host->dma.len == 0) - return MMC_ERR_TIMEOUT; + return -ETIMEDOUT; au_writel(data->blksz - 1, HOST_BLKSIZE(host)); @@ -650,11 +642,11 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF); } - return MMC_ERR_NONE; + return 0; dataerr: dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir); - return MMC_ERR_TIMEOUT; + return -ETIMEDOUT; } /* static void au1xmmc_request @@ -665,7 +657,8 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) { struct au1xmmc_host *host = mmc_priv(mmc); - int ret = MMC_ERR_NONE; + unsigned int flags = 0; + int ret = 0; WARN_ON(irqs_disabled()); WARN_ON(host->status != HOST_S_IDLE); @@ -677,13 +670,14 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) if (mrq->data) { FLUSH_FIFO(host); + flags = mrq->data->flags; ret = au1xmmc_prepare_data(host, mrq->data); } - if (ret == MMC_ERR_NONE) - ret = au1xmmc_send_command(host, 0, mrq->cmd); + if (!ret) + ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data); - if (ret != MMC_ERR_NONE) { + if (ret) { mrq->cmd->error = ret; au1xmmc_finish_request(host); } @@ -772,10 +766,10 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) if (host->mrq && (status & STATUS_TIMEOUT)) { if (status & SD_STATUS_RAT) - host->mrq->cmd->error = MMC_ERR_TIMEOUT; + host->mrq->cmd->error = -ETIMEDOUT; else if (status & SD_STATUS_DT) - host->mrq->data->error = MMC_ERR_TIMEOUT; + host->mrq->data->error = -ETIMEDOUT; /* In PIO mode, interrupts might still be enabled */ IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);