diff options
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r-- | drivers/mmc/sdhci.c | 91 |
1 files changed, 53 insertions, 38 deletions
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index c2d13d7e9911..4bf1fea5e2c4 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c | |||
@@ -37,6 +37,7 @@ static unsigned int debug_quirks = 0; | |||
37 | #define SDHCI_QUIRK_FORCE_DMA (1<<1) | 37 | #define SDHCI_QUIRK_FORCE_DMA (1<<1) |
38 | /* Controller doesn't like some resets when there is no card inserted. */ | 38 | /* Controller doesn't like some resets when there is no card inserted. */ |
39 | #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) | 39 | #define SDHCI_QUIRK_NO_CARD_NO_RESET (1<<2) |
40 | #define SDHCI_QUIRK_SINGLE_POWER_WRITE (1<<3) | ||
40 | 41 | ||
41 | static const struct pci_device_id pci_ids[] __devinitdata = { | 42 | static const struct pci_device_id pci_ids[] __devinitdata = { |
42 | { | 43 | { |
@@ -65,6 +66,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = { | |||
65 | .driver_data = SDHCI_QUIRK_FORCE_DMA, | 66 | .driver_data = SDHCI_QUIRK_FORCE_DMA, |
66 | }, | 67 | }, |
67 | 68 | ||
69 | { | ||
70 | .vendor = PCI_VENDOR_ID_ENE, | ||
71 | .device = PCI_DEVICE_ID_ENE_CB712_SD, | ||
72 | .subvendor = PCI_ANY_ID, | ||
73 | .subdevice = PCI_ANY_ID, | ||
74 | .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE, | ||
75 | }, | ||
76 | |||
68 | { /* Generic SD host controller */ | 77 | { /* Generic SD host controller */ |
69 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) | 78 | PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) |
70 | }, | 79 | }, |
@@ -197,15 +206,9 @@ static void sdhci_deactivate_led(struct sdhci_host *host) | |||
197 | * * | 206 | * * |
198 | \*****************************************************************************/ | 207 | \*****************************************************************************/ |
199 | 208 | ||
200 | static inline char* sdhci_kmap_sg(struct sdhci_host* host) | 209 | static inline char* sdhci_sg_to_buffer(struct sdhci_host* host) |
201 | { | 210 | { |
202 | host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ); | 211 | return page_address(host->cur_sg->page) + host->cur_sg->offset; |
203 | return host->mapped_sg + host->cur_sg->offset; | ||
204 | } | ||
205 | |||
206 | static inline void sdhci_kunmap_sg(struct sdhci_host* host) | ||
207 | { | ||
208 | kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ); | ||
209 | } | 212 | } |
210 | 213 | ||
211 | static inline int sdhci_next_sg(struct sdhci_host* host) | 214 | static inline int sdhci_next_sg(struct sdhci_host* host) |
@@ -240,7 +243,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) | |||
240 | chunk_remain = 0; | 243 | chunk_remain = 0; |
241 | data = 0; | 244 | data = 0; |
242 | 245 | ||
243 | buffer = sdhci_kmap_sg(host) + host->offset; | 246 | buffer = sdhci_sg_to_buffer(host) + host->offset; |
244 | 247 | ||
245 | while (blksize) { | 248 | while (blksize) { |
246 | if (chunk_remain == 0) { | 249 | if (chunk_remain == 0) { |
@@ -264,16 +267,13 @@ static void sdhci_read_block_pio(struct sdhci_host *host) | |||
264 | } | 267 | } |
265 | 268 | ||
266 | if (host->remain == 0) { | 269 | if (host->remain == 0) { |
267 | sdhci_kunmap_sg(host); | ||
268 | if (sdhci_next_sg(host) == 0) { | 270 | if (sdhci_next_sg(host) == 0) { |
269 | BUG_ON(blksize != 0); | 271 | BUG_ON(blksize != 0); |
270 | return; | 272 | return; |
271 | } | 273 | } |
272 | buffer = sdhci_kmap_sg(host); | 274 | buffer = sdhci_sg_to_buffer(host); |
273 | } | 275 | } |
274 | } | 276 | } |
275 | |||
276 | sdhci_kunmap_sg(host); | ||
277 | } | 277 | } |
278 | 278 | ||
279 | static void sdhci_write_block_pio(struct sdhci_host *host) | 279 | static void sdhci_write_block_pio(struct sdhci_host *host) |
@@ -290,7 +290,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host) | |||
290 | data = 0; | 290 | data = 0; |
291 | 291 | ||
292 | bytes = 0; | 292 | bytes = 0; |
293 | buffer = sdhci_kmap_sg(host) + host->offset; | 293 | buffer = sdhci_sg_to_buffer(host) + host->offset; |
294 | 294 | ||
295 | while (blksize) { | 295 | while (blksize) { |
296 | size = min(host->size, host->remain); | 296 | size = min(host->size, host->remain); |
@@ -314,16 +314,13 @@ static void sdhci_write_block_pio(struct sdhci_host *host) | |||
314 | } | 314 | } |
315 | 315 | ||
316 | if (host->remain == 0) { | 316 | if (host->remain == 0) { |
317 | sdhci_kunmap_sg(host); | ||
318 | if (sdhci_next_sg(host) == 0) { | 317 | if (sdhci_next_sg(host) == 0) { |
319 | BUG_ON(blksize != 0); | 318 | BUG_ON(blksize != 0); |
320 | return; | 319 | return; |
321 | } | 320 | } |
322 | buffer = sdhci_kmap_sg(host); | 321 | buffer = sdhci_sg_to_buffer(host); |
323 | } | 322 | } |
324 | } | 323 | } |
325 | |||
326 | sdhci_kunmap_sg(host); | ||
327 | } | 324 | } |
328 | 325 | ||
329 | static void sdhci_transfer_pio(struct sdhci_host *host) | 326 | static void sdhci_transfer_pio(struct sdhci_host *host) |
@@ -372,7 +369,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) | |||
372 | 369 | ||
373 | /* Sanity checks */ | 370 | /* Sanity checks */ |
374 | BUG_ON(data->blksz * data->blocks > 524288); | 371 | BUG_ON(data->blksz * data->blocks > 524288); |
375 | BUG_ON(data->blksz > host->max_block); | 372 | BUG_ON(data->blksz > host->mmc->max_blk_size); |
376 | BUG_ON(data->blocks > 65535); | 373 | BUG_ON(data->blocks > 65535); |
377 | 374 | ||
378 | /* timeout in us */ | 375 | /* timeout in us */ |
@@ -674,10 +671,17 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
674 | if (host->power == power) | 671 | if (host->power == power) |
675 | return; | 672 | return; |
676 | 673 | ||
677 | writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); | 674 | if (power == (unsigned short)-1) { |
678 | 675 | writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); | |
679 | if (power == (unsigned short)-1) | ||
680 | goto out; | 676 | goto out; |
677 | } | ||
678 | |||
679 | /* | ||
680 | * Spec says that we should clear the power reg before setting | ||
681 | * a new value. Some controllers don't seem to like this though. | ||
682 | */ | ||
683 | if (!(host->chip->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) | ||
684 | writeb(0, host->ioaddr + SDHCI_POWER_CONTROL); | ||
681 | 685 | ||
682 | pwr = SDHCI_POWER_ON; | 686 | pwr = SDHCI_POWER_ON; |
683 | 687 | ||
@@ -1109,7 +1113,9 @@ static int sdhci_resume (struct pci_dev *pdev) | |||
1109 | 1113 | ||
1110 | pci_set_power_state(pdev, PCI_D0); | 1114 | pci_set_power_state(pdev, PCI_D0); |
1111 | pci_restore_state(pdev); | 1115 | pci_restore_state(pdev); |
1112 | pci_enable_device(pdev); | 1116 | ret = pci_enable_device(pdev); |
1117 | if (ret) | ||
1118 | return ret; | ||
1113 | 1119 | ||
1114 | for (i = 0;i < chip->num_slots;i++) { | 1120 | for (i = 0;i < chip->num_slots;i++) { |
1115 | if (!chip->hosts[i]) | 1121 | if (!chip->hosts[i]) |
@@ -1274,15 +1280,6 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1274 | if (caps & SDHCI_TIMEOUT_CLK_UNIT) | 1280 | if (caps & SDHCI_TIMEOUT_CLK_UNIT) |
1275 | host->timeout_clk *= 1000; | 1281 | host->timeout_clk *= 1000; |
1276 | 1282 | ||
1277 | host->max_block = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; | ||
1278 | if (host->max_block >= 3) { | ||
1279 | printk(KERN_ERR "%s: Invalid maximum block size.\n", | ||
1280 | host->slot_descr); | ||
1281 | ret = -ENODEV; | ||
1282 | goto unmap; | ||
1283 | } | ||
1284 | host->max_block = 512 << host->max_block; | ||
1285 | |||
1286 | /* | 1283 | /* |
1287 | * Set host parameters. | 1284 | * Set host parameters. |
1288 | */ | 1285 | */ |
@@ -1294,9 +1291,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1294 | mmc->ocr_avail = 0; | 1291 | mmc->ocr_avail = 0; |
1295 | if (caps & SDHCI_CAN_VDD_330) | 1292 | if (caps & SDHCI_CAN_VDD_330) |
1296 | mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; | 1293 | mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; |
1297 | else if (caps & SDHCI_CAN_VDD_300) | 1294 | if (caps & SDHCI_CAN_VDD_300) |
1298 | mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; | 1295 | mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; |
1299 | else if (caps & SDHCI_CAN_VDD_180) | 1296 | if (caps & SDHCI_CAN_VDD_180) |
1300 | mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; | 1297 | mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; |
1301 | 1298 | ||
1302 | if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) { | 1299 | if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) { |
@@ -1326,15 +1323,33 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
1326 | 1323 | ||
1327 | /* | 1324 | /* |
1328 | * Maximum number of sectors in one transfer. Limited by DMA boundary | 1325 | * Maximum number of sectors in one transfer. Limited by DMA boundary |
1329 | * size (512KiB), which means (512 KiB/512=) 1024 entries. | 1326 | * size (512KiB). |
1330 | */ | 1327 | */ |
1331 | mmc->max_sectors = 1024; | 1328 | mmc->max_req_size = 524288; |
1332 | 1329 | ||
1333 | /* | 1330 | /* |
1334 | * Maximum segment size. Could be one segment with the maximum number | 1331 | * Maximum segment size. Could be one segment with the maximum number |
1335 | * of sectors. | 1332 | * of bytes. |
1333 | */ | ||
1334 | mmc->max_seg_size = mmc->max_req_size; | ||
1335 | |||
1336 | /* | ||
1337 | * Maximum block size. This varies from controller to controller and | ||
1338 | * is specified in the capabilities register. | ||
1339 | */ | ||
1340 | mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; | ||
1341 | if (mmc->max_blk_size >= 3) { | ||
1342 | printk(KERN_ERR "%s: Invalid maximum block size.\n", | ||
1343 | host->slot_descr); | ||
1344 | ret = -ENODEV; | ||
1345 | goto unmap; | ||
1346 | } | ||
1347 | mmc->max_blk_size = 512 << mmc->max_blk_size; | ||
1348 | |||
1349 | /* | ||
1350 | * Maximum block count. | ||
1336 | */ | 1351 | */ |
1337 | mmc->max_seg_size = mmc->max_sectors * 512; | 1352 | mmc->max_blk_count = 65535; |
1338 | 1353 | ||
1339 | /* | 1354 | /* |
1340 | * Init tasklets. | 1355 | * Init tasklets. |