aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/au1xmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/au1xmmc.c')
-rw-r--r--drivers/mmc/host/au1xmmc.c573
1 files changed, 340 insertions, 233 deletions
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index cc5f7bc546af..d8776d61b3cc 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -41,8 +41,9 @@
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/dma-mapping.h> 42#include <linux/dma-mapping.h>
43#include <linux/scatterlist.h> 43#include <linux/scatterlist.h>
44 44#include <linux/leds.h>
45#include <linux/mmc/host.h> 45#include <linux/mmc/host.h>
46
46#include <asm/io.h> 47#include <asm/io.h>
47#include <asm/mach-au1x00/au1000.h> 48#include <asm/mach-au1x00/au1000.h>
48#include <asm/mach-au1x00/au1xxx_dbdma.h> 49#include <asm/mach-au1x00/au1xxx_dbdma.h>
@@ -54,6 +55,7 @@
54#define DRIVER_NAME "au1xxx-mmc" 55#define DRIVER_NAME "au1xxx-mmc"
55 56
56/* Set this to enable special debugging macros */ 57/* Set this to enable special debugging macros */
58/* #define DEBUG */
57 59
58#ifdef DEBUG 60#ifdef DEBUG
59#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) 61#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args)
@@ -61,32 +63,6 @@
61#define DBG(fmt, idx, args...) 63#define DBG(fmt, idx, args...)
62#endif 64#endif
63 65
64const struct {
65 u32 iobase;
66 u32 tx_devid, rx_devid;
67 u16 bcsrpwr;
68 u16 bcsrstatus;
69 u16 wpstatus;
70} au1xmmc_card_table[] = {
71 { SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0,
72 BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP },
73#ifndef CONFIG_MIPS_DB1200
74 { SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1,
75 BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP }
76#endif
77};
78
79#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table))
80
81/* This array stores pointers for the hosts (used by the IRQ handler) */
82struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
83static int dma = 1;
84
85#ifdef MODULE
86module_param(dma, bool, 0);
87MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)");
88#endif
89
90static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) 66static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
91{ 67{
92 u32 val = au_readl(HOST_CONFIG(host)); 68 u32 val = au_readl(HOST_CONFIG(host));
@@ -135,26 +111,33 @@ static inline void SEND_STOP(struct au1xmmc_host *host)
135 111
136static void au1xmmc_set_power(struct au1xmmc_host *host, int state) 112static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
137{ 113{
138 114 if (host->platdata && host->platdata->set_power)
139 u32 val = au1xmmc_card_table[host->id].bcsrpwr; 115 host->platdata->set_power(host->mmc, state);
140
141 bcsr->board &= ~val;
142 if (state) bcsr->board |= val;
143
144 au_sync_delay(1);
145} 116}
146 117
147static inline int au1xmmc_card_inserted(struct au1xmmc_host *host) 118static int au1xmmc_card_inserted(struct au1xmmc_host *host)
148{ 119{
149 return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus) 120 int ret;
150 ? 1 : 0; 121
122 if (host->platdata && host->platdata->card_inserted)
123 ret = host->platdata->card_inserted(host->mmc);
124 else
125 ret = 1; /* assume there is a card */
126
127 return ret;
151} 128}
152 129
153static int au1xmmc_card_readonly(struct mmc_host *mmc) 130static int au1xmmc_card_readonly(struct mmc_host *mmc)
154{ 131{
155 struct au1xmmc_host *host = mmc_priv(mmc); 132 struct au1xmmc_host *host = mmc_priv(mmc);
156 return (bcsr->status & au1xmmc_card_table[host->id].wpstatus) 133 int ret;
157 ? 1 : 0; 134
135 if (host->platdata && host->platdata->card_readonly)
136 ret = host->platdata->card_readonly(mmc);
137 else
138 ret = 0; /* assume card is read-write */
139
140 return ret;
158} 141}
159 142
160static void au1xmmc_finish_request(struct au1xmmc_host *host) 143static void au1xmmc_finish_request(struct au1xmmc_host *host)
@@ -163,7 +146,7 @@ static void au1xmmc_finish_request(struct au1xmmc_host *host)
163 struct mmc_request *mrq = host->mrq; 146 struct mmc_request *mrq = host->mrq;
164 147
165 host->mrq = NULL; 148 host->mrq = NULL;
166 host->flags &= HOST_F_ACTIVE; 149 host->flags &= HOST_F_ACTIVE | HOST_F_DMA;
167 150
168 host->dma.len = 0; 151 host->dma.len = 0;
169 host->dma.dir = 0; 152 host->dma.dir = 0;
@@ -174,8 +157,6 @@ static void au1xmmc_finish_request(struct au1xmmc_host *host)
174 157
175 host->status = HOST_S_IDLE; 158 host->status = HOST_S_IDLE;
176 159
177 bcsr->disk_leds |= (1 << 8);
178
179 mmc_request_done(host->mmc, mrq); 160 mmc_request_done(host->mmc, mrq);
180} 161}
181 162
@@ -299,11 +280,13 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
299 280
300 if (!data->error) { 281 if (!data->error) {
301 if (host->flags & HOST_F_DMA) { 282 if (host->flags & HOST_F_DMA) {
283#ifdef CONFIG_SOC_AU1200 /* DBDMA */
302 u32 chan = DMA_CHANNEL(host); 284 u32 chan = DMA_CHANNEL(host);
303 285
304 chan_tab_t *c = *((chan_tab_t **) chan); 286 chan_tab_t *c = *((chan_tab_t **) chan);
305 au1x_dma_chan_t *cp = c->chan_ptr; 287 au1x_dma_chan_t *cp = c->chan_ptr;
306 data->bytes_xfered = cp->ddma_bytecnt; 288 data->bytes_xfered = cp->ddma_bytecnt;
289#endif
307 } 290 }
308 else 291 else
309 data->bytes_xfered = 292 data->bytes_xfered =
@@ -420,18 +403,18 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
420 break; 403 break;
421 404
422 if (status & SD_STATUS_RC) { 405 if (status & SD_STATUS_RC) {
423 DBG("RX CRC Error [%d + %d].\n", host->id, 406 DBG("RX CRC Error [%d + %d].\n", host->pdev->id,
424 host->pio.len, count); 407 host->pio.len, count);
425 break; 408 break;
426 } 409 }
427 410
428 if (status & SD_STATUS_RO) { 411 if (status & SD_STATUS_RO) {
429 DBG("RX Overrun [%d + %d]\n", host->id, 412 DBG("RX Overrun [%d + %d]\n", host->pdev->id,
430 host->pio.len, count); 413 host->pio.len, count);
431 break; 414 break;
432 } 415 }
433 else if (status & SD_STATUS_RU) { 416 else if (status & SD_STATUS_RU) {
434 DBG("RX Underrun [%d + %d]\n", host->id, 417 DBG("RX Underrun [%d + %d]\n", host->pdev->id,
435 host->pio.len, count); 418 host->pio.len, count);
436 break; 419 break;
437 } 420 }
@@ -528,6 +511,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
528 host->status = HOST_S_DATA; 511 host->status = HOST_S_DATA;
529 512
530 if (host->flags & HOST_F_DMA) { 513 if (host->flags & HOST_F_DMA) {
514#ifdef CONFIG_SOC_AU1200 /* DBDMA */
531 u32 channel = DMA_CHANNEL(host); 515 u32 channel = DMA_CHANNEL(host);
532 516
533 /* Start the DMA as soon as the buffer gets something in it */ 517 /* Start the DMA as soon as the buffer gets something in it */
@@ -540,6 +524,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
540 } 524 }
541 525
542 au1xxx_dbdma_start(channel); 526 au1xxx_dbdma_start(channel);
527#endif
543 } 528 }
544} 529}
545 530
@@ -571,12 +556,8 @@ static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
571static int 556static int
572au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data) 557au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
573{ 558{
574
575 int datalen = data->blocks * data->blksz; 559 int datalen = data->blocks * data->blksz;
576 560
577 if (dma != 0)
578 host->flags |= HOST_F_DMA;
579
580 if (data->flags & MMC_DATA_READ) 561 if (data->flags & MMC_DATA_READ)
581 host->flags |= HOST_F_RECV; 562 host->flags |= HOST_F_RECV;
582 else 563 else
@@ -596,6 +577,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
596 au_writel(data->blksz - 1, HOST_BLKSIZE(host)); 577 au_writel(data->blksz - 1, HOST_BLKSIZE(host));
597 578
598 if (host->flags & HOST_F_DMA) { 579 if (host->flags & HOST_F_DMA) {
580#ifdef CONFIG_SOC_AU1200 /* DBDMA */
599 int i; 581 int i;
600 u32 channel = DMA_CHANNEL(host); 582 u32 channel = DMA_CHANNEL(host);
601 583
@@ -621,11 +603,12 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
621 len, flags); 603 len, flags);
622 } 604 }
623 605
624 if (!ret) 606 if (!ret)
625 goto dataerr; 607 goto dataerr;
626 608
627 datalen -= len; 609 datalen -= len;
628 } 610 }
611#endif
629 } 612 }
630 else { 613 else {
631 host->pio.index = 0; 614 host->pio.index = 0;
@@ -641,8 +624,9 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
641 624
642 return 0; 625 return 0;
643 626
644 dataerr: 627dataerr:
645 dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir); 628 dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
629 host->dma.dir);
646 return -ETIMEDOUT; 630 return -ETIMEDOUT;
647} 631}
648 632
@@ -663,8 +647,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
663 host->mrq = mrq; 647 host->mrq = mrq;
664 host->status = HOST_S_CMD; 648 host->status = HOST_S_CMD;
665 649
666 bcsr->disk_leds &= ~(1 << 8);
667
668 if (mrq->data) { 650 if (mrq->data) {
669 FLUSH_FIFO(host); 651 FLUSH_FIFO(host);
670 flags = mrq->data->flags; 652 flags = mrq->data->flags;
@@ -728,149 +710,145 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
728 } 710 }
729} 711}
730 712
731static void au1xmmc_dma_callback(int irq, void *dev_id)
732{
733 struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
734
735 /* Avoid spurious interrupts */
736
737 if (!host->mrq)
738 return;
739
740 if (host->flags & HOST_F_STOP)
741 SEND_STOP(host);
742
743 tasklet_schedule(&host->data_task);
744}
745
746#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) 713#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
747#define STATUS_DATA_IN (SD_STATUS_NE) 714#define STATUS_DATA_IN (SD_STATUS_NE)
748#define STATUS_DATA_OUT (SD_STATUS_TH) 715#define STATUS_DATA_OUT (SD_STATUS_TH)
749 716
750static irqreturn_t au1xmmc_irq(int irq, void *dev_id) 717static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
751{ 718{
752 719 struct au1xmmc_host *host = dev_id;
753 u32 status; 720 u32 status;
754 int i, ret = 0;
755
756 disable_irq(AU1100_SD_IRQ);
757 721
758 for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { 722 status = au_readl(HOST_STATUS(host));
759 struct au1xmmc_host * host = au1xmmc_hosts[i];
760 u32 handled = 1;
761
762 status = au_readl(HOST_STATUS(host));
763 723
764 if (host->mrq && (status & STATUS_TIMEOUT)) { 724 if (!(status & SD_STATUS_I))
765 if (status & SD_STATUS_RAT) 725 return IRQ_NONE; /* not ours */
766 host->mrq->cmd->error = -ETIMEDOUT;
767 726
768 else if (status & SD_STATUS_DT) 727 if (host->mrq && (status & STATUS_TIMEOUT)) {
769 host->mrq->data->error = -ETIMEDOUT; 728 if (status & SD_STATUS_RAT)
729 host->mrq->cmd->error = -ETIMEDOUT;
730 else if (status & SD_STATUS_DT)
731 host->mrq->data->error = -ETIMEDOUT;
770 732
771 /* In PIO mode, interrupts might still be enabled */ 733 /* In PIO mode, interrupts might still be enabled */
772 IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH); 734 IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
773 735
774 //IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF); 736 /* IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA | SD_CONFIG_RF); */
775 tasklet_schedule(&host->finish_task); 737 tasklet_schedule(&host->finish_task);
776 } 738 }
777#if 0 739#if 0
778 else if (status & SD_STATUS_DD) { 740 else if (status & SD_STATUS_DD) {
779 741 /* Sometimes we get a DD before a NE in PIO mode */
780 /* Sometimes we get a DD before a NE in PIO mode */ 742 if (!(host->flags & HOST_F_DMA) && (status & SD_STATUS_NE))
781 743 au1xmmc_receive_pio(host);
782 if (!(host->flags & HOST_F_DMA) && 744 else {
783 (status & SD_STATUS_NE)) 745 au1xmmc_data_complete(host, status);
784 au1xmmc_receive_pio(host); 746 /* tasklet_schedule(&host->data_task); */
785 else {
786 au1xmmc_data_complete(host, status);
787 //tasklet_schedule(&host->data_task);
788 }
789 }
790#endif
791 else if (status & (SD_STATUS_CR)) {
792 if (host->status == HOST_S_CMD)
793 au1xmmc_cmd_complete(host,status);
794 }
795 else if (!(host->flags & HOST_F_DMA)) {
796 if ((host->flags & HOST_F_XMIT) &&
797 (status & STATUS_DATA_OUT))
798 au1xmmc_send_pio(host);
799 else if ((host->flags & HOST_F_RECV) &&
800 (status & STATUS_DATA_IN))
801 au1xmmc_receive_pio(host);
802 }
803 else if (status & 0x203FBC70) {
804 DBG("Unhandled status %8.8x\n", host->id, status);
805 handled = 0;
806 } 747 }
807
808 au_writel(status, HOST_STATUS(host));
809 au_sync();
810
811 ret |= handled;
812 } 748 }
813 749#endif
814 enable_irq(AU1100_SD_IRQ); 750 else if (status & SD_STATUS_CR) {
815 return ret; 751 if (host->status == HOST_S_CMD)
816} 752 au1xmmc_cmd_complete(host, status);
817 753
818static void au1xmmc_poll_event(unsigned long arg) 754 } else if (!(host->flags & HOST_F_DMA)) {
819{ 755 if ((host->flags & HOST_F_XMIT) && (status & STATUS_DATA_OUT))
820 struct au1xmmc_host *host = (struct au1xmmc_host *) arg; 756 au1xmmc_send_pio(host);
821 757 else if ((host->flags & HOST_F_RECV) && (status & STATUS_DATA_IN))
822 int card = au1xmmc_card_inserted(host); 758 au1xmmc_receive_pio(host);
823 int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0; 759
824 760 } else if (status & 0x203F3C70) {
825 if (card != controller) { 761 DBG("Unhandled status %8.8x\n", host->pdev->id,
826 host->flags &= ~HOST_F_ACTIVE; 762 status);
827 if (card) host->flags |= HOST_F_ACTIVE;
828 mmc_detect_change(host->mmc, 0);
829 } 763 }
830 764
831 if (host->mrq != NULL) { 765 au_writel(status, HOST_STATUS(host));
832 u32 status = au_readl(HOST_STATUS(host)); 766 au_sync();
833 DBG("PENDING - %8.8x\n", host->id, status);
834 }
835 767
836 mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); 768 return IRQ_HANDLED;
837} 769}
838 770
839static dbdev_tab_t au1xmmc_mem_dbdev = 771#ifdef CONFIG_SOC_AU1200
840{ 772/* 8bit memory DMA device */
841 DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0 773static dbdev_tab_t au1xmmc_mem_dbdev = {
774 .dev_id = DSCR_CMD0_ALWAYS,
775 .dev_flags = DEV_FLAGS_ANYUSE,
776 .dev_tsize = 0,
777 .dev_devwidth = 8,
778 .dev_physaddr = 0x00000000,
779 .dev_intlevel = 0,
780 .dev_intpolarity = 0,
842}; 781};
782static int memid;
843 783
844static void au1xmmc_init_dma(struct au1xmmc_host *host) 784static void au1xmmc_dbdma_callback(int irq, void *dev_id)
845{ 785{
786 struct au1xmmc_host *host = (struct au1xmmc_host *)dev_id;
846 787
847 u32 rxchan, txchan; 788 /* Avoid spurious interrupts */
789 if (!host->mrq)
790 return;
848 791
849 int txid = au1xmmc_card_table[host->id].tx_devid; 792 if (host->flags & HOST_F_STOP)
850 int rxid = au1xmmc_card_table[host->id].rx_devid; 793 SEND_STOP(host);
851 794
852 /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride 795 tasklet_schedule(&host->data_task);
853 of 8 bits. And since devices are shared, we need to create 796}
854 our own to avoid freaking out other devices
855 */
856 797
857 int memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev); 798static int au1xmmc_dbdma_init(struct au1xmmc_host *host)
799{
800 struct resource *res;
801 int txid, rxid;
802
803 res = platform_get_resource(host->pdev, IORESOURCE_DMA, 0);
804 if (!res)
805 return -ENODEV;
806 txid = res->start;
807
808 res = platform_get_resource(host->pdev, IORESOURCE_DMA, 1);
809 if (!res)
810 return -ENODEV;
811 rxid = res->start;
812
813 if (!memid)
814 return -ENODEV;
815
816 host->tx_chan = au1xxx_dbdma_chan_alloc(memid, txid,
817 au1xmmc_dbdma_callback, (void *)host);
818 if (!host->tx_chan) {
819 dev_err(&host->pdev->dev, "cannot allocate TX DMA\n");
820 return -ENODEV;
821 }
822
823 host->rx_chan = au1xxx_dbdma_chan_alloc(rxid, memid,
824 au1xmmc_dbdma_callback, (void *)host);
825 if (!host->rx_chan) {
826 dev_err(&host->pdev->dev, "cannot allocate RX DMA\n");
827 au1xxx_dbdma_chan_free(host->tx_chan);
828 return -ENODEV;
829 }
858 830
859 txchan = au1xxx_dbdma_chan_alloc(memid, txid, 831 au1xxx_dbdma_set_devwidth(host->tx_chan, 8);
860 au1xmmc_dma_callback, (void *) host); 832 au1xxx_dbdma_set_devwidth(host->rx_chan, 8);
861 833
862 rxchan = au1xxx_dbdma_chan_alloc(rxid, memid, 834 au1xxx_dbdma_ring_alloc(host->tx_chan, AU1XMMC_DESCRIPTOR_COUNT);
863 au1xmmc_dma_callback, (void *) host); 835 au1xxx_dbdma_ring_alloc(host->rx_chan, AU1XMMC_DESCRIPTOR_COUNT);
864 836
865 au1xxx_dbdma_set_devwidth(txchan, 8); 837 /* DBDMA is good to go */
866 au1xxx_dbdma_set_devwidth(rxchan, 8); 838 host->flags |= HOST_F_DMA;
867 839
868 au1xxx_dbdma_ring_alloc(txchan, AU1XMMC_DESCRIPTOR_COUNT); 840 return 0;
869 au1xxx_dbdma_ring_alloc(rxchan, AU1XMMC_DESCRIPTOR_COUNT); 841}
870 842
871 host->tx_chan = txchan; 843static void au1xmmc_dbdma_shutdown(struct au1xmmc_host *host)
872 host->rx_chan = rxchan; 844{
845 if (host->flags & HOST_F_DMA) {
846 host->flags &= ~HOST_F_DMA;
847 au1xxx_dbdma_chan_free(host->tx_chan);
848 au1xxx_dbdma_chan_free(host->rx_chan);
849 }
873} 850}
851#endif
874 852
875static const struct mmc_host_ops au1xmmc_ops = { 853static const struct mmc_host_ops au1xmmc_ops = {
876 .request = au1xmmc_request, 854 .request = au1xmmc_request,
@@ -878,116 +856,235 @@ static const struct mmc_host_ops au1xmmc_ops = {
878 .get_ro = au1xmmc_card_readonly, 856 .get_ro = au1xmmc_card_readonly,
879}; 857};
880 858
881static int __devinit au1xmmc_probe(struct platform_device *pdev) 859static void au1xmmc_poll_event(unsigned long arg)
882{ 860{
861 struct au1xmmc_host *host = (struct au1xmmc_host *)arg;
862 int card = au1xmmc_card_inserted(host);
863 int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0;
864
865 if (card != controller) {
866 host->flags &= ~HOST_F_ACTIVE;
867 if (card)
868 host->flags |= HOST_F_ACTIVE;
869 mmc_detect_change(host->mmc, 0);
870 }
883 871
884 int i, ret = 0; 872#ifdef DEBUG
873 if (host->mrq != NULL) {
874 u32 status = au_readl(HOST_STATUS(host));
875 DBG("PENDING - %8.8x\n", host->pdev->id, status);
876 }
877#endif
878 mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
879}
885 880
886 /* THe interrupt is shared among all controllers */ 881static void au1xmmc_init_cd_poll_timer(struct au1xmmc_host *host)
887 ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, IRQF_DISABLED, "MMC", 0); 882{
883 init_timer(&host->timer);
884 host->timer.function = au1xmmc_poll_event;
885 host->timer.data = (unsigned long)host;
886 host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
887}
888 888
889 if (ret) { 889static int __devinit au1xmmc_probe(struct platform_device *pdev)
890 printk(DRIVER_NAME "ERROR: Couldn't get int %d: %d\n", 890{
891 AU1100_SD_IRQ, ret); 891 struct mmc_host *mmc;
892 return -ENXIO; 892 struct au1xmmc_host *host;
893 struct resource *r;
894 int ret;
895
896 mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
897 if (!mmc) {
898 dev_err(&pdev->dev, "no memory for mmc_host\n");
899 ret = -ENOMEM;
900 goto out0;
893 } 901 }
894 902
895 disable_irq(AU1100_SD_IRQ); 903 host = mmc_priv(mmc);
904 host->mmc = mmc;
905 host->platdata = pdev->dev.platform_data;
906 host->pdev = pdev;
896 907
897 for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { 908 ret = -ENODEV;
898 struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); 909 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
899 struct au1xmmc_host *host = 0; 910 if (!r) {
911 dev_err(&pdev->dev, "no mmio defined\n");
912 goto out1;
913 }
900 914
901 if (!mmc) { 915 host->ioarea = request_mem_region(r->start, r->end - r->start + 1,
902 printk(DRIVER_NAME "ERROR: no mem for host %d\n", i); 916 pdev->name);
903 au1xmmc_hosts[i] = 0; 917 if (!host->ioarea) {
904 continue; 918 dev_err(&pdev->dev, "mmio already in use\n");
905 } 919 goto out1;
920 }
906 921
907 mmc->ops = &au1xmmc_ops; 922 host->iobase = (unsigned long)ioremap(r->start, 0x3c);
923 if (!host->iobase) {
924 dev_err(&pdev->dev, "cannot remap mmio\n");
925 goto out2;
926 }
927
928 r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
929 if (!r) {
930 dev_err(&pdev->dev, "no IRQ defined\n");
931 goto out3;
932 }
908 933
909 mmc->f_min = 450000; 934 host->irq = r->start;
910 mmc->f_max = 24000000; 935 /* IRQ is shared among both SD controllers */
936 ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED,
937 DRIVER_NAME, host);
938 if (ret) {
939 dev_err(&pdev->dev, "cannot grab IRQ\n");
940 goto out3;
941 }
911 942
912 mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE; 943 mmc->ops = &au1xmmc_ops;
913 mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
914 944
915 mmc->max_blk_size = 2048; 945 mmc->f_min = 450000;
916 mmc->max_blk_count = 512; 946 mmc->f_max = 24000000;
917 947
918 mmc->ocr_avail = AU1XMMC_OCR; 948 mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
949 mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
919 950
920 host = mmc_priv(mmc); 951 mmc->max_blk_size = 2048;
921 host->mmc = mmc; 952 mmc->max_blk_count = 512;
922 953
923 host->id = i; 954 mmc->ocr_avail = AU1XMMC_OCR;
924 host->iobase = au1xmmc_card_table[host->id].iobase; 955 mmc->caps = 0;
925 host->clock = 0;
926 host->power_mode = MMC_POWER_OFF;
927 956
928 host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0; 957 host->status = HOST_S_IDLE;
929 host->status = HOST_S_IDLE;
930 958
931 init_timer(&host->timer); 959 /* board-specific carddetect setup, if any */
960 if (host->platdata && host->platdata->cd_setup) {
961 ret = host->platdata->cd_setup(mmc, 1);
962 if (ret) {
963 dev_err(&pdev->dev, "board CD setup failed\n");
964 goto out4;
965 }
966 } else {
967 /* poll the board-specific is-card-in-socket-? method */
968 au1xmmc_init_cd_poll_timer(host);
969 }
932 970
933 host->timer.function = au1xmmc_poll_event; 971 tasklet_init(&host->data_task, au1xmmc_tasklet_data,
934 host->timer.data = (unsigned long) host; 972 (unsigned long)host);
935 host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
936 973
937 tasklet_init(&host->data_task, au1xmmc_tasklet_data, 974 tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
938 (unsigned long) host); 975 (unsigned long)host);
939 976
940 tasklet_init(&host->finish_task, au1xmmc_tasklet_finish, 977#ifdef CONFIG_SOC_AU1200
941 (unsigned long) host); 978 ret = au1xmmc_dbdma_init(host);
979 if (ret)
980 printk(KERN_INFO DRIVER_NAME ": DBDMA init failed; using PIO\n");
981#endif
942 982
943 spin_lock_init(&host->lock); 983#ifdef CONFIG_LEDS_CLASS
984 if (host->platdata && host->platdata->led) {
985 struct led_classdev *led = host->platdata->led;
986 led->name = mmc_hostname(mmc);
987 led->brightness = LED_OFF;
988 led->default_trigger = mmc_hostname(mmc);
989 ret = led_classdev_register(mmc_dev(mmc), led);
990 if (ret)
991 goto out5;
992 }
993#endif
944 994
945 if (dma != 0) 995 au1xmmc_reset_controller(host);
946 au1xmmc_init_dma(host);
947 996
948 au1xmmc_reset_controller(host); 997 ret = mmc_add_host(mmc);
998 if (ret) {
999 dev_err(&pdev->dev, "cannot add mmc host\n");
1000 goto out6;
1001 }
949 1002
950 mmc_add_host(mmc); 1003 platform_set_drvdata(pdev, mmc);
951 au1xmmc_hosts[i] = host;
952 1004
1005 /* start the carddetect poll timer if necessary */
1006 if (!(host->platdata && host->platdata->cd_setup))
953 add_timer(&host->timer); 1007 add_timer(&host->timer);
954 1008
955 printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n", 1009 printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X"
956 host->id, host->iobase, dma ? "dma" : "pio"); 1010 " (mode=%s)\n", pdev->id, host->iobase,
957 } 1011 host->flags & HOST_F_DMA ? "dma" : "pio");
958 1012
959 enable_irq(AU1100_SD_IRQ); 1013 return 0; /* all ok */
960 1014
961 return 0; 1015out6:
1016#ifdef CONFIG_LEDS_CLASS
1017 if (host->platdata && host->platdata->led)
1018 led_classdev_unregister(host->platdata->led);
1019out5:
1020#endif
1021 au_writel(0, HOST_ENABLE(host));
1022 au_writel(0, HOST_CONFIG(host));
1023 au_writel(0, HOST_CONFIG2(host));
1024 au_sync();
1025
1026#ifdef CONFIG_SOC_AU1200
1027 au1xmmc_dbdma_shutdown(host);
1028#endif
1029
1030 tasklet_kill(&host->data_task);
1031 tasklet_kill(&host->finish_task);
1032
1033 if (host->platdata && host->platdata->cd_setup)
1034 host->platdata->cd_setup(mmc, 0);
1035out4:
1036 free_irq(host->irq, host);
1037out3:
1038 iounmap((void *)host->iobase);
1039out2:
1040 release_resource(host->ioarea);
1041 kfree(host->ioarea);
1042out1:
1043 mmc_free_host(mmc);
1044out0:
1045 return ret;
962} 1046}
963 1047
964static int __devexit au1xmmc_remove(struct platform_device *pdev) 1048static int __devexit au1xmmc_remove(struct platform_device *pdev)
965{ 1049{
1050 struct mmc_host *mmc = platform_get_drvdata(pdev);
1051 struct au1xmmc_host *host;
1052
1053 if (mmc) {
1054 host = mmc_priv(mmc);
1055
1056 mmc_remove_host(mmc);
966 1057
967 int i; 1058#ifdef CONFIG_LEDS_CLASS
1059 if (host->platdata && host->platdata->led)
1060 led_classdev_unregister(host->platdata->led);
1061#endif
968 1062
969 disable_irq(AU1100_SD_IRQ); 1063 if (host->platdata && host->platdata->cd_setup)
1064 host->platdata->cd_setup(mmc, 0);
1065 else
1066 del_timer_sync(&host->timer);
970 1067
971 for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { 1068 au_writel(0, HOST_ENABLE(host));
972 struct au1xmmc_host *host = au1xmmc_hosts[i]; 1069 au_writel(0, HOST_CONFIG(host));
973 if (!host) continue; 1070 au_writel(0, HOST_CONFIG2(host));
1071 au_sync();
974 1072
975 tasklet_kill(&host->data_task); 1073 tasklet_kill(&host->data_task);
976 tasklet_kill(&host->finish_task); 1074 tasklet_kill(&host->finish_task);
977 1075
978 del_timer_sync(&host->timer); 1076#ifdef CONFIG_SOC_AU1200
1077 au1xmmc_dbdma_shutdown(host);
1078#endif
979 au1xmmc_set_power(host, 0); 1079 au1xmmc_set_power(host, 0);
980 1080
981 mmc_remove_host(host->mmc); 1081 free_irq(host->irq, host);
1082 iounmap((void *)host->iobase);
1083 release_resource(host->ioarea);
1084 kfree(host->ioarea);
982 1085
983 au1xxx_dbdma_chan_free(host->tx_chan); 1086 mmc_free_host(mmc);
984 au1xxx_dbdma_chan_free(host->rx_chan);
985
986 au_writel(0x0, HOST_ENABLE(host));
987 au_sync();
988 } 1087 }
989
990 free_irq(AU1100_SD_IRQ, 0);
991 return 0; 1088 return 0;
992} 1089}
993 1090
@@ -1004,21 +1101,31 @@ static struct platform_driver au1xmmc_driver = {
1004 1101
1005static int __init au1xmmc_init(void) 1102static int __init au1xmmc_init(void)
1006{ 1103{
1104#ifdef CONFIG_SOC_AU1200
1105 /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
1106 * of 8 bits. And since devices are shared, we need to create
1107 * our own to avoid freaking out other devices.
1108 */
1109 memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
1110 if (!memid)
1111 printk(KERN_ERR "au1xmmc: cannot add memory dbdma dev\n");
1112#endif
1007 return platform_driver_register(&au1xmmc_driver); 1113 return platform_driver_register(&au1xmmc_driver);
1008} 1114}
1009 1115
1010static void __exit au1xmmc_exit(void) 1116static void __exit au1xmmc_exit(void)
1011{ 1117{
1118#ifdef CONFIG_SOC_AU1200
1119 if (memid)
1120 au1xxx_ddma_del_device(memid);
1121#endif
1012 platform_driver_unregister(&au1xmmc_driver); 1122 platform_driver_unregister(&au1xmmc_driver);
1013} 1123}
1014 1124
1015module_init(au1xmmc_init); 1125module_init(au1xmmc_init);
1016module_exit(au1xmmc_exit); 1126module_exit(au1xmmc_exit);
1017 1127
1018#ifdef MODULE
1019MODULE_AUTHOR("Advanced Micro Devices, Inc"); 1128MODULE_AUTHOR("Advanced Micro Devices, Inc");
1020MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX"); 1129MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
1021MODULE_LICENSE("GPL"); 1130MODULE_LICENSE("GPL");
1022MODULE_ALIAS("platform:au1xxx-mmc"); 1131MODULE_ALIAS("platform:au1xxx-mmc");
1023#endif
1024