aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/Makefile1
-rw-r--r--drivers/mmc/core/bus.c8
-rw-r--r--drivers/mmc/core/core.h7
-rw-r--r--drivers/mmc/core/debugfs.c225
-rw-r--r--drivers/mmc/core/host.c8
-rw-r--r--drivers/mmc/host/atmel-mci-regs.h2
-rw-r--r--drivers/mmc/host/atmel-mci.c189
-rw-r--r--drivers/mmc/host/imxmmc.c50
-rw-r--r--drivers/mmc/host/mmc_spi.c3
9 files changed, 457 insertions, 36 deletions
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 19a1a254a0c5..889e5f898f6f 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -12,3 +12,4 @@ mmc_core-y := core.o bus.o host.o \
12 sdio.o sdio_ops.o sdio_bus.o \ 12 sdio.o sdio_ops.o sdio_bus.o \
13 sdio_cis.o sdio_io.o sdio_irq.o 13 sdio_cis.o sdio_io.o sdio_irq.o
14 14
15mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index fd95b18e988b..0d9b2d6f9ebf 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -252,6 +252,10 @@ int mmc_add_card(struct mmc_card *card)
252 if (ret) 252 if (ret)
253 return ret; 253 return ret;
254 254
255#ifdef CONFIG_DEBUG_FS
256 mmc_add_card_debugfs(card);
257#endif
258
255 mmc_card_set_present(card); 259 mmc_card_set_present(card);
256 260
257 return 0; 261 return 0;
@@ -263,6 +267,10 @@ int mmc_add_card(struct mmc_card *card)
263 */ 267 */
264void mmc_remove_card(struct mmc_card *card) 268void mmc_remove_card(struct mmc_card *card)
265{ 269{
270#ifdef CONFIG_DEBUG_FS
271 mmc_remove_card_debugfs(card);
272#endif
273
266 if (mmc_card_present(card)) { 274 if (mmc_card_present(card)) {
267 if (mmc_host_is_spi(card->host)) { 275 if (mmc_host_is_spi(card->host)) {
268 printk(KERN_INFO "%s: SPI card removed\n", 276 printk(KERN_INFO "%s: SPI card removed\n",
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index cdb332b7dedc..c819effa1032 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -52,5 +52,12 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
52 52
53extern int use_spi_crc; 53extern int use_spi_crc;
54 54
55/* Debugfs information for hosts and cards */
56void mmc_add_host_debugfs(struct mmc_host *host);
57void mmc_remove_host_debugfs(struct mmc_host *host);
58
59void mmc_add_card_debugfs(struct mmc_card *card);
60void mmc_remove_card_debugfs(struct mmc_card *card);
61
55#endif 62#endif
56 63
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
new file mode 100644
index 000000000000..1237bb4c722b
--- /dev/null
+++ b/drivers/mmc/core/debugfs.c
@@ -0,0 +1,225 @@
1/*
2 * Debugfs support for hosts and cards
3 *
4 * Copyright (C) 2008 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/debugfs.h>
11#include <linux/fs.h>
12#include <linux/seq_file.h>
13#include <linux/stat.h>
14
15#include <linux/mmc/card.h>
16#include <linux/mmc/host.h>
17
18#include "core.h"
19#include "mmc_ops.h"
20
21/* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */
22static int mmc_ios_show(struct seq_file *s, void *data)
23{
24 static const char *vdd_str[] = {
25 [8] = "2.0",
26 [9] = "2.1",
27 [10] = "2.2",
28 [11] = "2.3",
29 [12] = "2.4",
30 [13] = "2.5",
31 [14] = "2.6",
32 [15] = "2.7",
33 [16] = "2.8",
34 [17] = "2.9",
35 [18] = "3.0",
36 [19] = "3.1",
37 [20] = "3.2",
38 [21] = "3.3",
39 [22] = "3.4",
40 [23] = "3.5",
41 [24] = "3.6",
42 };
43 struct mmc_host *host = s->private;
44 struct mmc_ios *ios = &host->ios;
45 const char *str;
46
47 seq_printf(s, "clock:\t\t%u Hz\n", ios->clock);
48 seq_printf(s, "vdd:\t\t%u ", ios->vdd);
49 if ((1 << ios->vdd) & MMC_VDD_165_195)
50 seq_printf(s, "(1.65 - 1.95 V)\n");
51 else if (ios->vdd < (ARRAY_SIZE(vdd_str) - 1)
52 && vdd_str[ios->vdd] && vdd_str[ios->vdd + 1])
53 seq_printf(s, "(%s ~ %s V)\n", vdd_str[ios->vdd],
54 vdd_str[ios->vdd + 1]);
55 else
56 seq_printf(s, "(invalid)\n");
57
58 switch (ios->bus_mode) {
59 case MMC_BUSMODE_OPENDRAIN:
60 str = "open drain";
61 break;
62 case MMC_BUSMODE_PUSHPULL:
63 str = "push-pull";
64 break;
65 default:
66 str = "invalid";
67 break;
68 }
69 seq_printf(s, "bus mode:\t%u (%s)\n", ios->bus_mode, str);
70
71 switch (ios->chip_select) {
72 case MMC_CS_DONTCARE:
73 str = "don't care";
74 break;
75 case MMC_CS_HIGH:
76 str = "active high";
77 break;
78 case MMC_CS_LOW:
79 str = "active low";
80 break;
81 default:
82 str = "invalid";
83 break;
84 }
85 seq_printf(s, "chip select:\t%u (%s)\n", ios->chip_select, str);
86
87 switch (ios->power_mode) {
88 case MMC_POWER_OFF:
89 str = "off";
90 break;
91 case MMC_POWER_UP:
92 str = "up";
93 break;
94 case MMC_POWER_ON:
95 str = "on";
96 break;
97 default:
98 str = "invalid";
99 break;
100 }
101 seq_printf(s, "power mode:\t%u (%s)\n", ios->power_mode, str);
102 seq_printf(s, "bus width:\t%u (%u bits)\n",
103 ios->bus_width, 1 << ios->bus_width);
104
105 switch (ios->timing) {
106 case MMC_TIMING_LEGACY:
107 str = "legacy";
108 break;
109 case MMC_TIMING_MMC_HS:
110 str = "mmc high-speed";
111 break;
112 case MMC_TIMING_SD_HS:
113 str = "sd high-speed";
114 break;
115 default:
116 str = "invalid";
117 break;
118 }
119 seq_printf(s, "timing spec:\t%u (%s)\n", ios->timing, str);
120
121 return 0;
122}
123
124static int mmc_ios_open(struct inode *inode, struct file *file)
125{
126 return single_open(file, mmc_ios_show, inode->i_private);
127}
128
129static const struct file_operations mmc_ios_fops = {
130 .open = mmc_ios_open,
131 .read = seq_read,
132 .llseek = seq_lseek,
133 .release = single_release,
134};
135
136void mmc_add_host_debugfs(struct mmc_host *host)
137{
138 struct dentry *root;
139
140 root = debugfs_create_dir(mmc_hostname(host), NULL);
141 if (IS_ERR(root))
142 /* Don't complain -- debugfs just isn't enabled */
143 return;
144 if (!root)
145 /* Complain -- debugfs is enabled, but it failed to
146 * create the directory. */
147 goto err_root;
148
149 host->debugfs_root = root;
150
151 if (!debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops))
152 goto err_ios;
153
154 return;
155
156err_ios:
157 debugfs_remove_recursive(root);
158 host->debugfs_root = NULL;
159err_root:
160 dev_err(&host->class_dev, "failed to initialize debugfs\n");
161}
162
163void mmc_remove_host_debugfs(struct mmc_host *host)
164{
165 debugfs_remove_recursive(host->debugfs_root);
166}
167
168static int mmc_dbg_card_status_get(void *data, u64 *val)
169{
170 struct mmc_card *card = data;
171 u32 status;
172 int ret;
173
174 mmc_claim_host(card->host);
175
176 ret = mmc_send_status(data, &status);
177 if (!ret)
178 *val = status;
179
180 mmc_release_host(card->host);
181
182 return ret;
183}
184DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
185 NULL, "%08llx\n");
186
187void mmc_add_card_debugfs(struct mmc_card *card)
188{
189 struct mmc_host *host = card->host;
190 struct dentry *root;
191
192 if (!host->debugfs_root)
193 return;
194
195 root = debugfs_create_dir(mmc_card_id(card), host->debugfs_root);
196 if (IS_ERR(root))
197 /* Don't complain -- debugfs just isn't enabled */
198 return;
199 if (!root)
200 /* Complain -- debugfs is enabled, but it failed to
201 * create the directory. */
202 goto err;
203
204 card->debugfs_root = root;
205
206 if (!debugfs_create_x32("state", S_IRUSR, root, &card->state))
207 goto err;
208
209 if (mmc_card_mmc(card) || mmc_card_sd(card))
210 if (!debugfs_create_file("status", S_IRUSR, root, card,
211 &mmc_dbg_card_status_fops))
212 goto err;
213
214 return;
215
216err:
217 debugfs_remove_recursive(root);
218 card->debugfs_root = NULL;
219 dev_err(&card->dev, "failed to initialize debugfs\n");
220}
221
222void mmc_remove_card_debugfs(struct mmc_card *card)
223{
224 debugfs_remove_recursive(card->debugfs_root);
225}
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 1d795c5379b5..6da80fd4d974 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -127,6 +127,10 @@ int mmc_add_host(struct mmc_host *host)
127 if (err) 127 if (err)
128 return err; 128 return err;
129 129
130#ifdef CONFIG_DEBUG_FS
131 mmc_add_host_debugfs(host);
132#endif
133
130 mmc_start_host(host); 134 mmc_start_host(host);
131 135
132 return 0; 136 return 0;
@@ -146,6 +150,10 @@ void mmc_remove_host(struct mmc_host *host)
146{ 150{
147 mmc_stop_host(host); 151 mmc_stop_host(host);
148 152
153#ifdef CONFIG_DEBUG_FS
154 mmc_remove_host_debugfs(host);
155#endif
156
149 device_del(&host->class_dev); 157 device_del(&host->class_dev);
150 158
151 led_trigger_unregister_simple(host->led); 159 led_trigger_unregister_simple(host->led);
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
index a9a5657706c6..26bd80e65031 100644
--- a/drivers/mmc/host/atmel-mci-regs.h
+++ b/drivers/mmc/host/atmel-mci-regs.h
@@ -82,6 +82,8 @@
82# define MCI_OVRE ( 1 << 30) /* RX Overrun Error */ 82# define MCI_OVRE ( 1 << 30) /* RX Overrun Error */
83# define MCI_UNRE ( 1 << 31) /* TX Underrun Error */ 83# define MCI_UNRE ( 1 << 31) /* TX Underrun Error */
84 84
85#define MCI_REGS_SIZE 0x100
86
85/* Register access macros */ 87/* Register access macros */
86#define mci_readl(port,reg) \ 88#define mci_readl(port,reg) \
87 __raw_readl((port)->regs + MCI_##reg) 89 __raw_readl((port)->regs + MCI_##reg)
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index cce873c5a149..b68381f7bfdd 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/blkdev.h> 10#include <linux/blkdev.h>
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/debugfs.h>
12#include <linux/device.h> 13#include <linux/device.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/interrupt.h> 15#include <linux/interrupt.h>
@@ -16,6 +17,8 @@
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <linux/seq_file.h>
21#include <linux/stat.h>
19 22
20#include <linux/mmc/host.h> 23#include <linux/mmc/host.h>
21 24
@@ -88,6 +91,188 @@ struct atmel_mci {
88#define atmci_clear_pending(host, event) \ 91#define atmci_clear_pending(host, event) \
89 clear_bit(event, &host->pending_events) 92 clear_bit(event, &host->pending_events)
90 93
94/*
95 * The debugfs stuff below is mostly optimized away when
96 * CONFIG_DEBUG_FS is not set.
97 */
98static int atmci_req_show(struct seq_file *s, void *v)
99{
100 struct atmel_mci *host = s->private;
101 struct mmc_request *mrq = host->mrq;
102 struct mmc_command *cmd;
103 struct mmc_command *stop;
104 struct mmc_data *data;
105
106 /* Make sure we get a consistent snapshot */
107 spin_lock_irq(&host->mmc->lock);
108
109 if (mrq) {
110 cmd = mrq->cmd;
111 data = mrq->data;
112 stop = mrq->stop;
113
114 if (cmd)
115 seq_printf(s,
116 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
117 cmd->opcode, cmd->arg, cmd->flags,
118 cmd->resp[0], cmd->resp[1], cmd->resp[2],
119 cmd->resp[2], cmd->error);
120 if (data)
121 seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
122 data->bytes_xfered, data->blocks,
123 data->blksz, data->flags, data->error);
124 if (stop)
125 seq_printf(s,
126 "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
127 stop->opcode, stop->arg, stop->flags,
128 stop->resp[0], stop->resp[1], stop->resp[2],
129 stop->resp[2], stop->error);
130 }
131
132 spin_unlock_irq(&host->mmc->lock);
133
134 return 0;
135}
136
137static int atmci_req_open(struct inode *inode, struct file *file)
138{
139 return single_open(file, atmci_req_show, inode->i_private);
140}
141
142static const struct file_operations atmci_req_fops = {
143 .owner = THIS_MODULE,
144 .open = atmci_req_open,
145 .read = seq_read,
146 .llseek = seq_lseek,
147 .release = single_release,
148};
149
150static void atmci_show_status_reg(struct seq_file *s,
151 const char *regname, u32 value)
152{
153 static const char *sr_bit[] = {
154 [0] = "CMDRDY",
155 [1] = "RXRDY",
156 [2] = "TXRDY",
157 [3] = "BLKE",
158 [4] = "DTIP",
159 [5] = "NOTBUSY",
160 [8] = "SDIOIRQA",
161 [9] = "SDIOIRQB",
162 [16] = "RINDE",
163 [17] = "RDIRE",
164 [18] = "RCRCE",
165 [19] = "RENDE",
166 [20] = "RTOE",
167 [21] = "DCRCE",
168 [22] = "DTOE",
169 [30] = "OVRE",
170 [31] = "UNRE",
171 };
172 unsigned int i;
173
174 seq_printf(s, "%s:\t0x%08x", regname, value);
175 for (i = 0; i < ARRAY_SIZE(sr_bit); i++) {
176 if (value & (1 << i)) {
177 if (sr_bit[i])
178 seq_printf(s, " %s", sr_bit[i]);
179 else
180 seq_puts(s, " UNKNOWN");
181 }
182 }
183 seq_putc(s, '\n');
184}
185
186static int atmci_regs_show(struct seq_file *s, void *v)
187{
188 struct atmel_mci *host = s->private;
189 u32 *buf;
190
191 buf = kmalloc(MCI_REGS_SIZE, GFP_KERNEL);
192 if (!buf)
193 return -ENOMEM;
194
195 /* Grab a more or less consistent snapshot */
196 spin_lock_irq(&host->mmc->lock);
197 memcpy_fromio(buf, host->regs, MCI_REGS_SIZE);
198 spin_unlock_irq(&host->mmc->lock);
199
200 seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
201 buf[MCI_MR / 4],
202 buf[MCI_MR / 4] & MCI_MR_RDPROOF ? " RDPROOF" : "",
203 buf[MCI_MR / 4] & MCI_MR_WRPROOF ? " WRPROOF" : "",
204 buf[MCI_MR / 4] & 0xff);
205 seq_printf(s, "DTOR:\t0x%08x\n", buf[MCI_DTOR / 4]);
206 seq_printf(s, "SDCR:\t0x%08x\n", buf[MCI_SDCR / 4]);
207 seq_printf(s, "ARGR:\t0x%08x\n", buf[MCI_ARGR / 4]);
208 seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n",
209 buf[MCI_BLKR / 4],
210 buf[MCI_BLKR / 4] & 0xffff,
211 (buf[MCI_BLKR / 4] >> 16) & 0xffff);
212
213 /* Don't read RSPR and RDR; it will consume the data there */
214
215 atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
216 atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
217
218 return 0;
219}
220
221static int atmci_regs_open(struct inode *inode, struct file *file)
222{
223 return single_open(file, atmci_regs_show, inode->i_private);
224}
225
226static const struct file_operations atmci_regs_fops = {
227 .owner = THIS_MODULE,
228 .open = atmci_regs_open,
229 .read = seq_read,
230 .llseek = seq_lseek,
231 .release = single_release,
232};
233
234static void atmci_init_debugfs(struct atmel_mci *host)
235{
236 struct mmc_host *mmc;
237 struct dentry *root;
238 struct dentry *node;
239 struct resource *res;
240
241 mmc = host->mmc;
242 root = mmc->debugfs_root;
243 if (!root)
244 return;
245
246 node = debugfs_create_file("regs", S_IRUSR, root, host,
247 &atmci_regs_fops);
248 if (IS_ERR(node))
249 return;
250 if (!node)
251 goto err;
252
253 res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
254 node->d_inode->i_size = res->end - res->start + 1;
255
256 node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops);
257 if (!node)
258 goto err;
259
260 node = debugfs_create_x32("pending_events", S_IRUSR, root,
261 (u32 *)&host->pending_events);
262 if (!node)
263 goto err;
264
265 node = debugfs_create_x32("completed_events", S_IRUSR, root,
266 (u32 *)&host->completed_events);
267 if (!node)
268 goto err;
269
270 return;
271
272err:
273 dev_err(&host->pdev->dev,
274 "failed to initialize debugfs for controller\n");
275}
91 276
92static void atmci_enable(struct atmel_mci *host) 277static void atmci_enable(struct atmel_mci *host)
93{ 278{
@@ -905,6 +1090,8 @@ static int __init atmci_probe(struct platform_device *pdev)
905 "Atmel MCI controller at 0x%08lx irq %d\n", 1090 "Atmel MCI controller at 0x%08lx irq %d\n",
906 host->mapbase, irq); 1091 host->mapbase, irq);
907 1092
1093 atmci_init_debugfs(host);
1094
908 return 0; 1095 return 0;
909 1096
910err_request_irq: 1097err_request_irq:
@@ -923,6 +1110,8 @@ static int __exit atmci_remove(struct platform_device *pdev)
923 platform_set_drvdata(pdev, NULL); 1110 platform_set_drvdata(pdev, NULL);
924 1111
925 if (host) { 1112 if (host) {
1113 /* Debugfs stuff is cleaned up by mmc core */
1114
926 if (host->detect_pin >= 0) { 1115 if (host->detect_pin >= 0) {
927 int pin = host->detect_pin; 1116 int pin = host->detect_pin;
928 1117
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 5e880c0f1349..f61406da65d2 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -26,12 +26,6 @@
26 * 26 *
27 */ 27 */
28 28
29#ifdef CONFIG_MMC_DEBUG
30#define DEBUG
31#else
32#undef DEBUG
33#endif
34
35#include <linux/module.h> 29#include <linux/module.h>
36#include <linux/init.h> 30#include <linux/init.h>
37#include <linux/ioport.h> 31#include <linux/ioport.h>
@@ -907,31 +901,12 @@ static const struct mmc_host_ops imxmci_ops = {
907 .get_ro = imxmci_get_ro, 901 .get_ro = imxmci_get_ro,
908}; 902};
909 903
910static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
911{
912 int i;
913
914 for (i = 0; i < dev->num_resources; i++)
915 if (dev->resource[i].flags == mask && nr-- == 0)
916 return &dev->resource[i];
917 return NULL;
918}
919
920static int platform_device_irq(struct platform_device *dev, int nr)
921{
922 int i;
923
924 for (i = 0; i < dev->num_resources; i++)
925 if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0)
926 return dev->resource[i].start;
927 return NO_IRQ;
928}
929
930static void imxmci_check_status(unsigned long data) 904static void imxmci_check_status(unsigned long data)
931{ 905{
932 struct imxmci_host *host = (struct imxmci_host *)data; 906 struct imxmci_host *host = (struct imxmci_host *)data;
933 907
934 if( host->pdata->card_present(mmc_dev(host->mmc)) != host->present ) { 908 if (host->pdata && host->pdata->card_present &&
909 host->pdata->card_present(mmc_dev(host->mmc)) != host->present) {
935 host->present ^= 1; 910 host->present ^= 1;
936 dev_info(mmc_dev(host->mmc), "card %s\n", 911 dev_info(mmc_dev(host->mmc), "card %s\n",
937 host->present ? "inserted" : "removed"); 912 host->present ? "inserted" : "removed");
@@ -962,13 +937,12 @@ static int imxmci_probe(struct platform_device *pdev)
962 937
963 printk(KERN_INFO "i.MX mmc driver\n"); 938 printk(KERN_INFO "i.MX mmc driver\n");
964 939
965 r = platform_device_resource(pdev, IORESOURCE_MEM, 0); 940 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
966 irq = platform_device_irq(pdev, 0); 941 irq = platform_get_irq(pdev, 0);
967 if (!r || irq == NO_IRQ) 942 if (!r || irq < 0)
968 return -ENXIO; 943 return -ENXIO;
969 944
970 r = request_mem_region(r->start, 0x100, "IMXMCI"); 945 if (!request_mem_region(r->start, 0x100, pdev->name))
971 if (!r)
972 return -EBUSY; 946 return -EBUSY;
973 947
974 mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev); 948 mmc = mmc_alloc_host(sizeof(struct imxmci_host), &pdev->dev);
@@ -995,6 +969,8 @@ static int imxmci_probe(struct platform_device *pdev)
995 host->mmc = mmc; 969 host->mmc = mmc;
996 host->dma_allocated = 0; 970 host->dma_allocated = 0;
997 host->pdata = pdev->dev.platform_data; 971 host->pdata = pdev->dev.platform_data;
972 if (!host->pdata)
973 dev_warn(&pdev->dev, "No platform data provided!\n");
998 974
999 spin_lock_init(&host->lock); 975 spin_lock_init(&host->lock);
1000 host->res = r; 976 host->res = r;
@@ -1047,7 +1023,11 @@ static int imxmci_probe(struct platform_device *pdev)
1047 if (ret) 1023 if (ret)
1048 goto out; 1024 goto out;
1049 1025
1050 host->present = host->pdata->card_present(mmc_dev(mmc)); 1026 if (host->pdata && host->pdata->card_present)
1027 host->present = host->pdata->card_present(mmc_dev(mmc));
1028 else /* if there is no way to detect assume that card is present */
1029 host->present = 1;
1030
1051 init_timer(&host->timer); 1031 init_timer(&host->timer);
1052 host->timer.data = (unsigned long)host; 1032 host->timer.data = (unsigned long)host;
1053 host->timer.function = imxmci_check_status; 1033 host->timer.function = imxmci_check_status;
@@ -1073,7 +1053,7 @@ out:
1073 } 1053 }
1074 if (mmc) 1054 if (mmc)
1075 mmc_free_host(mmc); 1055 mmc_free_host(mmc);
1076 release_resource(r); 1056 release_mem_region(r->start, 0x100);
1077 return ret; 1057 return ret;
1078} 1058}
1079 1059
@@ -1102,7 +1082,7 @@ static int imxmci_remove(struct platform_device *pdev)
1102 clk_disable(host->clk); 1082 clk_disable(host->clk);
1103 clk_put(host->clk); 1083 clk_put(host->clk);
1104 1084
1105 release_resource(host->res); 1085 release_mem_region(host->res->start, 0x100);
1106 1086
1107 mmc_free_host(mmc); 1087 mmc_free_host(mmc);
1108 } 1088 }
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 41cc63360e43..7503b81374e0 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1076,6 +1076,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1076 */ 1076 */
1077 if (canpower && ios->power_mode == MMC_POWER_OFF) { 1077 if (canpower && ios->power_mode == MMC_POWER_OFF) {
1078 int mres; 1078 int mres;
1079 u8 nullbyte = 0;
1079 1080
1080 host->spi->mode &= ~(SPI_CPOL|SPI_CPHA); 1081 host->spi->mode &= ~(SPI_CPOL|SPI_CPHA);
1081 mres = spi_setup(host->spi); 1082 mres = spi_setup(host->spi);
@@ -1083,7 +1084,7 @@ static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1083 dev_dbg(&host->spi->dev, 1084 dev_dbg(&host->spi->dev,
1084 "switch to SPI mode 0 failed\n"); 1085 "switch to SPI mode 0 failed\n");
1085 1086
1086 if (spi_w8r8(host->spi, 0x00) < 0) 1087 if (spi_write(host->spi, &nullbyte, 1) < 0)
1087 dev_dbg(&host->spi->dev, 1088 dev_dbg(&host->spi->dev,
1088 "put spi signals to low failed\n"); 1089 "put spi signals to low failed\n");
1089 1090