diff options
Diffstat (limited to 'drivers/mmc/host/tmio_mmc_pio.c')
-rw-r--r-- | drivers/mmc/host/tmio_mmc_pio.c | 398 |
1 files changed, 142 insertions, 256 deletions
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 50bf495a988..1f16357e730 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -35,30 +35,27 @@ | |||
35 | #include <linux/irq.h> | 35 | #include <linux/irq.h> |
36 | #include <linux/mfd/tmio.h> | 36 | #include <linux/mfd/tmio.h> |
37 | #include <linux/mmc/host.h> | 37 | #include <linux/mmc/host.h> |
38 | #include <linux/mmc/mmc.h> | ||
39 | #include <linux/mmc/slot-gpio.h> | ||
40 | #include <linux/mmc/tmio.h> | 38 | #include <linux/mmc/tmio.h> |
41 | #include <linux/module.h> | 39 | #include <linux/module.h> |
42 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
43 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
44 | #include <linux/pm_qos.h> | ||
45 | #include <linux/pm_runtime.h> | 42 | #include <linux/pm_runtime.h> |
46 | #include <linux/scatterlist.h> | 43 | #include <linux/scatterlist.h> |
47 | #include <linux/spinlock.h> | ||
48 | #include <linux/workqueue.h> | 44 | #include <linux/workqueue.h> |
45 | #include <linux/spinlock.h> | ||
49 | 46 | ||
50 | #include "tmio_mmc.h" | 47 | #include "tmio_mmc.h" |
51 | 48 | ||
52 | void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i) | 49 | void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i) |
53 | { | 50 | { |
54 | host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ); | 51 | u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ); |
55 | sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask); | 52 | sd_ctrl_write32(host, CTL_IRQ_MASK, mask); |
56 | } | 53 | } |
57 | 54 | ||
58 | void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i) | 55 | void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i) |
59 | { | 56 | { |
60 | host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ); | 57 | u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ); |
61 | sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask); | 58 | sd_ctrl_write32(host, CTL_IRQ_MASK, mask); |
62 | } | 59 | } |
63 | 60 | ||
64 | static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i) | 61 | static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i) |
@@ -95,7 +92,7 @@ static int tmio_mmc_next_sg(struct tmio_mmc_host *host) | |||
95 | static void pr_debug_status(u32 status) | 92 | static void pr_debug_status(u32 status) |
96 | { | 93 | { |
97 | int i = 0; | 94 | int i = 0; |
98 | pr_debug("status: %08x = ", status); | 95 | printk(KERN_DEBUG "status: %08x = ", status); |
99 | STATUS_TO_TEXT(CARD_REMOVE, status, i); | 96 | STATUS_TO_TEXT(CARD_REMOVE, status, i); |
100 | STATUS_TO_TEXT(CARD_INSERT, status, i); | 97 | STATUS_TO_TEXT(CARD_INSERT, status, i); |
101 | STATUS_TO_TEXT(SIGSTATE, status, i); | 98 | STATUS_TO_TEXT(SIGSTATE, status, i); |
@@ -129,14 +126,14 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
129 | struct tmio_mmc_host *host = mmc_priv(mmc); | 126 | struct tmio_mmc_host *host = mmc_priv(mmc); |
130 | 127 | ||
131 | if (enable) { | 128 | if (enable) { |
132 | host->sdio_irq_mask = TMIO_SDIO_MASK_ALL & | 129 | host->sdio_irq_enabled = 1; |
133 | ~TMIO_SDIO_STAT_IOIRQ; | ||
134 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); | 130 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); |
135 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); | 131 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, |
132 | (TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ)); | ||
136 | } else { | 133 | } else { |
137 | host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; | 134 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL); |
138 | sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); | ||
139 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); | 135 | sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); |
136 | host->sdio_irq_enabled = 0; | ||
140 | } | 137 | } |
141 | } | 138 | } |
142 | 139 | ||
@@ -247,7 +244,6 @@ static void tmio_mmc_reset_work(struct work_struct *work) | |||
247 | /* Ready for new calls */ | 244 | /* Ready for new calls */ |
248 | host->mrq = NULL; | 245 | host->mrq = NULL; |
249 | 246 | ||
250 | tmio_mmc_abort_dma(host); | ||
251 | mmc_request_done(host->mmc, mrq); | 247 | mmc_request_done(host->mmc, mrq); |
252 | } | 248 | } |
253 | 249 | ||
@@ -274,9 +270,6 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) | |||
274 | host->mrq = NULL; | 270 | host->mrq = NULL; |
275 | spin_unlock_irqrestore(&host->lock, flags); | 271 | spin_unlock_irqrestore(&host->lock, flags); |
276 | 272 | ||
277 | if (mrq->cmd->error || (mrq->data && mrq->data->error)) | ||
278 | tmio_mmc_abort_dma(host); | ||
279 | |||
280 | mmc_request_done(host->mmc, mrq); | 273 | mmc_request_done(host->mmc, mrq); |
281 | } | 274 | } |
282 | 275 | ||
@@ -304,10 +297,9 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command | |||
304 | { | 297 | { |
305 | struct mmc_data *data = host->data; | 298 | struct mmc_data *data = host->data; |
306 | int c = cmd->opcode; | 299 | int c = cmd->opcode; |
307 | u32 irq_mask = TMIO_MASK_CMD; | ||
308 | 300 | ||
309 | /* CMD12 is handled by hardware */ | 301 | /* Command 12 is handled by hardware */ |
310 | if (cmd->opcode == MMC_STOP_TRANSMISSION && !cmd->arg) { | 302 | if (cmd->opcode == 12 && !cmd->arg) { |
311 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001); | 303 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001); |
312 | return 0; | 304 | return 0; |
313 | } | 305 | } |
@@ -340,9 +332,7 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command | |||
340 | c |= TRANSFER_READ; | 332 | c |= TRANSFER_READ; |
341 | } | 333 | } |
342 | 334 | ||
343 | if (!host->native_hotplug) | 335 | tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_CMD); |
344 | irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT); | ||
345 | tmio_mmc_enable_mmc_irqs(host, irq_mask); | ||
346 | 336 | ||
347 | /* Fire off the command */ | 337 | /* Fire off the command */ |
348 | sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg); | 338 | sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg); |
@@ -450,7 +440,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host) | |||
450 | } | 440 | } |
451 | 441 | ||
452 | if (stop) { | 442 | if (stop) { |
453 | if (stop->opcode == MMC_STOP_TRANSMISSION && !stop->arg) | 443 | if (stop->opcode == 12 && !stop->arg) |
454 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000); | 444 | sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000); |
455 | else | 445 | else |
456 | BUG(); | 446 | BUG(); |
@@ -553,20 +543,45 @@ out: | |||
553 | spin_unlock(&host->lock); | 543 | spin_unlock(&host->lock); |
554 | } | 544 | } |
555 | 545 | ||
556 | static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host, | 546 | irqreturn_t tmio_mmc_irq(int irq, void *devid) |
557 | int *ireg, int *status) | ||
558 | { | 547 | { |
559 | *status = sd_ctrl_read32(host, CTL_STATUS); | 548 | struct tmio_mmc_host *host = devid; |
560 | *ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask; | 549 | struct mmc_host *mmc = host->mmc; |
550 | struct tmio_mmc_data *pdata = host->pdata; | ||
551 | unsigned int ireg, irq_mask, status; | ||
552 | unsigned int sdio_ireg, sdio_irq_mask, sdio_status; | ||
561 | 553 | ||
562 | pr_debug_status(*status); | 554 | pr_debug("MMC IRQ begin\n"); |
563 | pr_debug_status(*ireg); | ||
564 | } | ||
565 | 555 | ||
566 | static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host, | 556 | status = sd_ctrl_read32(host, CTL_STATUS); |
567 | int ireg, int status) | 557 | irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK); |
568 | { | 558 | ireg = status & TMIO_MASK_IRQ & ~irq_mask; |
569 | struct mmc_host *mmc = host->mmc; | 559 | |
560 | sdio_ireg = 0; | ||
561 | if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) { | ||
562 | sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS); | ||
563 | sdio_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK); | ||
564 | sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask; | ||
565 | |||
566 | sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL); | ||
567 | |||
568 | if (sdio_ireg && !host->sdio_irq_enabled) { | ||
569 | pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n", | ||
570 | sdio_status, sdio_irq_mask, sdio_ireg); | ||
571 | tmio_mmc_enable_sdio_irq(mmc, 0); | ||
572 | goto out; | ||
573 | } | ||
574 | |||
575 | if (mmc->caps & MMC_CAP_SDIO_IRQ && | ||
576 | sdio_ireg & TMIO_SDIO_STAT_IOIRQ) | ||
577 | mmc_signal_sdio_irq(mmc); | ||
578 | |||
579 | if (sdio_ireg) | ||
580 | goto out; | ||
581 | } | ||
582 | |||
583 | pr_debug_status(status); | ||
584 | pr_debug_status(ireg); | ||
570 | 585 | ||
571 | /* Card insert / remove attempts */ | 586 | /* Card insert / remove attempts */ |
572 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | 587 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { |
@@ -576,102 +591,43 @@ static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host, | |||
576 | ((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) && | 591 | ((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) && |
577 | !work_pending(&mmc->detect.work)) | 592 | !work_pending(&mmc->detect.work)) |
578 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); | 593 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); |
579 | return true; | 594 | goto out; |
580 | } | 595 | } |
581 | 596 | ||
582 | return false; | 597 | /* CRC and other errors */ |
583 | } | 598 | /* if (ireg & TMIO_STAT_ERR_IRQ) |
584 | 599 | * handled |= tmio_error_irq(host, irq, stat); | |
585 | irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid) | 600 | */ |
586 | { | ||
587 | unsigned int ireg, status; | ||
588 | struct tmio_mmc_host *host = devid; | ||
589 | |||
590 | tmio_mmc_card_irq_status(host, &ireg, &status); | ||
591 | __tmio_mmc_card_detect_irq(host, ireg, status); | ||
592 | |||
593 | return IRQ_HANDLED; | ||
594 | } | ||
595 | EXPORT_SYMBOL(tmio_mmc_card_detect_irq); | ||
596 | 601 | ||
597 | static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host, | ||
598 | int ireg, int status) | ||
599 | { | ||
600 | /* Command completion */ | 602 | /* Command completion */ |
601 | if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) { | 603 | if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) { |
602 | tmio_mmc_ack_mmc_irqs(host, | 604 | tmio_mmc_ack_mmc_irqs(host, |
603 | TMIO_STAT_CMDRESPEND | | 605 | TMIO_STAT_CMDRESPEND | |
604 | TMIO_STAT_CMDTIMEOUT); | 606 | TMIO_STAT_CMDTIMEOUT); |
605 | tmio_mmc_cmd_irq(host, status); | 607 | tmio_mmc_cmd_irq(host, status); |
606 | return true; | 608 | goto out; |
607 | } | 609 | } |
608 | 610 | ||
609 | /* Data transfer */ | 611 | /* Data transfer */ |
610 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { | 612 | if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { |
611 | tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); | 613 | tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); |
612 | tmio_mmc_pio_irq(host); | 614 | tmio_mmc_pio_irq(host); |
613 | return true; | 615 | goto out; |
614 | } | 616 | } |
615 | 617 | ||
616 | /* Data transfer completion */ | 618 | /* Data transfer completion */ |
617 | if (ireg & TMIO_STAT_DATAEND) { | 619 | if (ireg & TMIO_STAT_DATAEND) { |
618 | tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND); | 620 | tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND); |
619 | tmio_mmc_data_irq(host); | 621 | tmio_mmc_data_irq(host); |
620 | return true; | 622 | goto out; |
621 | } | 623 | } |
622 | 624 | ||
623 | return false; | 625 | pr_warning("tmio_mmc: Spurious irq, disabling! " |
624 | } | 626 | "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg); |
625 | 627 | pr_debug_status(status); | |
626 | irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid) | 628 | tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask); |
627 | { | ||
628 | unsigned int ireg, status; | ||
629 | struct tmio_mmc_host *host = devid; | ||
630 | |||
631 | tmio_mmc_card_irq_status(host, &ireg, &status); | ||
632 | __tmio_mmc_sdcard_irq(host, ireg, status); | ||
633 | |||
634 | return IRQ_HANDLED; | ||
635 | } | ||
636 | EXPORT_SYMBOL(tmio_mmc_sdcard_irq); | ||
637 | |||
638 | irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid) | ||
639 | { | ||
640 | struct tmio_mmc_host *host = devid; | ||
641 | struct mmc_host *mmc = host->mmc; | ||
642 | struct tmio_mmc_data *pdata = host->pdata; | ||
643 | unsigned int ireg, status; | ||
644 | |||
645 | if (!(pdata->flags & TMIO_MMC_SDIO_IRQ)) | ||
646 | return IRQ_HANDLED; | ||
647 | |||
648 | status = sd_ctrl_read16(host, CTL_SDIO_STATUS); | ||
649 | ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask; | ||
650 | |||
651 | sd_ctrl_write16(host, CTL_SDIO_STATUS, status & ~TMIO_SDIO_MASK_ALL); | ||
652 | |||
653 | if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ) | ||
654 | mmc_signal_sdio_irq(mmc); | ||
655 | |||
656 | return IRQ_HANDLED; | ||
657 | } | ||
658 | EXPORT_SYMBOL(tmio_mmc_sdio_irq); | ||
659 | |||
660 | irqreturn_t tmio_mmc_irq(int irq, void *devid) | ||
661 | { | ||
662 | struct tmio_mmc_host *host = devid; | ||
663 | unsigned int ireg, status; | ||
664 | |||
665 | pr_debug("MMC IRQ begin\n"); | ||
666 | |||
667 | tmio_mmc_card_irq_status(host, &ireg, &status); | ||
668 | if (__tmio_mmc_card_detect_irq(host, ireg, status)) | ||
669 | return IRQ_HANDLED; | ||
670 | if (__tmio_mmc_sdcard_irq(host, ireg, status)) | ||
671 | return IRQ_HANDLED; | ||
672 | |||
673 | tmio_mmc_sdio_irq(irq, devid); | ||
674 | 629 | ||
630 | out: | ||
675 | return IRQ_HANDLED; | 631 | return IRQ_HANDLED; |
676 | } | 632 | } |
677 | EXPORT_SYMBOL(tmio_mmc_irq); | 633 | EXPORT_SYMBOL(tmio_mmc_irq); |
@@ -752,34 +708,6 @@ fail: | |||
752 | mmc_request_done(mmc, mrq); | 708 | mmc_request_done(mmc, mrq); |
753 | } | 709 | } |
754 | 710 | ||
755 | static int tmio_mmc_clk_update(struct mmc_host *mmc) | ||
756 | { | ||
757 | struct tmio_mmc_host *host = mmc_priv(mmc); | ||
758 | struct tmio_mmc_data *pdata = host->pdata; | ||
759 | int ret; | ||
760 | |||
761 | if (!pdata->clk_enable) | ||
762 | return -ENOTSUPP; | ||
763 | |||
764 | ret = pdata->clk_enable(host->pdev, &mmc->f_max); | ||
765 | if (!ret) | ||
766 | mmc->f_min = mmc->f_max / 512; | ||
767 | |||
768 | return ret; | ||
769 | } | ||
770 | |||
771 | static void tmio_mmc_set_power(struct tmio_mmc_host *host, struct mmc_ios *ios) | ||
772 | { | ||
773 | struct mmc_host *mmc = host->mmc; | ||
774 | |||
775 | if (host->set_pwr) | ||
776 | host->set_pwr(host->pdev, ios->power_mode != MMC_POWER_OFF); | ||
777 | if (!IS_ERR(mmc->supply.vmmc)) | ||
778 | /* Errors ignored... */ | ||
779 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, | ||
780 | ios->power_mode ? ios->vdd : 0); | ||
781 | } | ||
782 | |||
783 | /* Set MMC clock / power. | 711 | /* Set MMC clock / power. |
784 | * Note: This controller uses a simple divider scheme therefore it cannot | 712 | * Note: This controller uses a simple divider scheme therefore it cannot |
785 | * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as | 713 | * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as |
@@ -789,7 +717,7 @@ static void tmio_mmc_set_power(struct tmio_mmc_host *host, struct mmc_ios *ios) | |||
789 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 717 | static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
790 | { | 718 | { |
791 | struct tmio_mmc_host *host = mmc_priv(mmc); | 719 | struct tmio_mmc_host *host = mmc_priv(mmc); |
792 | struct device *dev = &host->pdev->dev; | 720 | struct tmio_mmc_data *pdata = host->pdata; |
793 | unsigned long flags; | 721 | unsigned long flags; |
794 | 722 | ||
795 | mutex_lock(&host->ios_lock); | 723 | mutex_lock(&host->ios_lock); |
@@ -797,13 +725,13 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
797 | spin_lock_irqsave(&host->lock, flags); | 725 | spin_lock_irqsave(&host->lock, flags); |
798 | if (host->mrq) { | 726 | if (host->mrq) { |
799 | if (IS_ERR(host->mrq)) { | 727 | if (IS_ERR(host->mrq)) { |
800 | dev_dbg(dev, | 728 | dev_dbg(&host->pdev->dev, |
801 | "%s.%d: concurrent .set_ios(), clk %u, mode %u\n", | 729 | "%s.%d: concurrent .set_ios(), clk %u, mode %u\n", |
802 | current->comm, task_pid_nr(current), | 730 | current->comm, task_pid_nr(current), |
803 | ios->clock, ios->power_mode); | 731 | ios->clock, ios->power_mode); |
804 | host->mrq = ERR_PTR(-EINTR); | 732 | host->mrq = ERR_PTR(-EINTR); |
805 | } else { | 733 | } else { |
806 | dev_dbg(dev, | 734 | dev_dbg(&host->pdev->dev, |
807 | "%s.%d: CMD%u active since %lu, now %lu!\n", | 735 | "%s.%d: CMD%u active since %lu, now %lu!\n", |
808 | current->comm, task_pid_nr(current), | 736 | current->comm, task_pid_nr(current), |
809 | host->mrq->cmd->opcode, host->last_req_ts, jiffies); | 737 | host->mrq->cmd->opcode, host->last_req_ts, jiffies); |
@@ -819,44 +747,38 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
819 | spin_unlock_irqrestore(&host->lock, flags); | 747 | spin_unlock_irqrestore(&host->lock, flags); |
820 | 748 | ||
821 | /* | 749 | /* |
822 | * host->power toggles between false and true in both cases - either | 750 | * pdata->power == false only if COLD_CD is available, otherwise only |
823 | * or not the controller can be runtime-suspended during inactivity. | 751 | * in short time intervals during probing or resuming |
824 | * But if the controller has to be kept on, the runtime-pm usage_count | ||
825 | * is kept positive, so no suspending actually takes place. | ||
826 | */ | 752 | */ |
827 | if (ios->power_mode == MMC_POWER_ON && ios->clock) { | 753 | if (ios->power_mode == MMC_POWER_ON && ios->clock) { |
828 | if (!host->power) { | 754 | if (!pdata->power) { |
829 | tmio_mmc_clk_update(mmc); | 755 | pm_runtime_get_sync(&host->pdev->dev); |
830 | pm_runtime_get_sync(dev); | 756 | pdata->power = true; |
831 | host->power = true; | ||
832 | } | 757 | } |
833 | tmio_mmc_set_clock(host, ios->clock); | 758 | tmio_mmc_set_clock(host, ios->clock); |
834 | /* power up SD bus */ | 759 | /* power up SD bus */ |
835 | tmio_mmc_set_power(host, ios); | 760 | if (host->set_pwr) |
761 | host->set_pwr(host->pdev, 1); | ||
836 | /* start bus clock */ | 762 | /* start bus clock */ |
837 | tmio_mmc_clk_start(host); | 763 | tmio_mmc_clk_start(host); |
838 | } else if (ios->power_mode != MMC_POWER_UP) { | 764 | } else if (ios->power_mode != MMC_POWER_UP) { |
839 | if (ios->power_mode == MMC_POWER_OFF) | 765 | if (host->set_pwr) |
840 | tmio_mmc_set_power(host, ios); | 766 | host->set_pwr(host->pdev, 0); |
841 | if (host->power) { | 767 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && |
842 | struct tmio_mmc_data *pdata = host->pdata; | 768 | pdata->power) { |
843 | tmio_mmc_clk_stop(host); | 769 | pdata->power = false; |
844 | host->power = false; | 770 | pm_runtime_put(&host->pdev->dev); |
845 | pm_runtime_put(dev); | ||
846 | if (pdata->clk_disable) | ||
847 | pdata->clk_disable(host->pdev); | ||
848 | } | 771 | } |
772 | tmio_mmc_clk_stop(host); | ||
849 | } | 773 | } |
850 | 774 | ||
851 | if (host->power) { | 775 | switch (ios->bus_width) { |
852 | switch (ios->bus_width) { | 776 | case MMC_BUS_WIDTH_1: |
853 | case MMC_BUS_WIDTH_1: | 777 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); |
854 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); | 778 | break; |
855 | break; | 779 | case MMC_BUS_WIDTH_4: |
856 | case MMC_BUS_WIDTH_4: | 780 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); |
857 | sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); | 781 | break; |
858 | break; | ||
859 | } | ||
860 | } | 782 | } |
861 | 783 | ||
862 | /* Let things settle. delay taken from winCE driver */ | 784 | /* Let things settle. delay taken from winCE driver */ |
@@ -875,9 +797,6 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) | |||
875 | { | 797 | { |
876 | struct tmio_mmc_host *host = mmc_priv(mmc); | 798 | struct tmio_mmc_host *host = mmc_priv(mmc); |
877 | struct tmio_mmc_data *pdata = host->pdata; | 799 | struct tmio_mmc_data *pdata = host->pdata; |
878 | int ret = mmc_gpio_get_ro(mmc); | ||
879 | if (ret >= 0) | ||
880 | return ret; | ||
881 | 800 | ||
882 | return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || | 801 | return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || |
883 | (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)); | 802 | (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)); |
@@ -887,9 +806,6 @@ static int tmio_mmc_get_cd(struct mmc_host *mmc) | |||
887 | { | 806 | { |
888 | struct tmio_mmc_host *host = mmc_priv(mmc); | 807 | struct tmio_mmc_host *host = mmc_priv(mmc); |
889 | struct tmio_mmc_data *pdata = host->pdata; | 808 | struct tmio_mmc_data *pdata = host->pdata; |
890 | int ret = mmc_gpio_get_cd(mmc); | ||
891 | if (ret >= 0) | ||
892 | return ret; | ||
893 | 809 | ||
894 | if (!pdata->get_cd) | 810 | if (!pdata->get_cd) |
895 | return -ENOSYS; | 811 | return -ENOSYS; |
@@ -905,20 +821,7 @@ static const struct mmc_host_ops tmio_mmc_ops = { | |||
905 | .enable_sdio_irq = tmio_mmc_enable_sdio_irq, | 821 | .enable_sdio_irq = tmio_mmc_enable_sdio_irq, |
906 | }; | 822 | }; |
907 | 823 | ||
908 | static void tmio_mmc_init_ocr(struct tmio_mmc_host *host) | 824 | int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, |
909 | { | ||
910 | struct tmio_mmc_data *pdata = host->pdata; | ||
911 | struct mmc_host *mmc = host->mmc; | ||
912 | |||
913 | mmc_regulator_get_supply(mmc); | ||
914 | |||
915 | if (!mmc->ocr_avail) | ||
916 | mmc->ocr_avail = pdata->ocr_mask ? : MMC_VDD_32_33 | MMC_VDD_33_34; | ||
917 | else if (pdata->ocr_mask) | ||
918 | dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); | ||
919 | } | ||
920 | |||
921 | int tmio_mmc_host_probe(struct tmio_mmc_host **host, | ||
922 | struct platform_device *pdev, | 825 | struct platform_device *pdev, |
923 | struct tmio_mmc_data *pdata) | 826 | struct tmio_mmc_data *pdata) |
924 | { | 827 | { |
@@ -957,61 +860,29 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
957 | 860 | ||
958 | mmc->ops = &tmio_mmc_ops; | 861 | mmc->ops = &tmio_mmc_ops; |
959 | mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities; | 862 | mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities; |
960 | mmc->caps2 = pdata->capabilities2; | 863 | mmc->f_max = pdata->hclk; |
864 | mmc->f_min = mmc->f_max / 512; | ||
961 | mmc->max_segs = 32; | 865 | mmc->max_segs = 32; |
962 | mmc->max_blk_size = 512; | 866 | mmc->max_blk_size = 512; |
963 | mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) * | 867 | mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) * |
964 | mmc->max_segs; | 868 | mmc->max_segs; |
965 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 869 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
966 | mmc->max_seg_size = mmc->max_req_size; | 870 | mmc->max_seg_size = mmc->max_req_size; |
967 | tmio_mmc_init_ocr(_host); | 871 | if (pdata->ocr_mask) |
968 | 872 | mmc->ocr_avail = pdata->ocr_mask; | |
969 | _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD || | 873 | else |
970 | mmc->caps & MMC_CAP_NEEDS_POLL || | 874 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
971 | mmc->caps & MMC_CAP_NONREMOVABLE); | ||
972 | 875 | ||
973 | _host->power = false; | 876 | pdata->power = false; |
974 | pm_runtime_enable(&pdev->dev); | 877 | pm_runtime_enable(&pdev->dev); |
975 | ret = pm_runtime_resume(&pdev->dev); | 878 | ret = pm_runtime_resume(&pdev->dev); |
976 | if (ret < 0) | 879 | if (ret < 0) |
977 | goto pm_disable; | 880 | goto pm_disable; |
978 | 881 | ||
979 | if (tmio_mmc_clk_update(mmc) < 0) { | ||
980 | mmc->f_max = pdata->hclk; | ||
981 | mmc->f_min = mmc->f_max / 512; | ||
982 | } | ||
983 | |||
984 | /* | ||
985 | * There are 4 different scenarios for the card detection: | ||
986 | * 1) an external gpio irq handles the cd (best for power savings) | ||
987 | * 2) internal sdhi irq handles the cd | ||
988 | * 3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL | ||
989 | * 4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE | ||
990 | * | ||
991 | * While we increment the runtime PM counter for all scenarios when | ||
992 | * the mmc core activates us by calling an appropriate set_ios(), we | ||
993 | * must additionally ensure that in case 2) the tmio mmc hardware stays | ||
994 | * powered on during runtime for the card detection to work. | ||
995 | */ | ||
996 | if (_host->native_hotplug) | ||
997 | pm_runtime_get_noresume(&pdev->dev); | ||
998 | |||
999 | tmio_mmc_clk_stop(_host); | 882 | tmio_mmc_clk_stop(_host); |
1000 | tmio_mmc_reset(_host); | 883 | tmio_mmc_reset(_host); |
1001 | 884 | ||
1002 | _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK); | ||
1003 | tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL); | 885 | tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL); |
1004 | |||
1005 | /* Unmask the IRQs we want to know about */ | ||
1006 | if (!_host->chan_rx) | ||
1007 | irq_mask |= TMIO_MASK_READOP; | ||
1008 | if (!_host->chan_tx) | ||
1009 | irq_mask |= TMIO_MASK_WRITEOP; | ||
1010 | if (!_host->native_hotplug) | ||
1011 | irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT); | ||
1012 | |||
1013 | _host->sdcard_irq_mask &= ~irq_mask; | ||
1014 | |||
1015 | if (pdata->flags & TMIO_MMC_SDIO_IRQ) | 886 | if (pdata->flags & TMIO_MMC_SDIO_IRQ) |
1016 | tmio_mmc_enable_sdio_irq(mmc, 0); | 887 | tmio_mmc_enable_sdio_irq(mmc, 0); |
1017 | 888 | ||
@@ -1025,23 +896,21 @@ int tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
1025 | /* See if we also get DMA */ | 896 | /* See if we also get DMA */ |
1026 | tmio_mmc_request_dma(_host, pdata); | 897 | tmio_mmc_request_dma(_host, pdata); |
1027 | 898 | ||
1028 | ret = mmc_add_host(mmc); | 899 | /* We have to keep the device powered for its card detection to work */ |
1029 | if (pdata->clk_disable) | 900 | if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) { |
1030 | pdata->clk_disable(pdev); | 901 | pdata->power = true; |
1031 | if (ret < 0) { | 902 | pm_runtime_get_noresume(&pdev->dev); |
1032 | tmio_mmc_host_remove(_host); | ||
1033 | return ret; | ||
1034 | } | 903 | } |
1035 | 904 | ||
1036 | dev_pm_qos_expose_latency_limit(&pdev->dev, 100); | 905 | mmc_add_host(mmc); |
1037 | 906 | ||
1038 | if (pdata->flags & TMIO_MMC_USE_GPIO_CD) { | 907 | /* Unmask the IRQs we want to know about */ |
1039 | ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio); | 908 | if (!_host->chan_rx) |
1040 | if (ret < 0) { | 909 | irq_mask |= TMIO_MASK_READOP; |
1041 | tmio_mmc_host_remove(_host); | 910 | if (!_host->chan_tx) |
1042 | return ret; | 911 | irq_mask |= TMIO_MASK_WRITEOP; |
1043 | } | 912 | |
1044 | } | 913 | tmio_mmc_enable_mmc_irqs(_host, irq_mask); |
1045 | 914 | ||
1046 | *host = _host; | 915 | *host = _host; |
1047 | 916 | ||
@@ -1060,22 +929,18 @@ EXPORT_SYMBOL(tmio_mmc_host_probe); | |||
1060 | void tmio_mmc_host_remove(struct tmio_mmc_host *host) | 929 | void tmio_mmc_host_remove(struct tmio_mmc_host *host) |
1061 | { | 930 | { |
1062 | struct platform_device *pdev = host->pdev; | 931 | struct platform_device *pdev = host->pdev; |
1063 | struct tmio_mmc_data *pdata = host->pdata; | ||
1064 | struct mmc_host *mmc = host->mmc; | ||
1065 | 932 | ||
1066 | if (pdata->flags & TMIO_MMC_USE_GPIO_CD) | 933 | /* |
1067 | /* | 934 | * We don't have to manipulate pdata->power here: if there is a card in |
1068 | * This means we can miss a card-eject, but this is anyway | 935 | * the slot, the runtime PM is active and our .runtime_resume() will not |
1069 | * possible, because of delayed processing of hotplug events. | 936 | * be run. If there is no card in the slot and the platform can suspend |
1070 | */ | 937 | * the controller, the runtime PM is suspended and pdata->power == false, |
1071 | mmc_gpio_free_cd(mmc); | 938 | * so, our .runtime_resume() will not try to detect a card in the slot. |
1072 | 939 | */ | |
1073 | if (!host->native_hotplug) | 940 | if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD) |
1074 | pm_runtime_get_sync(&pdev->dev); | 941 | pm_runtime_get_sync(&pdev->dev); |
1075 | 942 | ||
1076 | dev_pm_qos_hide_latency_limit(&pdev->dev); | 943 | mmc_remove_host(host->mmc); |
1077 | |||
1078 | mmc_remove_host(mmc); | ||
1079 | cancel_work_sync(&host->done); | 944 | cancel_work_sync(&host->done); |
1080 | cancel_delayed_work_sync(&host->delayed_reset_work); | 945 | cancel_delayed_work_sync(&host->delayed_reset_work); |
1081 | tmio_mmc_release_dma(host); | 946 | tmio_mmc_release_dma(host); |
@@ -1084,7 +949,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
1084 | pm_runtime_disable(&pdev->dev); | 949 | pm_runtime_disable(&pdev->dev); |
1085 | 950 | ||
1086 | iounmap(host->ctl); | 951 | iounmap(host->ctl); |
1087 | mmc_free_host(mmc); | 952 | mmc_free_host(host->mmc); |
1088 | } | 953 | } |
1089 | EXPORT_SYMBOL(tmio_mmc_host_remove); | 954 | EXPORT_SYMBOL(tmio_mmc_host_remove); |
1090 | 955 | ||
@@ -1098,6 +963,8 @@ int tmio_mmc_host_suspend(struct device *dev) | |||
1098 | if (!ret) | 963 | if (!ret) |
1099 | tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); | 964 | tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); |
1100 | 965 | ||
966 | host->pm_error = pm_runtime_put_sync(dev); | ||
967 | |||
1101 | return ret; | 968 | return ret; |
1102 | } | 969 | } |
1103 | EXPORT_SYMBOL(tmio_mmc_host_suspend); | 970 | EXPORT_SYMBOL(tmio_mmc_host_suspend); |
@@ -1107,10 +974,20 @@ int tmio_mmc_host_resume(struct device *dev) | |||
1107 | struct mmc_host *mmc = dev_get_drvdata(dev); | 974 | struct mmc_host *mmc = dev_get_drvdata(dev); |
1108 | struct tmio_mmc_host *host = mmc_priv(mmc); | 975 | struct tmio_mmc_host *host = mmc_priv(mmc); |
1109 | 976 | ||
1110 | tmio_mmc_reset(host); | ||
1111 | tmio_mmc_enable_dma(host, true); | ||
1112 | |||
1113 | /* The MMC core will perform the complete set up */ | 977 | /* The MMC core will perform the complete set up */ |
978 | host->pdata->power = false; | ||
979 | |||
980 | host->pm_global = true; | ||
981 | if (!host->pm_error) | ||
982 | pm_runtime_get_sync(dev); | ||
983 | |||
984 | if (host->pm_global) { | ||
985 | /* Runtime PM resume callback didn't run */ | ||
986 | tmio_mmc_reset(host); | ||
987 | tmio_mmc_enable_dma(host, true); | ||
988 | host->pm_global = false; | ||
989 | } | ||
990 | |||
1114 | return mmc_resume_host(mmc); | 991 | return mmc_resume_host(mmc); |
1115 | } | 992 | } |
1116 | EXPORT_SYMBOL(tmio_mmc_host_resume); | 993 | EXPORT_SYMBOL(tmio_mmc_host_resume); |
@@ -1127,10 +1004,19 @@ int tmio_mmc_host_runtime_resume(struct device *dev) | |||
1127 | { | 1004 | { |
1128 | struct mmc_host *mmc = dev_get_drvdata(dev); | 1005 | struct mmc_host *mmc = dev_get_drvdata(dev); |
1129 | struct tmio_mmc_host *host = mmc_priv(mmc); | 1006 | struct tmio_mmc_host *host = mmc_priv(mmc); |
1007 | struct tmio_mmc_data *pdata = host->pdata; | ||
1130 | 1008 | ||
1131 | tmio_mmc_reset(host); | 1009 | tmio_mmc_reset(host); |
1132 | tmio_mmc_enable_dma(host, true); | 1010 | tmio_mmc_enable_dma(host, true); |
1133 | 1011 | ||
1012 | if (pdata->power) { | ||
1013 | /* Only entered after a card-insert interrupt */ | ||
1014 | if (!mmc->card) | ||
1015 | tmio_mmc_set_ios(mmc, &mmc->ios); | ||
1016 | mmc_detect_change(mmc, msecs_to_jiffies(100)); | ||
1017 | } | ||
1018 | host->pm_global = false; | ||
1019 | |||
1134 | return 0; | 1020 | return 0; |
1135 | } | 1021 | } |
1136 | EXPORT_SYMBOL(tmio_mmc_host_runtime_resume); | 1022 | EXPORT_SYMBOL(tmio_mmc_host_runtime_resume); |