diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/mmc/host/cb710-mmc.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/mmc/host/cb710-mmc.c')
-rw-r--r-- | drivers/mmc/host/cb710-mmc.c | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index ca3bdc831900..ce2a47b71dd6 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c | |||
@@ -25,7 +25,7 @@ static const u8 cb710_src_freq_mhz[16] = { | |||
25 | 50, 55, 60, 65, 70, 75, 80, 85 | 25 | 50, 55, 60, 65, 70, 75, 80, 85 |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static void cb710_mmc_set_clock(struct mmc_host *mmc, int hz) | 28 | static void cb710_mmc_select_clock_divider(struct mmc_host *mmc, int hz) |
29 | { | 29 | { |
30 | struct cb710_slot *slot = cb710_mmc_to_slot(mmc); | 30 | struct cb710_slot *slot = cb710_mmc_to_slot(mmc); |
31 | struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev; | 31 | struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev; |
@@ -33,8 +33,11 @@ static void cb710_mmc_set_clock(struct mmc_host *mmc, int hz) | |||
33 | u32 divider_idx; | 33 | u32 divider_idx; |
34 | int src_hz; | 34 | int src_hz; |
35 | 35 | ||
36 | /* this is magic, unverifiable for me, unless I get | 36 | /* on CB710 in HP nx9500: |
37 | * MMC card with cables connected to bus signals */ | 37 | * src_freq_idx == 0 |
38 | * indexes 1-7 work as written in the table | ||
39 | * indexes 0,8-15 give no clock output | ||
40 | */ | ||
38 | pci_read_config_dword(pdev, 0x48, &src_freq_idx); | 41 | pci_read_config_dword(pdev, 0x48, &src_freq_idx); |
39 | src_freq_idx = (src_freq_idx >> 16) & 0xF; | 42 | src_freq_idx = (src_freq_idx >> 16) & 0xF; |
40 | src_hz = cb710_src_freq_mhz[src_freq_idx] * 1000000; | 43 | src_hz = cb710_src_freq_mhz[src_freq_idx] * 1000000; |
@@ -46,13 +49,15 @@ static void cb710_mmc_set_clock(struct mmc_host *mmc, int hz) | |||
46 | 49 | ||
47 | if (src_freq_idx) | 50 | if (src_freq_idx) |
48 | divider_idx |= 0x8; | 51 | divider_idx |= 0x8; |
52 | else if (divider_idx == 0) | ||
53 | divider_idx = 1; | ||
49 | 54 | ||
50 | cb710_pci_update_config_reg(pdev, 0x40, ~0xF0000000, divider_idx << 28); | 55 | cb710_pci_update_config_reg(pdev, 0x40, ~0xF0000000, divider_idx << 28); |
51 | 56 | ||
52 | dev_dbg(cb710_slot_dev(slot), | 57 | dev_dbg(cb710_slot_dev(slot), |
53 | "clock set to %d Hz, wanted %d Hz; flag = %d\n", | 58 | "clock set to %d Hz, wanted %d Hz; src_freq_idx = %d, divider_idx = %d|%d\n", |
54 | src_hz >> cb710_clock_divider_log2[divider_idx & 7], | 59 | src_hz >> cb710_clock_divider_log2[divider_idx & 7], |
55 | hz, (divider_idx & 8) != 0); | 60 | hz, src_freq_idx, divider_idx & 7, divider_idx & 8); |
56 | } | 61 | } |
57 | 62 | ||
58 | static void __cb710_mmc_enable_irq(struct cb710_slot *slot, | 63 | static void __cb710_mmc_enable_irq(struct cb710_slot *slot, |
@@ -95,16 +100,8 @@ static void cb710_mmc_reset_events(struct cb710_slot *slot) | |||
95 | cb710_write_port_8(slot, CB710_MMC_STATUS2_PORT, 0xFF); | 100 | cb710_write_port_8(slot, CB710_MMC_STATUS2_PORT, 0xFF); |
96 | } | 101 | } |
97 | 102 | ||
98 | static int cb710_mmc_is_card_inserted(struct cb710_slot *slot) | ||
99 | { | ||
100 | return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT) | ||
101 | & CB710_MMC_S3_CARD_DETECTED; | ||
102 | } | ||
103 | |||
104 | static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable) | 103 | static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable) |
105 | { | 104 | { |
106 | dev_dbg(cb710_slot_dev(slot), "configuring %d-data-line%s mode\n", | ||
107 | enable ? 4 : 1, enable ? "s" : ""); | ||
108 | if (enable) | 105 | if (enable) |
109 | cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, | 106 | cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, |
110 | CB710_MMC_C1_4BIT_DATA_BUS, 0); | 107 | CB710_MMC_C1_4BIT_DATA_BUS, 0); |
@@ -208,7 +205,7 @@ static int cb710_wait_while_busy(struct cb710_slot *slot, uint8_t mask) | |||
208 | "WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n", | 205 | "WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n", |
209 | limit, mask, e, x); | 206 | limit, mask, e, x); |
210 | #endif | 207 | #endif |
211 | return 0; | 208 | return err; |
212 | } | 209 | } |
213 | 210 | ||
214 | static void cb710_mmc_set_transfer_size(struct cb710_slot *slot, | 211 | static void cb710_mmc_set_transfer_size(struct cb710_slot *slot, |
@@ -494,13 +491,8 @@ static void cb710_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
494 | reader->mrq = mrq; | 491 | reader->mrq = mrq; |
495 | cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0); | 492 | cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0); |
496 | 493 | ||
497 | if (cb710_mmc_is_card_inserted(slot)) { | 494 | if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop) |
498 | if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop) | 495 | cb710_mmc_command(mmc, mrq->stop); |
499 | cb710_mmc_command(mmc, mrq->stop); | ||
500 | mdelay(1); | ||
501 | } else { | ||
502 | mrq->cmd->error = -ENOMEDIUM; | ||
503 | } | ||
504 | 496 | ||
505 | tasklet_schedule(&reader->finish_req_tasklet); | 497 | tasklet_schedule(&reader->finish_req_tasklet); |
506 | } | 498 | } |
@@ -512,7 +504,7 @@ static int cb710_mmc_powerup(struct cb710_slot *slot) | |||
512 | #endif | 504 | #endif |
513 | int err; | 505 | int err; |
514 | 506 | ||
515 | /* a lot of magic; see comment in cb710_mmc_set_clock() */ | 507 | /* a lot of magic for now */ |
516 | dev_dbg(cb710_slot_dev(slot), "bus powerup\n"); | 508 | dev_dbg(cb710_slot_dev(slot), "bus powerup\n"); |
517 | cb710_dump_regs(chip, CB710_DUMP_REGS_MMC); | 509 | cb710_dump_regs(chip, CB710_DUMP_REGS_MMC); |
518 | err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20); | 510 | err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20); |
@@ -572,13 +564,7 @@ static void cb710_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
572 | struct cb710_mmc_reader *reader = mmc_priv(mmc); | 564 | struct cb710_mmc_reader *reader = mmc_priv(mmc); |
573 | int err; | 565 | int err; |
574 | 566 | ||
575 | cb710_mmc_set_clock(mmc, ios->clock); | 567 | cb710_mmc_select_clock_divider(mmc, ios->clock); |
576 | |||
577 | if (!cb710_mmc_is_card_inserted(slot)) { | ||
578 | dev_dbg(cb710_slot_dev(slot), | ||
579 | "no card inserted - ignoring bus powerup request\n"); | ||
580 | ios->power_mode = MMC_POWER_OFF; | ||
581 | } | ||
582 | 568 | ||
583 | if (ios->power_mode != reader->last_power_mode) | 569 | if (ios->power_mode != reader->last_power_mode) |
584 | switch (ios->power_mode) { | 570 | switch (ios->power_mode) { |
@@ -619,6 +605,14 @@ static int cb710_mmc_get_ro(struct mmc_host *mmc) | |||
619 | & CB710_MMC_S3_WRITE_PROTECTED; | 605 | & CB710_MMC_S3_WRITE_PROTECTED; |
620 | } | 606 | } |
621 | 607 | ||
608 | static int cb710_mmc_get_cd(struct mmc_host *mmc) | ||
609 | { | ||
610 | struct cb710_slot *slot = cb710_mmc_to_slot(mmc); | ||
611 | |||
612 | return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT) | ||
613 | & CB710_MMC_S3_CARD_DETECTED; | ||
614 | } | ||
615 | |||
622 | static int cb710_mmc_irq_handler(struct cb710_slot *slot) | 616 | static int cb710_mmc_irq_handler(struct cb710_slot *slot) |
623 | { | 617 | { |
624 | struct mmc_host *mmc = cb710_slot_to_mmc(slot); | 618 | struct mmc_host *mmc = cb710_slot_to_mmc(slot); |
@@ -664,7 +658,8 @@ static void cb710_mmc_finish_request_tasklet(unsigned long data) | |||
664 | static const struct mmc_host_ops cb710_mmc_host = { | 658 | static const struct mmc_host_ops cb710_mmc_host = { |
665 | .request = cb710_mmc_request, | 659 | .request = cb710_mmc_request, |
666 | .set_ios = cb710_mmc_set_ios, | 660 | .set_ios = cb710_mmc_set_ios, |
667 | .get_ro = cb710_mmc_get_ro | 661 | .get_ro = cb710_mmc_get_ro, |
662 | .get_cd = cb710_mmc_get_cd, | ||
668 | }; | 663 | }; |
669 | 664 | ||
670 | #ifdef CONFIG_PM | 665 | #ifdef CONFIG_PM |
@@ -746,6 +741,7 @@ static int __devinit cb710_mmc_init(struct platform_device *pdev) | |||
746 | err_free_mmc: | 741 | err_free_mmc: |
747 | dev_dbg(cb710_slot_dev(slot), "mmc_add_host() failed: %d\n", err); | 742 | dev_dbg(cb710_slot_dev(slot), "mmc_add_host() failed: %d\n", err); |
748 | 743 | ||
744 | cb710_set_irq_handler(slot, NULL); | ||
749 | mmc_free_host(mmc); | 745 | mmc_free_host(mmc); |
750 | return err; | 746 | return err; |
751 | } | 747 | } |