diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/mmci.c | 9 | ||||
-rw-r--r-- | drivers/mmc/wbsd.c | 80 | ||||
-rw-r--r-- | drivers/mmc/wbsd.h | 9 |
3 files changed, 56 insertions, 42 deletions
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 3a5f6ac5b364..7a42966d755b 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mmc/host.h> | 20 | #include <linux/mmc/host.h> |
21 | #include <linux/mmc/protocol.h> | 21 | #include <linux/mmc/protocol.h> |
22 | 22 | ||
23 | #include <asm/div64.h> | ||
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
24 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
25 | #include <asm/scatterlist.h> | 26 | #include <asm/scatterlist.h> |
@@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_host *host) | |||
70 | static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | 71 | static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) |
71 | { | 72 | { |
72 | unsigned int datactrl, timeout, irqmask; | 73 | unsigned int datactrl, timeout, irqmask; |
74 | unsigned long long clks; | ||
73 | void __iomem *base; | 75 | void __iomem *base; |
74 | 76 | ||
75 | DBG(host, "blksz %04x blks %04x flags %08x\n", | 77 | DBG(host, "blksz %04x blks %04x flags %08x\n", |
@@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) | |||
81 | 83 | ||
82 | mmci_init_sg(host, data); | 84 | mmci_init_sg(host, data); |
83 | 85 | ||
84 | timeout = data->timeout_clks + | 86 | clks = (unsigned long long)data->timeout_ns * host->cclk; |
85 | ((unsigned long long)data->timeout_ns * host->cclk) / | 87 | do_div(clks, 1000000000UL); |
86 | 1000000000ULL; | 88 | |
89 | timeout = data->timeout_clks + (unsigned int)clks; | ||
87 | 90 | ||
88 | base = host->base; | 91 | base = host->base; |
89 | writel(timeout, base + MMCIDATATIMER); | 92 | writel(timeout, base + MMCIDATATIMER); |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index b7fbd30b49a0..0c41d4b41a65 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -54,28 +54,6 @@ | |||
54 | #define DBGF(x...) do { } while (0) | 54 | #define DBGF(x...) do { } while (0) |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | #ifdef CONFIG_MMC_DEBUG | ||
58 | void DBG_REG(int reg, u8 value) | ||
59 | { | ||
60 | int i; | ||
61 | |||
62 | printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ", | ||
63 | reg, (int)value, (int)value, (value < 0x20)?'.':value); | ||
64 | |||
65 | for (i = 7;i >= 0;i--) | ||
66 | { | ||
67 | if (value & (1 << i)) | ||
68 | printk("x"); | ||
69 | else | ||
70 | printk("."); | ||
71 | } | ||
72 | |||
73 | printk("\n"); | ||
74 | } | ||
75 | #else | ||
76 | #define DBG_REG(r, v) do {} while (0) | ||
77 | #endif | ||
78 | |||
79 | /* | 57 | /* |
80 | * Device resources | 58 | * Device resources |
81 | */ | 59 | */ |
@@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table); | |||
92 | 70 | ||
93 | #endif /* CONFIG_PNP */ | 71 | #endif /* CONFIG_PNP */ |
94 | 72 | ||
73 | static const int config_ports[] = { 0x2E, 0x4E }; | ||
74 | static const int unlock_codes[] = { 0x83, 0x87 }; | ||
75 | |||
76 | static const int valid_ids[] = { | ||
77 | 0x7112, | ||
78 | }; | ||
79 | |||
95 | #ifdef CONFIG_PNP | 80 | #ifdef CONFIG_PNP |
96 | static unsigned int nopnp = 0; | 81 | static unsigned int nopnp = 0; |
97 | #else | 82 | #else |
@@ -1051,6 +1036,20 @@ static struct mmc_host_ops wbsd_ops = { | |||
1051 | \*****************************************************************************/ | 1036 | \*****************************************************************************/ |
1052 | 1037 | ||
1053 | /* | 1038 | /* |
1039 | * Helper function for card detection | ||
1040 | */ | ||
1041 | static void wbsd_detect_card(unsigned long data) | ||
1042 | { | ||
1043 | struct wbsd_host *host = (struct wbsd_host*)data; | ||
1044 | |||
1045 | BUG_ON(host == NULL); | ||
1046 | |||
1047 | DBG("Executing card detection\n"); | ||
1048 | |||
1049 | mmc_detect_change(host->mmc); | ||
1050 | } | ||
1051 | |||
1052 | /* | ||
1054 | * Tasklets | 1053 | * Tasklets |
1055 | */ | 1054 | */ |
1056 | 1055 | ||
@@ -1075,7 +1074,6 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1075 | { | 1074 | { |
1076 | struct wbsd_host* host = (struct wbsd_host*)param; | 1075 | struct wbsd_host* host = (struct wbsd_host*)param; |
1077 | u8 csr; | 1076 | u8 csr; |
1078 | int change = 0; | ||
1079 | 1077 | ||
1080 | spin_lock(&host->lock); | 1078 | spin_lock(&host->lock); |
1081 | 1079 | ||
@@ -1094,14 +1092,20 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1094 | { | 1092 | { |
1095 | DBG("Card inserted\n"); | 1093 | DBG("Card inserted\n"); |
1096 | host->flags |= WBSD_FCARD_PRESENT; | 1094 | host->flags |= WBSD_FCARD_PRESENT; |
1097 | change = 1; | 1095 | |
1096 | /* | ||
1097 | * Delay card detection to allow electrical connections | ||
1098 | * to stabilise. | ||
1099 | */ | ||
1100 | mod_timer(&host->timer, jiffies + HZ/2); | ||
1098 | } | 1101 | } |
1102 | |||
1103 | spin_unlock(&host->lock); | ||
1099 | } | 1104 | } |
1100 | else if (host->flags & WBSD_FCARD_PRESENT) | 1105 | else if (host->flags & WBSD_FCARD_PRESENT) |
1101 | { | 1106 | { |
1102 | DBG("Card removed\n"); | 1107 | DBG("Card removed\n"); |
1103 | host->flags &= ~WBSD_FCARD_PRESENT; | 1108 | host->flags &= ~WBSD_FCARD_PRESENT; |
1104 | change = 1; | ||
1105 | 1109 | ||
1106 | if (host->mrq) | 1110 | if (host->mrq) |
1107 | { | 1111 | { |
@@ -1112,15 +1116,14 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1112 | host->mrq->cmd->error = MMC_ERR_FAILED; | 1116 | host->mrq->cmd->error = MMC_ERR_FAILED; |
1113 | tasklet_schedule(&host->finish_tasklet); | 1117 | tasklet_schedule(&host->finish_tasklet); |
1114 | } | 1118 | } |
1115 | } | 1119 | |
1116 | 1120 | /* | |
1117 | /* | 1121 | * Unlock first since we might get a call back. |
1118 | * Unlock first since we might get a call back. | 1122 | */ |
1119 | */ | 1123 | spin_unlock(&host->lock); |
1120 | spin_unlock(&host->lock); | ||
1121 | 1124 | ||
1122 | if (change) | ||
1123 | mmc_detect_change(host->mmc); | 1125 | mmc_detect_change(host->mmc); |
1126 | } | ||
1124 | } | 1127 | } |
1125 | 1128 | ||
1126 | static void wbsd_tasklet_fifo(unsigned long param) | 1129 | static void wbsd_tasklet_fifo(unsigned long param) |
@@ -1325,6 +1328,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
1325 | spin_lock_init(&host->lock); | 1328 | spin_lock_init(&host->lock); |
1326 | 1329 | ||
1327 | /* | 1330 | /* |
1331 | * Set up detection timer | ||
1332 | */ | ||
1333 | init_timer(&host->timer); | ||
1334 | host->timer.data = (unsigned long)host; | ||
1335 | host->timer.function = wbsd_detect_card; | ||
1336 | |||
1337 | /* | ||
1328 | * Maximum number of segments. Worst case is one sector per segment | 1338 | * Maximum number of segments. Worst case is one sector per segment |
1329 | * so this will be 64kB/512. | 1339 | * so this will be 64kB/512. |
1330 | */ | 1340 | */ |
@@ -1351,11 +1361,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) | |||
1351 | static void __devexit wbsd_free_mmc(struct device* dev) | 1361 | static void __devexit wbsd_free_mmc(struct device* dev) |
1352 | { | 1362 | { |
1353 | struct mmc_host* mmc; | 1363 | struct mmc_host* mmc; |
1364 | struct wbsd_host* host; | ||
1354 | 1365 | ||
1355 | mmc = dev_get_drvdata(dev); | 1366 | mmc = dev_get_drvdata(dev); |
1356 | if (!mmc) | 1367 | if (!mmc) |
1357 | return; | 1368 | return; |
1358 | 1369 | ||
1370 | host = mmc_priv(mmc); | ||
1371 | BUG_ON(host == NULL); | ||
1372 | |||
1373 | del_timer_sync(&host->timer); | ||
1374 | |||
1359 | mmc_free_host(mmc); | 1375 | mmc_free_host(mmc); |
1360 | 1376 | ||
1361 | dev_set_drvdata(dev, NULL); | 1377 | dev_set_drvdata(dev, NULL); |
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index 864f30828d01..661a9f6a6e6f 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h | |||
@@ -8,13 +8,6 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | const int config_ports[] = { 0x2E, 0x4E }; | ||
12 | const int unlock_codes[] = { 0x83, 0x87 }; | ||
13 | |||
14 | const int valid_ids[] = { | ||
15 | 0x7112, | ||
16 | }; | ||
17 | |||
18 | #define LOCK_CODE 0xAA | 11 | #define LOCK_CODE 0xAA |
19 | 12 | ||
20 | #define WBSD_CONF_SWRST 0x02 | 13 | #define WBSD_CONF_SWRST 0x02 |
@@ -187,4 +180,6 @@ struct wbsd_host | |||
187 | struct tasklet_struct timeout_tasklet; | 180 | struct tasklet_struct timeout_tasklet; |
188 | struct tasklet_struct finish_tasklet; | 181 | struct tasklet_struct finish_tasklet; |
189 | struct tasklet_struct block_tasklet; | 182 | struct tasklet_struct block_tasklet; |
183 | |||
184 | struct timer_list timer; /* Card detection timer */ | ||
190 | }; | 185 | }; |