diff options
Diffstat (limited to 'drivers/mmc/wbsd.c')
-rw-r--r-- | drivers/mmc/wbsd.c | 80 |
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 | ||
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); |