aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/msm_sdcc.c
diff options
context:
space:
mode:
authorJoe Perches <joe@perches.com>2009-09-22 19:44:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:33 -0400
commitb5a74d6058e86546868242bb5283e16fb10fd90a (patch)
treea1ad0fe373afc57205bf3e571957e7afa7d8fac0 /drivers/mmc/host/msm_sdcc.c
parent75d145283b2e42619d7ee1e00b78466bacd51808 (diff)
msm_sdcc.c: move overly indented code to separate function
Signed-off-by: Joe Perches <joe@perches.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Brian Swetland <swetland@google.com> Cc: Pierre Ossman <drzeus-list@drzeus.cx> Cc: San Mehat <san@android.com> Cc: Matt Fleming <matt@console-pimps.org> Cc: Ian Molton <ian@mnementh.co.uk> Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Cc: Philip Langdale <philipl@overt.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/mmc/host/msm_sdcc.c')
-rw-r--r--drivers/mmc/host/msm_sdcc.c132
1 files changed, 63 insertions, 69 deletions
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 874de6a1e4e7..dba4600bcdb4 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -584,6 +584,67 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status)
584 msmsdcc_start_data(host, cmd->data); 584 msmsdcc_start_data(host, cmd->data);
585} 585}
586 586
587static void
588msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status,
589 void __iomem *base)
590{
591 struct mmc_data *data = host->curr.data;
592
593 if (!data)
594 return;
595
596 /* Check for data errors */
597 if (status & (MCI_DATACRCFAIL | MCI_DATATIMEOUT |
598 MCI_TXUNDERRUN | MCI_RXOVERRUN)) {
599 msmsdcc_data_err(host, data, status);
600 host->curr.data_xfered = 0;
601 if (host->dma.sg)
602 msm_dmov_stop_cmd(host->dma.channel,
603 &host->dma.hdr, 0);
604 else {
605 msmsdcc_stop_data(host);
606 if (!data->stop)
607 msmsdcc_request_end(host, data->mrq);
608 else
609 msmsdcc_start_command(host, data->stop, 0);
610 }
611 }
612
613 /* Check for data done */
614 if (!host->curr.got_dataend && (status & MCI_DATAEND))
615 host->curr.got_dataend = 1;
616
617 if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND))
618 host->curr.got_datablkend = 1;
619
620 /*
621 * If DMA is still in progress, we complete via the completion handler
622 */
623 if (host->curr.got_dataend && host->curr.got_datablkend &&
624 !host->dma.busy) {
625 /*
626 * There appears to be an issue in the controller where
627 * if you request a small block transfer (< fifo size),
628 * you may get your DATAEND/DATABLKEND irq without the
629 * PIO data irq.
630 *
631 * Check to see if there is still data to be read,
632 * and simulate a PIO irq.
633 */
634 if (readl(base + MMCISTATUS) & MCI_RXDATAAVLBL)
635 msmsdcc_pio_irq(1, host);
636
637 msmsdcc_stop_data(host);
638 if (!data->error)
639 host->curr.data_xfered = host->curr.xfer_size;
640
641 if (!data->stop)
642 msmsdcc_request_end(host, data->mrq);
643 else
644 msmsdcc_start_command(host, data->stop, 0);
645 }
646}
647
587static irqreturn_t 648static irqreturn_t
588msmsdcc_irq(int irq, void *dev_id) 649msmsdcc_irq(int irq, void *dev_id)
589{ 650{
@@ -596,79 +657,12 @@ msmsdcc_irq(int irq, void *dev_id)
596 spin_lock(&host->lock); 657 spin_lock(&host->lock);
597 658
598 do { 659 do {
599 struct mmc_data *data;
600 status = readl(base + MMCISTATUS); 660 status = readl(base + MMCISTATUS);
601 661
602 status &= (readl(base + MMCIMASK0) | 662 status &= (readl(base + MMCIMASK0) | MCI_DATABLOCKENDMASK);
603 MCI_DATABLOCKENDMASK);
604 writel(status, base + MMCICLEAR); 663 writel(status, base + MMCICLEAR);
605 664
606 data = host->curr.data; 665 msmsdcc_handle_irq_data(host, status, base);
607 if (data) {
608 /* Check for data errors */
609 if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|
610 MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
611 msmsdcc_data_err(host, data, status);
612 host->curr.data_xfered = 0;
613 if (host->dma.sg)
614 msm_dmov_stop_cmd(host->dma.channel,
615 &host->dma.hdr, 0);
616 else {
617 msmsdcc_stop_data(host);
618 if (!data->stop)
619 msmsdcc_request_end(host,
620 data->mrq);
621 else
622 msmsdcc_start_command(host,
623 data->stop,
624 0);
625 }
626 }
627
628 /* Check for data done */
629 if (!host->curr.got_dataend && (status & MCI_DATAEND))
630 host->curr.got_dataend = 1;
631
632 if (!host->curr.got_datablkend &&
633 (status & MCI_DATABLOCKEND)) {
634 host->curr.got_datablkend = 1;
635 }
636
637 if (host->curr.got_dataend &&
638 host->curr.got_datablkend) {
639 /*
640 * If DMA is still in progress, we complete
641 * via the completion handler
642 */
643 if (!host->dma.busy) {
644 /*
645 * There appears to be an issue in the
646 * controller where if you request a
647 * small block transfer (< fifo size),
648 * you may get your DATAEND/DATABLKEND
649 * irq without the PIO data irq.
650 *
651 * Check to see if theres still data
652 * to be read, and simulate a PIO irq.
653 */
654 if (readl(base + MMCISTATUS) &
655 MCI_RXDATAAVLBL)
656 msmsdcc_pio_irq(1, host);
657
658 msmsdcc_stop_data(host);
659 if (!data->error)
660 host->curr.data_xfered =
661 host->curr.xfer_size;
662
663 if (!data->stop)
664 msmsdcc_request_end(host,
665 data->mrq);
666 else
667 msmsdcc_start_command(host,
668 data->stop, 0);
669 }
670 }
671 }
672 666
673 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | 667 if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL |
674 MCI_CMDTIMEOUT) && host->curr.cmd) { 668 MCI_CMDTIMEOUT) && host->curr.cmd) {