aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-03-16 17:13:46 -0400
committerPierre Ossman <drzeus@drzeus.cx>2009-03-24 16:30:07 -0400
commit4e4141a526dd7f5ac3ce1458ae79ea6e5a515b06 (patch)
tree06f374b2e3a7a22eb66261d79d3374b1d23e5350
parentf079a8fc61e3dc35830f6abc58c21ae815ab4297 (diff)
sdhci: Add support for bus-specific IO memory accessors
Currently the SDHCI driver works with PCI accessors (write{l,b,w} and read{l,b,w}). With this patch drivers may change memory accessors, so that we can support hosts with "weird" IO memory access requirments. For example, in "FSL eSDHC" SDHCI hardware all registers are 32 bit width, with big-endian addressing. That is, readb(0x2f) should turn into readb(0x2c), and readw(0x2c) should be translated to le16_to_cpu(readw(0x2e)). Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/host/Kconfig7
-rw-r--r--drivers/mmc/host/sdhci.c159
-rw-r--r--drivers/mmc/host/sdhci.h95
3 files changed, 180 insertions, 81 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 092baf66733c..e8a7b50a01e7 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -37,6 +37,13 @@ config MMC_SDHCI
37 37
38 If unsure, say N. 38 If unsure, say N.
39 39
40config MMC_SDHCI_IO_ACCESSORS
41 bool
42 depends on MMC_SDHCI
43 help
44 This is silent Kconfig symbol that is selected by the drivers that
45 need to overwrite SDHCI IO memory accessors.
46
40config MMC_SDHCI_PCI 47config MMC_SDHCI_PCI
41 tristate "SDHCI support on PCI bus" 48 tristate "SDHCI support on PCI bus"
42 depends on MMC_SDHCI && PCI 49 depends on MMC_SDHCI && PCI
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index accb592764ed..fd36b822f809 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -48,35 +48,35 @@ static void sdhci_dumpregs(struct sdhci_host *host)
48 printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n"); 48 printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
49 49
50 printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", 50 printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n",
51 readl(host->ioaddr + SDHCI_DMA_ADDRESS), 51 sdhci_readl(host, SDHCI_DMA_ADDRESS),
52 readw(host->ioaddr + SDHCI_HOST_VERSION)); 52 sdhci_readw(host, SDHCI_HOST_VERSION));
53 printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", 53 printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n",
54 readw(host->ioaddr + SDHCI_BLOCK_SIZE), 54 sdhci_readw(host, SDHCI_BLOCK_SIZE),
55 readw(host->ioaddr + SDHCI_BLOCK_COUNT)); 55 sdhci_readw(host, SDHCI_BLOCK_COUNT));
56 printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", 56 printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
57 readl(host->ioaddr + SDHCI_ARGUMENT), 57 sdhci_readl(host, SDHCI_ARGUMENT),
58 readw(host->ioaddr + SDHCI_TRANSFER_MODE)); 58 sdhci_readw(host, SDHCI_TRANSFER_MODE));
59 printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", 59 printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n",
60 readl(host->ioaddr + SDHCI_PRESENT_STATE), 60 sdhci_readl(host, SDHCI_PRESENT_STATE),
61 readb(host->ioaddr + SDHCI_HOST_CONTROL)); 61 sdhci_readb(host, SDHCI_HOST_CONTROL));
62 printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", 62 printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n",
63 readb(host->ioaddr + SDHCI_POWER_CONTROL), 63 sdhci_readb(host, SDHCI_POWER_CONTROL),
64 readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL)); 64 sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
65 printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", 65 printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n",
66 readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL), 66 sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
67 readw(host->ioaddr + SDHCI_CLOCK_CONTROL)); 67 sdhci_readw(host, SDHCI_CLOCK_CONTROL));
68 printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", 68 printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n",
69 readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL), 69 sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
70 readl(host->ioaddr + SDHCI_INT_STATUS)); 70 sdhci_readl(host, SDHCI_INT_STATUS));
71 printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", 71 printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
72 readl(host->ioaddr + SDHCI_INT_ENABLE), 72 sdhci_readl(host, SDHCI_INT_ENABLE),
73 readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); 73 sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
74 printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", 74 printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
75 readw(host->ioaddr + SDHCI_ACMD12_ERR), 75 sdhci_readw(host, SDHCI_ACMD12_ERR),
76 readw(host->ioaddr + SDHCI_SLOT_INT_STATUS)); 76 sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
77 printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n", 77 printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n",
78 readl(host->ioaddr + SDHCI_CAPABILITIES), 78 sdhci_readl(host, SDHCI_CAPABILITIES),
79 readl(host->ioaddr + SDHCI_MAX_CURRENT)); 79 sdhci_readl(host, SDHCI_MAX_CURRENT));
80 80
81 printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); 81 printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
82} 82}
@@ -92,12 +92,12 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
92 unsigned long timeout; 92 unsigned long timeout;
93 93
94 if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { 94 if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
95 if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & 95 if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
96 SDHCI_CARD_PRESENT)) 96 SDHCI_CARD_PRESENT))
97 return; 97 return;
98 } 98 }
99 99
100 writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET); 100 sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
101 101
102 if (mask & SDHCI_RESET_ALL) 102 if (mask & SDHCI_RESET_ALL)
103 host->clock = 0; 103 host->clock = 0;
@@ -106,7 +106,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
106 timeout = 100; 106 timeout = 100;
107 107
108 /* hw clears the bit when it's done */ 108 /* hw clears the bit when it's done */
109 while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) { 109 while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
110 if (timeout == 0) { 110 if (timeout == 0) {
111 printk(KERN_ERR "%s: Reset 0x%x never completed.\n", 111 printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
112 mmc_hostname(host->mmc), (int)mask); 112 mmc_hostname(host->mmc), (int)mask);
@@ -132,26 +132,26 @@ static void sdhci_init(struct sdhci_host *host)
132 SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE | 132 SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
133 SDHCI_INT_ADMA_ERROR; 133 SDHCI_INT_ADMA_ERROR;
134 134
135 writel(intmask, host->ioaddr + SDHCI_INT_ENABLE); 135 sdhci_writel(host, intmask, SDHCI_INT_ENABLE);
136 writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); 136 sdhci_writel(host, intmask, SDHCI_SIGNAL_ENABLE);
137} 137}
138 138
139static void sdhci_activate_led(struct sdhci_host *host) 139static void sdhci_activate_led(struct sdhci_host *host)
140{ 140{
141 u8 ctrl; 141 u8 ctrl;
142 142
143 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); 143 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
144 ctrl |= SDHCI_CTRL_LED; 144 ctrl |= SDHCI_CTRL_LED;
145 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 145 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
146} 146}
147 147
148static void sdhci_deactivate_led(struct sdhci_host *host) 148static void sdhci_deactivate_led(struct sdhci_host *host)
149{ 149{
150 u8 ctrl; 150 u8 ctrl;
151 151
152 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); 152 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
153 ctrl &= ~SDHCI_CTRL_LED; 153 ctrl &= ~SDHCI_CTRL_LED;
154 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 154 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
155} 155}
156 156
157#ifdef SDHCI_USE_LEDS_CLASS 157#ifdef SDHCI_USE_LEDS_CLASS
@@ -205,7 +205,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
205 205
206 while (len) { 206 while (len) {
207 if (chunk == 0) { 207 if (chunk == 0) {
208 scratch = readl(host->ioaddr + SDHCI_BUFFER); 208 scratch = sdhci_readl(host, SDHCI_BUFFER);
209 chunk = 4; 209 chunk = 4;
210 } 210 }
211 211
@@ -257,7 +257,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
257 len--; 257 len--;
258 258
259 if ((chunk == 4) || ((len == 0) && (blksize == 0))) { 259 if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
260 writel(scratch, host->ioaddr + SDHCI_BUFFER); 260 sdhci_writel(host, scratch, SDHCI_BUFFER);
261 chunk = 0; 261 chunk = 0;
262 scratch = 0; 262 scratch = 0;
263 } 263 }
@@ -292,7 +292,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
292 (host->data->blocks == 1)) 292 (host->data->blocks == 1))
293 mask = ~0; 293 mask = ~0;
294 294
295 while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { 295 while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
296 if (host->data->flags & MMC_DATA_READ) 296 if (host->data->flags & MMC_DATA_READ)
297 sdhci_read_block_pio(host); 297 sdhci_read_block_pio(host);
298 else 298 else
@@ -581,7 +581,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
581 host->data_early = 0; 581 host->data_early = 0;
582 582
583 count = sdhci_calc_timeout(host, data); 583 count = sdhci_calc_timeout(host, data);
584 writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL); 584 sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
585 585
586 if (host->flags & SDHCI_USE_DMA) 586 if (host->flags & SDHCI_USE_DMA)
587 host->flags |= SDHCI_REQ_USE_DMA; 587 host->flags |= SDHCI_REQ_USE_DMA;
@@ -661,8 +661,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
661 WARN_ON(1); 661 WARN_ON(1);
662 host->flags &= ~SDHCI_REQ_USE_DMA; 662 host->flags &= ~SDHCI_REQ_USE_DMA;
663 } else { 663 } else {
664 writel(host->adma_addr, 664 sdhci_writel(host, host->adma_addr,
665 host->ioaddr + SDHCI_ADMA_ADDRESS); 665 SDHCI_ADMA_ADDRESS);
666 } 666 }
667 } else { 667 } else {
668 int sg_cnt; 668 int sg_cnt;
@@ -681,8 +681,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
681 host->flags &= ~SDHCI_REQ_USE_DMA; 681 host->flags &= ~SDHCI_REQ_USE_DMA;
682 } else { 682 } else {
683 WARN_ON(sg_cnt != 1); 683 WARN_ON(sg_cnt != 1);
684 writel(sg_dma_address(data->sg), 684 sdhci_writel(host, sg_dma_address(data->sg),
685 host->ioaddr + SDHCI_DMA_ADDRESS); 685 SDHCI_DMA_ADDRESS);
686 } 686 }
687 } 687 }
688 } 688 }
@@ -693,14 +693,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
693 * is ADMA. 693 * is ADMA.
694 */ 694 */
695 if (host->version >= SDHCI_SPEC_200) { 695 if (host->version >= SDHCI_SPEC_200) {
696 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); 696 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
697 ctrl &= ~SDHCI_CTRL_DMA_MASK; 697 ctrl &= ~SDHCI_CTRL_DMA_MASK;
698 if ((host->flags & SDHCI_REQ_USE_DMA) && 698 if ((host->flags & SDHCI_REQ_USE_DMA) &&
699 (host->flags & SDHCI_USE_ADMA)) 699 (host->flags & SDHCI_USE_ADMA))
700 ctrl |= SDHCI_CTRL_ADMA32; 700 ctrl |= SDHCI_CTRL_ADMA32;
701 else 701 else
702 ctrl |= SDHCI_CTRL_SDMA; 702 ctrl |= SDHCI_CTRL_SDMA;
703 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 703 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
704 } 704 }
705 705
706 if (!(host->flags & SDHCI_REQ_USE_DMA)) { 706 if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -710,9 +710,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
710 } 710 }
711 711
712 /* We do not handle DMA boundaries, so set it to max (512 KiB) */ 712 /* We do not handle DMA boundaries, so set it to max (512 KiB) */
713 writew(SDHCI_MAKE_BLKSZ(7, data->blksz), 713 sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
714 host->ioaddr + SDHCI_BLOCK_SIZE); 714 sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
715 writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
716} 715}
717 716
718static void sdhci_set_transfer_mode(struct sdhci_host *host, 717static void sdhci_set_transfer_mode(struct sdhci_host *host,
@@ -733,7 +732,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
733 if (host->flags & SDHCI_REQ_USE_DMA) 732 if (host->flags & SDHCI_REQ_USE_DMA)
734 mode |= SDHCI_TRNS_DMA; 733 mode |= SDHCI_TRNS_DMA;
735 734
736 writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE); 735 sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
737} 736}
738 737
739static void sdhci_finish_data(struct sdhci_host *host) 738static void sdhci_finish_data(struct sdhci_host *host)
@@ -802,7 +801,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
802 if (host->mrq->data && (cmd == host->mrq->data->stop)) 801 if (host->mrq->data && (cmd == host->mrq->data->stop))
803 mask &= ~SDHCI_DATA_INHIBIT; 802 mask &= ~SDHCI_DATA_INHIBIT;
804 803
805 while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { 804 while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
806 if (timeout == 0) { 805 if (timeout == 0) {
807 printk(KERN_ERR "%s: Controller never released " 806 printk(KERN_ERR "%s: Controller never released "
808 "inhibit bit(s).\n", mmc_hostname(host->mmc)); 807 "inhibit bit(s).\n", mmc_hostname(host->mmc));
@@ -821,7 +820,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
821 820
822 sdhci_prepare_data(host, cmd->data); 821 sdhci_prepare_data(host, cmd->data);
823 822
824 writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT); 823 sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
825 824
826 sdhci_set_transfer_mode(host, cmd->data); 825 sdhci_set_transfer_mode(host, cmd->data);
827 826
@@ -849,8 +848,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
849 if (cmd->data) 848 if (cmd->data)
850 flags |= SDHCI_CMD_DATA; 849 flags |= SDHCI_CMD_DATA;
851 850
852 writew(SDHCI_MAKE_CMD(cmd->opcode, flags), 851 sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
853 host->ioaddr + SDHCI_COMMAND);
854} 852}
855 853
856static void sdhci_finish_command(struct sdhci_host *host) 854static void sdhci_finish_command(struct sdhci_host *host)
@@ -863,15 +861,15 @@ static void sdhci_finish_command(struct sdhci_host *host)
863 if (host->cmd->flags & MMC_RSP_136) { 861 if (host->cmd->flags & MMC_RSP_136) {
864 /* CRC is stripped so we need to do some shifting. */ 862 /* CRC is stripped so we need to do some shifting. */
865 for (i = 0;i < 4;i++) { 863 for (i = 0;i < 4;i++) {
866 host->cmd->resp[i] = readl(host->ioaddr + 864 host->cmd->resp[i] = sdhci_readl(host,
867 SDHCI_RESPONSE + (3-i)*4) << 8; 865 SDHCI_RESPONSE + (3-i)*4) << 8;
868 if (i != 3) 866 if (i != 3)
869 host->cmd->resp[i] |= 867 host->cmd->resp[i] |=
870 readb(host->ioaddr + 868 sdhci_readb(host,
871 SDHCI_RESPONSE + (3-i)*4-1); 869 SDHCI_RESPONSE + (3-i)*4-1);
872 } 870 }
873 } else { 871 } else {
874 host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE); 872 host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
875 } 873 }
876 } 874 }
877 875
@@ -895,7 +893,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
895 if (clock == host->clock) 893 if (clock == host->clock)
896 return; 894 return;
897 895
898 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); 896 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
899 897
900 if (clock == 0) 898 if (clock == 0)
901 goto out; 899 goto out;
@@ -908,11 +906,11 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
908 906
909 clk = div << SDHCI_DIVIDER_SHIFT; 907 clk = div << SDHCI_DIVIDER_SHIFT;
910 clk |= SDHCI_CLOCK_INT_EN; 908 clk |= SDHCI_CLOCK_INT_EN;
911 writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); 909 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
912 910
913 /* Wait max 10 ms */ 911 /* Wait max 10 ms */
914 timeout = 10; 912 timeout = 10;
915 while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL)) 913 while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
916 & SDHCI_CLOCK_INT_STABLE)) { 914 & SDHCI_CLOCK_INT_STABLE)) {
917 if (timeout == 0) { 915 if (timeout == 0) {
918 printk(KERN_ERR "%s: Internal clock never " 916 printk(KERN_ERR "%s: Internal clock never "
@@ -925,7 +923,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
925 } 923 }
926 924
927 clk |= SDHCI_CLOCK_CARD_EN; 925 clk |= SDHCI_CLOCK_CARD_EN;
928 writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); 926 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
929 927
930out: 928out:
931 host->clock = clock; 929 host->clock = clock;
@@ -939,7 +937,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
939 return; 937 return;
940 938
941 if (power == (unsigned short)-1) { 939 if (power == (unsigned short)-1) {
942 writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); 940 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
943 goto out; 941 goto out;
944 } 942 }
945 943
@@ -948,7 +946,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
948 * a new value. Some controllers don't seem to like this though. 946 * a new value. Some controllers don't seem to like this though.
949 */ 947 */
950 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) 948 if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
951 writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); 949 sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
952 950
953 pwr = SDHCI_POWER_ON; 951 pwr = SDHCI_POWER_ON;
954 952
@@ -973,10 +971,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
973 * and set turn on power at the same time, so set the voltage first. 971 * and set turn on power at the same time, so set the voltage first.
974 */ 972 */
975 if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER)) 973 if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
976 writeb(pwr & ~SDHCI_POWER_ON, 974 sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
977 host->ioaddr + SDHCI_POWER_CONTROL);
978 975
979 writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL); 976 sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
980 977
981out: 978out:
982 host->power = power; 979 host->power = power;
@@ -1005,7 +1002,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
1005 1002
1006 host->mrq = mrq; 1003 host->mrq = mrq;
1007 1004
1008 if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT) 1005 if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
1009 || (host->flags & SDHCI_DEVICE_DEAD)) { 1006 || (host->flags & SDHCI_DEVICE_DEAD)) {
1010 host->mrq->cmd->error = -ENOMEDIUM; 1007 host->mrq->cmd->error = -ENOMEDIUM;
1011 tasklet_schedule(&host->finish_tasklet); 1008 tasklet_schedule(&host->finish_tasklet);
@@ -1034,7 +1031,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1034 * Should clear out any weird states. 1031 * Should clear out any weird states.
1035 */ 1032 */
1036 if (ios->power_mode == MMC_POWER_OFF) { 1033 if (ios->power_mode == MMC_POWER_OFF) {
1037 writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); 1034 sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
1038 sdhci_init(host); 1035 sdhci_init(host);
1039 } 1036 }
1040 1037
@@ -1045,7 +1042,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1045 else 1042 else
1046 sdhci_set_power(host, ios->vdd); 1043 sdhci_set_power(host, ios->vdd);
1047 1044
1048 ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); 1045 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
1049 1046
1050 if (ios->bus_width == MMC_BUS_WIDTH_4) 1047 if (ios->bus_width == MMC_BUS_WIDTH_4)
1051 ctrl |= SDHCI_CTRL_4BITBUS; 1048 ctrl |= SDHCI_CTRL_4BITBUS;
@@ -1057,7 +1054,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1057 else 1054 else
1058 ctrl &= ~SDHCI_CTRL_HISPD; 1055 ctrl &= ~SDHCI_CTRL_HISPD;
1059 1056
1060 writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); 1057 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1061 1058
1062 /* 1059 /*
1063 * Some (ENE) controllers go apeshit on some ios operation, 1060 * Some (ENE) controllers go apeshit on some ios operation,
@@ -1085,7 +1082,7 @@ static int sdhci_get_ro(struct mmc_host *mmc)
1085 if (host->flags & SDHCI_DEVICE_DEAD) 1082 if (host->flags & SDHCI_DEVICE_DEAD)
1086 present = 0; 1083 present = 0;
1087 else 1084 else
1088 present = readl(host->ioaddr + SDHCI_PRESENT_STATE); 1085 present = sdhci_readl(host, SDHCI_PRESENT_STATE);
1089 1086
1090 spin_unlock_irqrestore(&host->lock, flags); 1087 spin_unlock_irqrestore(&host->lock, flags);
1091 1088
@@ -1105,14 +1102,14 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1105 if (host->flags & SDHCI_DEVICE_DEAD) 1102 if (host->flags & SDHCI_DEVICE_DEAD)
1106 goto out; 1103 goto out;
1107 1104
1108 ier = readl(host->ioaddr + SDHCI_INT_ENABLE); 1105 ier = sdhci_readl(host, SDHCI_INT_ENABLE);
1109 1106
1110 ier &= ~SDHCI_INT_CARD_INT; 1107 ier &= ~SDHCI_INT_CARD_INT;
1111 if (enable) 1108 if (enable)
1112 ier |= SDHCI_INT_CARD_INT; 1109 ier |= SDHCI_INT_CARD_INT;
1113 1110
1114 writel(ier, host->ioaddr + SDHCI_INT_ENABLE); 1111 sdhci_writel(host, ier, SDHCI_INT_ENABLE);
1115 writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); 1112 sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
1116 1113
1117out: 1114out:
1118 mmiowb(); 1115 mmiowb();
@@ -1142,7 +1139,7 @@ static void sdhci_tasklet_card(unsigned long param)
1142 1139
1143 spin_lock_irqsave(&host->lock, flags); 1140 spin_lock_irqsave(&host->lock, flags);
1144 1141
1145 if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { 1142 if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
1146 if (host->mrq) { 1143 if (host->mrq) {
1147 printk(KERN_ERR "%s: Card removed during transfer!\n", 1144 printk(KERN_ERR "%s: Card removed during transfer!\n",
1148 mmc_hostname(host->mmc)); 1145 mmc_hostname(host->mmc));
@@ -1346,8 +1343,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
1346 * we need to at least restart the transfer. 1343 * we need to at least restart the transfer.
1347 */ 1344 */
1348 if (intmask & SDHCI_INT_DMA_END) 1345 if (intmask & SDHCI_INT_DMA_END)
1349 writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), 1346 sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
1350 host->ioaddr + SDHCI_DMA_ADDRESS); 1347 SDHCI_DMA_ADDRESS);
1351 1348
1352 if (intmask & SDHCI_INT_DATA_END) { 1349 if (intmask & SDHCI_INT_DATA_END) {
1353 if (host->cmd) { 1350 if (host->cmd) {
@@ -1373,7 +1370,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1373 1370
1374 spin_lock(&host->lock); 1371 spin_lock(&host->lock);
1375 1372
1376 intmask = readl(host->ioaddr + SDHCI_INT_STATUS); 1373 intmask = sdhci_readl(host, SDHCI_INT_STATUS);
1377 1374
1378 if (!intmask || intmask == 0xffffffff) { 1375 if (!intmask || intmask == 0xffffffff) {
1379 result = IRQ_NONE; 1376 result = IRQ_NONE;
@@ -1384,22 +1381,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1384 mmc_hostname(host->mmc), intmask); 1381 mmc_hostname(host->mmc), intmask);
1385 1382
1386 if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { 1383 if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
1387 writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), 1384 sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
1388 host->ioaddr + SDHCI_INT_STATUS); 1385 SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
1389 tasklet_schedule(&host->card_tasklet); 1386 tasklet_schedule(&host->card_tasklet);
1390 } 1387 }
1391 1388
1392 intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); 1389 intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
1393 1390
1394 if (intmask & SDHCI_INT_CMD_MASK) { 1391 if (intmask & SDHCI_INT_CMD_MASK) {
1395 writel(intmask & SDHCI_INT_CMD_MASK, 1392 sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
1396 host->ioaddr + SDHCI_INT_STATUS); 1393 SDHCI_INT_STATUS);
1397 sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); 1394 sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
1398 } 1395 }
1399 1396
1400 if (intmask & SDHCI_INT_DATA_MASK) { 1397 if (intmask & SDHCI_INT_DATA_MASK) {
1401 writel(intmask & SDHCI_INT_DATA_MASK, 1398 sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
1402 host->ioaddr + SDHCI_INT_STATUS); 1399 SDHCI_INT_STATUS);
1403 sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); 1400 sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
1404 } 1401 }
1405 1402
@@ -1410,7 +1407,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1410 if (intmask & SDHCI_INT_BUS_POWER) { 1407 if (intmask & SDHCI_INT_BUS_POWER) {
1411 printk(KERN_ERR "%s: Card is consuming too much power!\n", 1408 printk(KERN_ERR "%s: Card is consuming too much power!\n",
1412 mmc_hostname(host->mmc)); 1409 mmc_hostname(host->mmc));
1413 writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS); 1410 sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
1414 } 1411 }
1415 1412
1416 intmask &= ~SDHCI_INT_BUS_POWER; 1413 intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1425,7 +1422,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
1425 mmc_hostname(host->mmc), intmask); 1422 mmc_hostname(host->mmc), intmask);
1426 sdhci_dumpregs(host); 1423 sdhci_dumpregs(host);
1427 1424
1428 writel(intmask, host->ioaddr + SDHCI_INT_STATUS); 1425 sdhci_writel(host, intmask, SDHCI_INT_STATUS);
1429 } 1426 }
1430 1427
1431 result = IRQ_HANDLED; 1428 result = IRQ_HANDLED;
@@ -1537,7 +1534,7 @@ int sdhci_add_host(struct sdhci_host *host)
1537 1534
1538 sdhci_reset(host, SDHCI_RESET_ALL); 1535 sdhci_reset(host, SDHCI_RESET_ALL);
1539 1536
1540 host->version = readw(host->ioaddr + SDHCI_HOST_VERSION); 1537 host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
1541 host->version = (host->version & SDHCI_SPEC_VER_MASK) 1538 host->version = (host->version & SDHCI_SPEC_VER_MASK)
1542 >> SDHCI_SPEC_VER_SHIFT; 1539 >> SDHCI_SPEC_VER_SHIFT;
1543 if (host->version > SDHCI_SPEC_200) { 1540 if (host->version > SDHCI_SPEC_200) {
@@ -1546,7 +1543,7 @@ int sdhci_add_host(struct sdhci_host *host)
1546 host->version); 1543 host->version);
1547 } 1544 }
1548 1545
1549 caps = readl(host->ioaddr + SDHCI_CAPABILITIES); 1546 caps = sdhci_readl(host, SDHCI_CAPABILITIES);
1550 1547
1551 if (host->quirks & SDHCI_QUIRK_FORCE_DMA) 1548 if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
1552 host->flags |= SDHCI_USE_DMA; 1549 host->flags |= SDHCI_USE_DMA;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 43c37c68d07a..d9733f841061 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -10,6 +10,9 @@
10 */ 10 */
11 11
12#include <linux/scatterlist.h> 12#include <linux/scatterlist.h>
13#include <linux/compiler.h>
14#include <linux/types.h>
15#include <linux/io.h>
13 16
14/* 17/*
15 * Controller registers 18 * Controller registers
@@ -267,9 +270,101 @@ struct sdhci_host {
267 270
268 271
269struct sdhci_ops { 272struct sdhci_ops {
273#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
274 u32 (*readl)(struct sdhci_host *host, int reg);
275 u16 (*readw)(struct sdhci_host *host, int reg);
276 u8 (*readb)(struct sdhci_host *host, int reg);
277 void (*writel)(struct sdhci_host *host, u32 val, int reg);
278 void (*writew)(struct sdhci_host *host, u16 val, int reg);
279 void (*writeb)(struct sdhci_host *host, u8 val, int reg);
280#endif
281
270 int (*enable_dma)(struct sdhci_host *host); 282 int (*enable_dma)(struct sdhci_host *host);
271}; 283};
272 284
285#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
286
287static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
288{
289 if (unlikely(host->ops->writel))
290 host->ops->writel(host, val, reg);
291 else
292 writel(val, host->ioaddr + reg);
293}
294
295static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
296{
297 if (unlikely(host->ops->writew))
298 host->ops->writew(host, val, reg);
299 else
300 writew(val, host->ioaddr + reg);
301}
302
303static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
304{
305 if (unlikely(host->ops->writeb))
306 host->ops->writeb(host, val, reg);
307 else
308 writeb(val, host->ioaddr + reg);
309}
310
311static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
312{
313 if (unlikely(host->ops->readl))
314 return host->ops->readl(host, reg);
315 else
316 return readl(host->ioaddr + reg);
317}
318
319static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
320{
321 if (unlikely(host->ops->readw))
322 return host->ops->readw(host, reg);
323 else
324 return readw(host->ioaddr + reg);
325}
326
327static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
328{
329 if (unlikely(host->ops->readb))
330 return host->ops->readb(host, reg);
331 else
332 return readb(host->ioaddr + reg);
333}
334
335#else
336
337static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
338{
339 writel(val, host->ioaddr + reg);
340}
341
342static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
343{
344 writew(val, host->ioaddr + reg);
345}
346
347static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
348{
349 writeb(val, host->ioaddr + reg);
350}
351
352static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
353{
354 return readl(host->ioaddr + reg);
355}
356
357static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
358{
359 return readw(host->ioaddr + reg);
360}
361
362static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
363{
364 return readb(host->ioaddr + reg);
365}
366
367#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
273 368
274extern struct sdhci_host *sdhci_alloc_host(struct device *dev, 369extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
275 size_t priv_size); 370 size_t priv_size);