Line 34... |
Line 34... |
|
|
#define DRIVER_NAME "mmc-ocores"
|
#define DRIVER_NAME "mmc-ocores"
|
|
|
#define NR_SG 1
|
#define NR_SG 1
|
|
|
struct ocores_registers
|
|
{
|
|
unsigned int normal_int_status;
|
|
unsigned int error_int_status;
|
|
};
|
|
|
|
struct ocores_host {
|
struct ocores_host {
|
struct mmc_host *mmc;
|
struct mmc_host *mmc;
|
spinlock_t lock;
|
spinlock_t lock;
|
struct resource *res;
|
struct resource *res;
|
Line 86... |
Line 82... |
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
|
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
|
{
|
{
|
unsigned int cmd_arg, cmd_command=0;
|
unsigned int cmd_arg, cmd_command=0;
|
|
|
//struct mmc_data *data = cmd->data;
|
//struct mmc_data *data = cmd->data;
|
|
|
|
|
//WARN_ON(host->cmd != NULL);
|
//WARN_ON(host->cmd != NULL);
|
host->cmd = cmd;
|
host->cmd = cmd;
|
|
|
//Set up command
|
//Set up command
|
cmd_arg = cmd->arg;
|
cmd_arg = cmd->arg;
|
cmd_command |= cmd->opcode << 8;
|
cmd_command |= cmd->opcode << 8;
|
|
cmd_command |= host->word_cnt << 6;
|
|
|
|
if ( mmc_resp_type(cmd) == MMC_RSP_CRC )
|
|
cmd_command |= CRCE;
|
|
if ( mmc_resp_type(cmd) == MMC_RSP_OPCODE )
|
|
cmd_command |= CICE;
|
|
|
switch (mmc_resp_type(cmd)) {
|
switch (mmc_resp_type(cmd)) {
|
case MMC_RSP_NONE:
|
case MMC_RSP_NONE:
|
cmd_command |= MMCOC_RSP_NONE;
|
cmd_command |= MMCOC_RSP_NONE;
|
break;
|
break;
|
Line 111... |
Line 111... |
cmd_command |= MMCOC_RSP_136;
|
cmd_command |= MMCOC_RSP_136;
|
break;
|
break;
|
case MMC_RSP_R3:
|
case MMC_RSP_R3:
|
cmd_command |= MMCOC_RSP_48;
|
cmd_command |= MMCOC_RSP_48;
|
break;
|
break;
|
|
|
default:
|
default:
|
printk(KERN_INFO "mmc_ocores: unhandled response type %02x\n",
|
printk(KERN_INFO "mmc_ocores: unhandled response type %02x\n",
|
mmc_resp_type(cmd));
|
mmc_resp_type(cmd));
|
}
|
}
|
|
|
if ( mmc_resp_type(cmd) == MMC_RSP_CRC )
|
|
cmd_command |= CRCE;
|
|
if ( mmc_resp_type(cmd) == MMC_RSP_OPCODE )
|
|
cmd_command |= CICE;
|
|
|
|
|
|
printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
|
printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
|
printk(KERN_ALERT "%s: cmd_command = %08x\n", __FUNCTION__, cmd_command);
|
printk(KERN_ALERT "%s: cmd_command = %08x\n", __FUNCTION__, cmd_command);
|
|
oc_host=host;
|
|
|
CMD_IRQ_ON (host,ECC);
|
CMD_IRQ_ON (host,(ECC|EEI));
|
writel(cmd_command, host->base + SD_COMMAND);
|
writel(cmd_command, host->base + SD_COMMAND);
|
wmb();
|
wmb();
|
writel(cmd_arg, host->base + SD_ARG);
|
writel(cmd_arg, host->base + SD_ARG);
|
|
|
}
|
}
|
|
|
static void ocores_process_next(struct ocores_host *host)
|
static void ocores_process_next(struct ocores_host *host)
|
{
|
{
|
|
host->word_cnt=0;
|
if (!(host->flags & FL_SENT_COMMAND)) {
|
if (!(host->flags & FL_SENT_COMMAND)) {
|
host->flags |= FL_SENT_COMMAND;
|
host->flags |= FL_SENT_COMMAND;
|
ocores_start_cmd(host, host->mrq->cmd);
|
ocores_start_cmd(host, host->mrq->cmd);
|
}
|
}
|
else if ((!(host->flags & FL_SENT_STOP)) && host->mrq->stop) {
|
else if ((!(host->flags & FL_SENT_STOP)) && host->mrq->stop) {
|
Line 232... |
Line 227... |
host->registers.error_int_status = readl(host->base + SD_ERROR_INT_STATUS);
|
host->registers.error_int_status = readl(host->base + SD_ERROR_INT_STATUS);
|
|
|
writel(0,host->base + SD_NORMAL_INT_STATUS);
|
writel(0,host->base + SD_NORMAL_INT_STATUS);
|
writel(0,host->base + SD_ERROR_INT_STATUS);
|
writel(0,host->base + SD_ERROR_INT_STATUS);
|
|
|
printk(KERN_ALERT "%s: IRQ END***** Error In = %08x\n", __FUNCTION__, readl(host->base + SD_ERROR_INT_STATUS));
|
//printk(KERN_ALERT "%s: IRQ END***** Error In = %08x\n", __FUNCTION__, readl(host->base + SD_ERROR_INT_STATUS));
|
tasklet_schedule(&host->finish_cmd);
|
tasklet_schedule(&host->finish_cmd);
|
CMD_IRQ_OFF (host,ECC);
|
CMD_IRQ_OFF (host,(ECC|EEI));
|
enable_irq(host->irq_cmd);
|
enable_irq(host->irq_cmd);
|
|
|
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
}
|
}
|
|
|
static irqreturn_t ocores_irq_dat(int irq, void *dev_id)
|
static irqreturn_t ocores_irq_dat(int irq, void *dev_id)
|
{
|
{
|
Line 383... |
Line 377... |
break;
|
break;
|
}
|
}
|
}
|
}
|
else
|
else
|
{
|
{
|
|
if ( mmc_resp_type(host->mrq->cmd) == MMCOC_RSP_136 ) //Long response
|
|
{
|
|
printk(KERN_ALERT "Long Response, Word Cnt * = %08x\n ",host->word_cnt);
|
|
host->word_cnt+=1;
|
|
switch(host->word_cnt-1)
|
|
{
|
|
case (0):
|
|
host->mrq->cmd->resp[3] = readl(host->base + SD_RESP1);
|
|
ocores_start_cmd(host, host->mrq->cmd);
|
|
break;
|
|
case (1):
|
|
host->mrq->cmd->resp[2] = readl(host->base + SD_RESP1);
|
|
ocores_start_cmd(host, host->mrq->cmd);
|
|
break;
|
|
case (2):
|
|
host->mrq->cmd->resp[1] = readl(host->base + SD_RESP1);
|
|
ocores_start_cmd(host, host->mrq->cmd);
|
|
break;
|
|
case (3):
|
|
host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1);
|
|
mmc_request_done(host->mmc, host->mrq);
|
|
break;
|
|
}
|
|
}
|
|
else //Short response
|
|
{
|
host->mrq->cmd->error = 0 ;
|
host->mrq->cmd->error = 0 ;
|
host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1);
|
host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1);
|
printk(KERN_ALERT " CMD RSP * = %08x\n", host->mrq->cmd->resp[0]);
|
printk(KERN_ALERT "Short Response CMD RSP * = %08x\n", host->mrq->cmd->resp[0]);
|
|
mmc_request_done(host->mmc, host->mrq);
|
|
}
|
}
|
}
|
|
|
mmc_request_done(host->mmc, host->mrq);
|
|
|
|
}
|
}
|
|
|
static int ocores_remove(struct platform_device *pdev)
|
static int ocores_remove(struct platform_device *pdev)
|
{
|
{
|