Date:2010-06-27 18:56:47 (13 years 5 months ago)
Author:Lars C.
Commit:128b6b375f629bbec7c8017e2bbb8d45b651f856
Message:mmc: jz4740: Merge jz_mmc_cmd_done into jz_mmc_irq_worker

Files: drivers/mmc/host/jz4740_mmc.c (4 diffs)

Change Details

drivers/mmc/host/jz4740_mmc.c
131131    struct timer_list timeout_timer;
132132};
133133
134static void jz4740_mmc_cmd_done(struct jz4740_mmc_host *host);
135
136134static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host,
137135    unsigned int irq, bool enabled)
138136{
...... 
381379    jz4740_mmc_request_done(host);
382380}
383381
384static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
385{
386    struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)devid;
387
388    if (host->cmd->error)
389        jz4740_mmc_request_done(host);
390    else
391        jz4740_mmc_cmd_done(host);
392
393    return IRQ_HANDLED;
394}
395
396static irqreturn_t jz_mmc_irq(int irq, void *devid)
397{
398    struct jz4740_mmc_host *host = devid;
399    uint16_t irq_reg, status, tmp;
400    unsigned long flags;
401    irqreturn_t ret = IRQ_HANDLED;
402
403    irq_reg = readw(host->base + JZ_REG_MMC_IREG);
404
405    tmp = irq_reg;
406    spin_lock_irqsave(&host->lock, flags);
407    irq_reg &= ~host->irq_mask;
408    spin_unlock_irqrestore(&host->lock, flags);
409
410    tmp &= ~(JZ_MMC_IRQ_TXFIFO_WR_REQ | JZ_MMC_IRQ_RXFIFO_RD_REQ |
411            JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE);
412
413    if (tmp != irq_reg)
414        writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG);
415
416    if (irq_reg & JZ_MMC_IRQ_SDIO) {
417        writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG);
418        mmc_signal_sdio_irq(host->mmc);
419    }
420
421    if (!host->req || !host->cmd)
422        goto handled;
423
424    if (!test_and_clear_bit(0, &host->waiting))
425        goto handled;
426
427    del_timer(&host->timeout_timer);
428
429    status = readl(host->base + JZ_REG_MMC_STATUS);
430
431    if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
432        host->cmd->error = -ETIMEDOUT;
433    } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) {
434        host->cmd->error = -EIO;
435    } else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
436            JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
437        host->cmd->data->error = -EIO;
438    } else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
439            JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
440        host->cmd->data->error = -EIO;
441    }
442
443    if (irq_reg & JZ_MMC_IRQ_END_CMD_RES) {
444        jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, false);
445        writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
446        ret = IRQ_WAKE_THREAD;
447    }
448
449    return ret;
450
451handled:
452    writew(0xff, host->base + JZ_REG_MMC_IREG);
453    return IRQ_HANDLED;
454}
455
456static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate)
457{
458    int div = 0;
459    int real_rate;
460
461    jz4740_mmc_clock_disable(host);
462    clk_set_rate(host->clk, JZ_MMC_CLK_RATE);
463
464    real_rate = clk_get_rate(host->clk);
465
466    while (real_rate > rate && div < 7) {
467        ++div;
468        real_rate >>= 1;
469    }
470
471    writew(div, host->base + JZ_REG_MMC_CLKRT);
472    return real_rate;
473}
474
475382static void jz4740_mmc_read_response(struct jz4740_mmc_host *host,
476383    struct mmc_command *cmd)
477384{
...... 
541448    mod_timer(&host->timeout_timer, jiffies + 5*HZ);
542449}
543450
544static void jz4740_mmc_cmd_done(struct jz4740_mmc_host *host)
451
452static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
545453{
546    uint32_t status;
454    struct jz4740_mmc_host *host = (struct jz4740_mmc_host *)devid;
547455    struct mmc_command *cmd = host->req->cmd;
548456    struct mmc_request *req = host->req;
549457    unsigned int timeout = JZ4740_MMC_MAX_TIMEOUT;
458    uint32_t status;
459
460    if (cmd->error)
461        goto done;
550462
551463    if (cmd->flags & MMC_RSP_PRESENT)
552464        jz4740_mmc_read_response(host, cmd);
...... 
569481    if (unlikely(timeout == 0))
570482        req->stop->error = -ETIMEDOUT;
571483
484done:
572485    jz4740_mmc_request_done(host);
486
487    return IRQ_HANDLED;
488}
489
490static irqreturn_t jz_mmc_irq(int irq, void *devid)
491{
492    struct jz4740_mmc_host *host = devid;
493    uint16_t irq_reg, status, tmp;
494    unsigned long flags;
495    irqreturn_t ret = IRQ_HANDLED;
496
497    irq_reg = readw(host->base + JZ_REG_MMC_IREG);
498
499    tmp = irq_reg;
500    spin_lock_irqsave(&host->lock, flags);
501    irq_reg &= ~host->irq_mask;
502    spin_unlock_irqrestore(&host->lock, flags);
503
504    tmp &= ~(JZ_MMC_IRQ_TXFIFO_WR_REQ | JZ_MMC_IRQ_RXFIFO_RD_REQ |
505            JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE);
506
507    if (tmp != irq_reg)
508        writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG);
509
510    if (irq_reg & JZ_MMC_IRQ_SDIO) {
511        writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG);
512        mmc_signal_sdio_irq(host->mmc);
513    }
514
515    if (!host->req || !host->cmd)
516        goto handled;
517
518    if (!test_and_clear_bit(0, &host->waiting))
519        goto handled;
520
521    del_timer(&host->timeout_timer);
522
523    status = readl(host->base + JZ_REG_MMC_STATUS);
524
525    if (status & JZ_MMC_STATUS_TIMEOUT_RES) {
526        host->cmd->error = -ETIMEDOUT;
527    } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) {
528        host->cmd->error = -EIO;
529    } else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
530            JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
531        host->cmd->data->error = -EIO;
532    } else if (status & (JZ_MMC_STATUS_CRC_READ_ERROR |
533            JZ_MMC_STATUS_CRC_WRITE_ERROR)) {
534        host->cmd->data->error = -EIO;
535    }
536
537    if (irq_reg & JZ_MMC_IRQ_END_CMD_RES) {
538        jz4740_mmc_set_irq_enabled(host, JZ_MMC_IRQ_END_CMD_RES, false);
539        writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG);
540        ret = IRQ_WAKE_THREAD;
541    }
542
543    return ret;
544
545handled:
546    writew(0xff, host->base + JZ_REG_MMC_IREG);
547    return IRQ_HANDLED;
548}
549
550static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate)
551{
552    int div = 0;
553    int real_rate;
554
555    jz4740_mmc_clock_disable(host);
556    clk_set_rate(host->clk, JZ_MMC_CLK_RATE);
557
558    real_rate = clk_get_rate(host->clk);
559
560    while (real_rate > rate && div < 7) {
561        ++div;
562        real_rate >>= 1;
563    }
564
565    writew(div, host->base + JZ_REG_MMC_CLKRT);
566    return real_rate;
573567}
574568
575569static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req)

Archive Download the corresponding diff file



interactive