~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/mmc/host/cb710-mmc.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 */
10
10
#include <linux/kernel.h>
11
11
#include <linux/module.h>
12
 
#include <linux/slab.h>
13
12
#include <linux/pci.h>
14
13
#include <linux/delay.h>
15
14
#include "cb710-mmc.h"
26
25
        50, 55, 60, 65, 70, 75, 80, 85
27
26
};
28
27
 
29
 
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)
30
29
{
31
30
        struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
32
31
        struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev;
34
33
        u32 divider_idx;
35
34
        int src_hz;
36
35
 
37
 
        /* this is magic, unverifiable for me, unless I get
38
 
         * MMC card with cables connected to bus signals */
 
36
        /* on CB710 in HP nx9500:
 
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
         */
39
41
        pci_read_config_dword(pdev, 0x48, &src_freq_idx);
40
42
        src_freq_idx = (src_freq_idx >> 16) & 0xF;
41
43
        src_hz = cb710_src_freq_mhz[src_freq_idx] * 1000000;
47
49
 
48
50
        if (src_freq_idx)
49
51
                divider_idx |= 0x8;
 
52
        else if (divider_idx == 0)
 
53
                divider_idx = 1;
50
54
 
51
55
        cb710_pci_update_config_reg(pdev, 0x40, ~0xF0000000, divider_idx << 28);
52
56
 
53
57
        dev_dbg(cb710_slot_dev(slot),
54
 
                "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",
55
59
                src_hz >> cb710_clock_divider_log2[divider_idx & 7],
56
 
                hz, (divider_idx & 8) != 0);
 
60
                hz, src_freq_idx, divider_idx & 7, divider_idx & 8);
57
61
}
58
62
 
59
63
static void __cb710_mmc_enable_irq(struct cb710_slot *slot,
96
100
        cb710_write_port_8(slot, CB710_MMC_STATUS2_PORT, 0xFF);
97
101
}
98
102
 
99
 
static int cb710_mmc_is_card_inserted(struct cb710_slot *slot)
100
 
{
101
 
        return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
102
 
                & CB710_MMC_S3_CARD_DETECTED;
103
 
}
104
 
 
105
103
static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable)
106
104
{
107
 
        dev_dbg(cb710_slot_dev(slot), "configuring %d-data-line%s mode\n",
108
 
                enable ? 4 : 1, enable ? "s" : "");
109
105
        if (enable)
110
106
                cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
111
107
                        CB710_MMC_C1_4BIT_DATA_BUS, 0);
495
491
        reader->mrq = mrq;
496
492
        cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);
497
493
 
498
 
        if (cb710_mmc_is_card_inserted(slot)) {
499
 
                if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop)
500
 
                        cb710_mmc_command(mmc, mrq->stop);
501
 
                mdelay(1);
502
 
        } else {
503
 
                mrq->cmd->error = -ENOMEDIUM;
504
 
        }
 
494
        if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop)
 
495
                cb710_mmc_command(mmc, mrq->stop);
505
496
 
506
497
        tasklet_schedule(&reader->finish_req_tasklet);
507
498
}
513
504
#endif
514
505
        int err;
515
506
 
516
 
        /* a lot of magic; see comment in cb710_mmc_set_clock() */
 
507
        /* a lot of magic for now */
517
508
        dev_dbg(cb710_slot_dev(slot), "bus powerup\n");
518
509
        cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
519
510
        err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
573
564
        struct cb710_mmc_reader *reader = mmc_priv(mmc);
574
565
        int err;
575
566
 
576
 
        cb710_mmc_set_clock(mmc, ios->clock);
577
 
 
578
 
        if (!cb710_mmc_is_card_inserted(slot)) {
579
 
                dev_dbg(cb710_slot_dev(slot),
580
 
                        "no card inserted - ignoring bus powerup request\n");
581
 
                ios->power_mode = MMC_POWER_OFF;
582
 
        }
 
567
        cb710_mmc_select_clock_divider(mmc, ios->clock);
583
568
 
584
569
        if (ios->power_mode != reader->last_power_mode)
585
570
        switch (ios->power_mode) {
620
605
                & CB710_MMC_S3_WRITE_PROTECTED;
621
606
}
622
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
 
623
616
static int cb710_mmc_irq_handler(struct cb710_slot *slot)
624
617
{
625
618
        struct mmc_host *mmc = cb710_slot_to_mmc(slot);
665
658
static const struct mmc_host_ops cb710_mmc_host = {
666
659
        .request = cb710_mmc_request,
667
660
        .set_ios = cb710_mmc_set_ios,
668
 
        .get_ro = cb710_mmc_get_ro
 
661
        .get_ro = cb710_mmc_get_ro,
 
662
        .get_cd = cb710_mmc_get_cd,
669
663
};
670
664
 
671
665
#ifdef CONFIG_PM
676
670
        struct mmc_host *mmc = cb710_slot_to_mmc(slot);
677
671
        int err;
678
672
 
679
 
        err = mmc_suspend_host(mmc, state);
 
673
        err = mmc_suspend_host(mmc);
680
674
        if (err)
681
675
                return err;
682
676
 
747
741
err_free_mmc:
748
742
        dev_dbg(cb710_slot_dev(slot), "mmc_add_host() failed: %d\n", err);
749
743
 
 
744
        cb710_set_irq_handler(slot, NULL);
750
745
        mmc_free_host(mmc);
751
746
        return err;
752
747
}