aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/cb710-mmc.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/mmc/host/cb710-mmc.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (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.c56
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
28static void cb710_mmc_set_clock(struct mmc_host *mmc, int hz) 28static 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
58static void __cb710_mmc_enable_irq(struct cb710_slot *slot, 63static 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
98static 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
104static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable) 103static 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
214static void cb710_mmc_set_transfer_size(struct cb710_slot *slot, 211static 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
608static 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
622static int cb710_mmc_irq_handler(struct cb710_slot *slot) 616static 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)
664static const struct mmc_host_ops cb710_mmc_host = { 658static 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)
746err_free_mmc: 741err_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}