diff options
-rw-r--r-- | drivers/mmc/host/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.c | 159 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci.h | 95 |
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 | ||
40 | config 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 | |||
40 | config MMC_SDHCI_PCI | 47 | config 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 | ||
139 | static void sdhci_activate_led(struct sdhci_host *host) | 139 | static 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 | ||
148 | static void sdhci_deactivate_led(struct sdhci_host *host) | 148 | static 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 | ||
718 | static void sdhci_set_transfer_mode(struct sdhci_host *host, | 717 | static 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 | ||
739 | static void sdhci_finish_data(struct sdhci_host *host) | 738 | static 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 | ||
856 | static void sdhci_finish_command(struct sdhci_host *host) | 854 | static 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 | ||
930 | out: | 928 | out: |
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 | ||
981 | out: | 978 | out: |
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 | ||
1117 | out: | 1114 | out: |
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 | ||
269 | struct sdhci_ops { | 272 | struct 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 | |||
287 | static 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 | |||
295 | static 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 | |||
303 | static 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 | |||
311 | static 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 | |||
319 | static 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 | |||
327 | static 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 | |||
337 | static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg) | ||
338 | { | ||
339 | writel(val, host->ioaddr + reg); | ||
340 | } | ||
341 | |||
342 | static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg) | ||
343 | { | ||
344 | writew(val, host->ioaddr + reg); | ||
345 | } | ||
346 | |||
347 | static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg) | ||
348 | { | ||
349 | writeb(val, host->ioaddr + reg); | ||
350 | } | ||
351 | |||
352 | static inline u32 sdhci_readl(struct sdhci_host *host, int reg) | ||
353 | { | ||
354 | return readl(host->ioaddr + reg); | ||
355 | } | ||
356 | |||
357 | static inline u16 sdhci_readw(struct sdhci_host *host, int reg) | ||
358 | { | ||
359 | return readw(host->ioaddr + reg); | ||
360 | } | ||
361 | |||
362 | static 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 | ||
274 | extern struct sdhci_host *sdhci_alloc_host(struct device *dev, | 369 | extern struct sdhci_host *sdhci_alloc_host(struct device *dev, |
275 | size_t priv_size); | 370 | size_t priv_size); |