aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/wbsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/wbsd.c')
-rw-r--r--drivers/mmc/wbsd.c80
1 files changed, 48 insertions, 32 deletions
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
58void 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
73static const int config_ports[] = { 0x2E, 0x4E };
74static const int unlock_codes[] = { 0x83, 0x87 };
75
76static const int valid_ids[] = {
77 0x7112,
78 };
79
95#ifdef CONFIG_PNP 80#ifdef CONFIG_PNP
96static unsigned int nopnp = 0; 81static 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 */
1041static 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
1126static void wbsd_tasklet_fifo(unsigned long param) 1129static 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)
1351static void __devexit wbsd_free_mmc(struct device* dev) 1361static 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);