Commit 8c1c77ff authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (75 commits)
  mmc: core: eMMC bus width may not work on all platforms
  mmc: sdhci: Auto-CMD23 fixes.
  mmc: sdhci: Auto-CMD23 support.
  mmc: core: Block CMD23 support for UHS104/SDXC cards.
  mmc: sdhci: Implement MMC_CAP_CMD23 for SDHCI.
  mmc: core: Use CMD23 for multiblock transfers when we can.
  mmc: quirks: Add/remove quirks conditional support.
  mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver
  mmc: sdhci-pxa: Add quirks for DMA/ADMA to match h/w
  mmc: core: duplicated trial with same freq in mmc_rescan_try_freq()
  mmc: core: add support for eMMC Dual Data Rate
  mmc: core: eMMC signal voltage does not use CMD11
  mmc: sdhci-pxa: add platform code for UHS signaling
  mmc: sdhci: add hooks for setting UHS in platform specific code
  mmc: core: clear MMC_PM_KEEP_POWER flag on resume
  mmc: dw_mmc: fixed wrong regulator_enable in suspend/resume
  mmc: sdhi: allow powering down controller with no card inserted
  mmc: tmio: runtime suspend the controller, where possible
  mmc: sdhi: support up to 3 interrupt sources
  mmc: sdhi: print physical base address and clock rate
  ...
parents f3ae1c75 08ee80cc
......@@ -304,6 +304,7 @@ Code Seq#(hex) Include File Comments
0xB0 all RATIO devices in development:
<mailto:vgo@ratio.de>
0xB1 00-1F PPPoX <mailto:mostrows@styx.uwaterloo.ca>
0xB3 00 linux/mmc/ioctl.h
0xC0 00-0F linux/usb/iowarrior.h
0xCB 00-1F CBM serial IEC bus in development:
<mailto:michael.klein@puffin.lb.shuttle.de>
......
......@@ -2,3 +2,5 @@
- this file
mmc-dev-attrs.txt
- info on SD and MMC device attributes
mmc-dev-parts.txt
- info on SD and MMC device partitions
SD and MMC Block Device Attributes
==================================
These attributes are defined for the block devices associated with the
SD or MMC device.
The following attributes are read/write.
force_ro Enforce read-only access even if write protect switch is off.
SD and MMC Device Attributes
============================
......
SD and MMC Device Partitions
============================
Device partitions are additional logical block devices present on the
SD/MMC device.
As of this writing, MMC boot partitions as supported and exposed as
/dev/mmcblkXboot0 and /dev/mmcblkXboot1, where X is the index of the
parent /dev/mmcblkX.
MMC Boot Partitions
===================
Read and write access is provided to the two MMC boot partitions. Due to
the sensitive nature of the boot partition contents, which often store
a bootloader or bootloader configuration tables crucial to booting the
platform, write access is disabled by default to reduce the chance of
accidental bricking.
To enable write access to /dev/mmcblkXbootY, disable the forced read-only
access with:
echo 0 > /sys/block/mmcblkXbootY/force_ro
To re-enable read-only access:
echo 1 > /sys/block/mmcblkXbootY/force_ro
......@@ -6800,6 +6800,13 @@ L: lm-sensors@lm-sensors.org
S: Maintained
F: drivers/hwmon/vt8231.c
VUB300 USB to SDIO/SD/MMC bridge chip
M: Tony Olech <tony.olech@elandigitalsystems.com>
L: linux-mmc@vger.kernel.org
L: linux-usb@vger.kernel.org
S: Supported
F: drivers/mmc/host/vub300.c
W1 DALLAS'S 1-WIRE BUS
M: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
S: Maintained
......
......@@ -24,6 +24,7 @@ struct tegra_sdhci_platform_data {
int wp_gpio;
int power_gpio;
int is_8bit;
int pm_flags;
};
#endif
This diff is collapsed.
......@@ -212,7 +212,7 @@ static int mmc_test_busy(struct mmc_command *cmd)
static int mmc_test_wait_busy(struct mmc_test_card *test)
{
int ret, busy;
struct mmc_command cmd;
struct mmc_command cmd = {0};
busy = 0;
do {
......@@ -246,18 +246,13 @@ static int mmc_test_buffer_transfer(struct mmc_test_card *test,
{
int ret;
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_command stop = {0};
struct mmc_data data = {0};
struct scatterlist sg;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
memset(&stop, 0, sizeof(struct mmc_command));
mrq.cmd = &cmd;
mrq.data = &data;
mrq.stop = &stop;
......@@ -731,15 +726,10 @@ static int mmc_test_simple_transfer(struct mmc_test_card *test,
struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
unsigned blocks, unsigned blksz, int write)
{
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
memset(&stop, 0, sizeof(struct mmc_command));
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_command stop = {0};
struct mmc_data data = {0};
mrq.cmd = &cmd;
mrq.data = &data;
......@@ -761,18 +751,13 @@ static int mmc_test_simple_transfer(struct mmc_test_card *test,
static int mmc_test_broken_transfer(struct mmc_test_card *test,
unsigned blocks, unsigned blksz, int write)
{
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_command stop = {0};
struct mmc_data data = {0};
struct scatterlist sg;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
memset(&stop, 0, sizeof(struct mmc_command));
mrq.cmd = &cmd;
mrq.data = &data;
mrq.stop = &stop;
......@@ -1401,8 +1386,9 @@ static int mmc_test_area_io(struct mmc_test_card *test, unsigned long sz,
*/
static int mmc_test_area_fill(struct mmc_test_card *test)
{
return mmc_test_area_io(test, test->area.max_tfr, test->area.dev_addr,
1, 0, 0);
struct mmc_test_area *t = &test->area;
return mmc_test_area_io(test, t->max_tfr, t->dev_addr, 1, 0, 0);
}
/*
......@@ -1415,7 +1401,7 @@ static int mmc_test_area_erase(struct mmc_test_card *test)
if (!mmc_can_erase(test->card))
return 0;
return mmc_erase(test->card, t->dev_addr, test->area.max_sz >> 9,
return mmc_erase(test->card, t->dev_addr, t->max_sz >> 9,
MMC_ERASE_ARG);
}
......@@ -1542,8 +1528,10 @@ static int mmc_test_area_prepare_fill(struct mmc_test_card *test)
static int mmc_test_best_performance(struct mmc_test_card *test, int write,
int max_scatter)
{
return mmc_test_area_io(test, test->area.max_tfr, test->area.dev_addr,
write, max_scatter, 1);
struct mmc_test_area *t = &test->area;
return mmc_test_area_io(test, t->max_tfr, t->dev_addr, write,
max_scatter, 1);
}
/*
......@@ -1583,18 +1571,19 @@ static int mmc_test_best_write_perf_max_scatter(struct mmc_test_card *test)
*/
static int mmc_test_profile_read_perf(struct mmc_test_card *test)
{
struct mmc_test_area *t = &test->area;
unsigned long sz;
unsigned int dev_addr;
int ret;
for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
dev_addr = test->area.dev_addr + (sz >> 9);
for (sz = 512; sz < t->max_tfr; sz <<= 1) {
dev_addr = t->dev_addr + (sz >> 9);
ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
if (ret)
return ret;
}
sz = test->area.max_tfr;
dev_addr = test->area.dev_addr;
sz = t->max_tfr;
dev_addr = t->dev_addr;
return mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
}
......@@ -1603,6 +1592,7 @@ static int mmc_test_profile_read_perf(struct mmc_test_card *test)
*/
static int mmc_test_profile_write_perf(struct mmc_test_card *test)
{
struct mmc_test_area *t = &test->area;
unsigned long sz;
unsigned int dev_addr;
int ret;
......@@ -1610,8 +1600,8 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
ret = mmc_test_area_erase(test);
if (ret)
return ret;
for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
dev_addr = test->area.dev_addr + (sz >> 9);
for (sz = 512; sz < t->max_tfr; sz <<= 1) {
dev_addr = t->dev_addr + (sz >> 9);
ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
if (ret)
return ret;
......@@ -1619,8 +1609,8 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
ret = mmc_test_area_erase(test);
if (ret)
return ret;
sz = test->area.max_tfr;
dev_addr = test->area.dev_addr;
sz = t->max_tfr;
dev_addr = t->dev_addr;
return mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
}
......@@ -1629,6 +1619,7 @@ static int mmc_test_profile_write_perf(struct mmc_test_card *test)
*/
static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
{
struct mmc_test_area *t = &test->area;
unsigned long sz;
unsigned int dev_addr;
struct timespec ts1, ts2;
......@@ -1640,8 +1631,8 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
if (!mmc_can_erase(test->card))
return RESULT_UNSUP_HOST;
for (sz = 512; sz < test->area.max_sz; sz <<= 1) {
dev_addr = test->area.dev_addr + (sz >> 9);
for (sz = 512; sz < t->max_sz; sz <<= 1) {
dev_addr = t->dev_addr + (sz >> 9);
getnstimeofday(&ts1);
ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG);
if (ret)
......@@ -1649,7 +1640,7 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
getnstimeofday(&ts2);
mmc_test_print_rate(test, sz, &ts1, &ts2);
}
dev_addr = test->area.dev_addr;
dev_addr = t->dev_addr;
getnstimeofday(&ts1);
ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG);
if (ret)
......@@ -1661,12 +1652,13 @@ static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
static int mmc_test_seq_read_perf(struct mmc_test_card *test, unsigned long sz)
{
struct mmc_test_area *t = &test->area;
unsigned int dev_addr, i, cnt;
struct timespec ts1, ts2;
int ret;
cnt = test->area.max_sz / sz;
dev_addr = test->area.dev_addr;
cnt = t->max_sz / sz;
dev_addr = t->dev_addr;
getnstimeofday(&ts1);
for (i = 0; i < cnt; i++) {
ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 0);
......@@ -1684,20 +1676,22 @@ static int mmc_test_seq_read_perf(struct mmc_test_card *test, unsigned long sz)
*/
static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test)
{
struct mmc_test_area *t = &test->area;
unsigned long sz;
int ret;
for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
for (sz = 512; sz < t->max_tfr; sz <<= 1) {
ret = mmc_test_seq_read_perf(test, sz);
if (ret)
return ret;
}
sz = test->area.max_tfr;
sz = t->max_tfr;
return mmc_test_seq_read_perf(test, sz);
}
static int mmc_test_seq_write_perf(struct mmc_test_card *test, unsigned long sz)
{
struct mmc_test_area *t = &test->area;
unsigned int dev_addr, i, cnt;
struct timespec ts1, ts2;
int ret;
......@@ -1705,8 +1699,8 @@ static int mmc_test_seq_write_perf(struct mmc_test_card *test, unsigned long sz)
ret = mmc_test_area_erase(test);
if (ret)
return ret;
cnt = test->area.max_sz / sz;
dev_addr = test->area.dev_addr;
cnt = t->max_sz / sz;
dev_addr = t->dev_addr;
getnstimeofday(&ts1);
for (i = 0; i < cnt; i++) {
ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 0);
......@@ -1724,15 +1718,16 @@ static int mmc_test_seq_write_perf(struct mmc_test_card *test, unsigned long sz)
*/
static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test)
{
struct mmc_test_area *t = &test->area;
unsigned long sz;
int ret;
for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
for (sz = 512; sz < t->max_tfr; sz <<= 1) {
ret = mmc_test_seq_write_perf(test, sz);
if (ret)
return ret;
}
sz = test->area.max_tfr;
sz = t->max_tfr;
return mmc_test_seq_write_perf(test, sz);
}
......@@ -1741,6 +1736,7 @@ static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test)
*/
static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
{
struct mmc_test_area *t = &test->area;
unsigned long sz;
unsigned int dev_addr, i, cnt;
struct timespec ts1, ts2;
......@@ -1752,15 +1748,15 @@ static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
if (!mmc_can_erase(test->card))
return RESULT_UNSUP_HOST;
for (sz = 512; sz <= test->area.max_sz; sz <<= 1) {
for (sz = 512; sz <= t->max_sz; sz <<= 1) {
ret = mmc_test_area_erase(test);
if (ret)
return ret;
ret = mmc_test_area_fill(test);
if (ret)
return ret;
cnt = test->area.max_sz / sz;
dev_addr = test->area.dev_addr;
cnt = t->max_sz / sz;
dev_addr = t->dev_addr;
getnstimeofday(&ts1);
for (i = 0; i < cnt; i++) {
ret = mmc_erase(test->card, dev_addr, sz >> 9,
......@@ -1823,11 +1819,12 @@ static int mmc_test_rnd_perf(struct mmc_test_card *test, int write, int print,
static int mmc_test_random_perf(struct mmc_test_card *test, int write)
{
struct mmc_test_area *t = &test->area;
unsigned int next;
unsigned long sz;
int ret;
for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
for (sz = 512; sz < t->max_tfr; sz <<= 1) {
/*
* When writing, try to get more consistent results by running
* the test twice with exactly the same I/O but outputting the
......@@ -1844,7 +1841,7 @@ static int mmc_test_random_perf(struct mmc_test_card *test, int write)
if (ret)
return ret;
}
sz = test->area.max_tfr;
sz = t->max_tfr;
if (write) {
next = rnd_next;
ret = mmc_test_rnd_perf(test, write, 0, sz);
......@@ -1874,17 +1871,18 @@ static int mmc_test_random_write_perf(struct mmc_test_card *test)
static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
unsigned int tot_sz, int max_scatter)
{
struct mmc_test_area *t = &test->area;
unsigned int dev_addr, i, cnt, sz, ssz;
struct timespec ts1, ts2;
int ret;
sz = test->area.max_tfr;
sz = t->max_tfr;
/*
* In the case of a maximally scattered transfer, the maximum transfer
* size is further limited by using PAGE_SIZE segments.
*/
if (max_scatter) {
struct mmc_test_area *t = &test->area;
unsigned long max_tfr;
if (t->max_seg_sz >= PAGE_SIZE)
......
......@@ -343,18 +343,14 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
*/
void mmc_queue_bounce_pre(struct mmc_queue *mq)
{
unsigned long flags;
if (!mq->bounce_buf)
return;
if (rq_data_dir(mq->req) != WRITE)
return;
local_irq_save(flags);
sg_copy_to_buffer(mq->bounce_sg, mq->bounce_sg_len,
mq->bounce_buf, mq->sg[0].length);
local_irq_restore(flags);
}
/*
......@@ -363,17 +359,13 @@ void mmc_queue_bounce_pre(struct mmc_queue *mq)
*/
void mmc_queue_bounce_post(struct mmc_queue *mq)
{
unsigned long flags;
if (!mq->bounce_buf)
return;
if (rq_data_dir(mq->req) != READ)
return;
local_irq_save(flags);
sg_copy_from_buffer(mq->bounce_sg, mq->bounce_sg_len,
mq->bounce_buf, mq->sg[0].length);
local_irq_restore(flags);
}
......@@ -274,8 +274,12 @@ int mmc_add_card(struct mmc_card *card)
break;
case MMC_TYPE_SD:
type = "SD";
if (mmc_card_blockaddr(card))
type = "SDHC";
if (mmc_card_blockaddr(card)) {
if (mmc_card_ext_capacity(card))
type = "SDXC";
else
type = "SDHC";
}
break;
case MMC_TYPE_SDIO:
type = "SDIO";
......@@ -299,7 +303,8 @@ int mmc_add_card(struct mmc_card *card)
} else {
printk(KERN_INFO "%s: new %s%s%s card at address %04x\n",
mmc_hostname(card->host),
mmc_card_highspeed(card) ? "high speed " : "",
mmc_sd_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
type, card->rca);
}
......
......@@ -236,12 +236,10 @@ EXPORT_SYMBOL(mmc_wait_for_req);
*/
int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
{
struct mmc_request mrq;
struct mmc_request mrq = {0};
WARN_ON(!host->claimed);
memset(&mrq, 0, sizeof(struct mmc_request));
memset(cmd->resp, 0, sizeof(cmd->resp));
cmd->retries = retries;
......@@ -719,23 +717,13 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
mmc_set_ios(host);
}
/*
* Change data bus width and DDR mode of a host.
*/
void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
unsigned int ddr)
{
host->ios.bus_width = width;
host->ios.ddr = ddr;
mmc_set_ios(host);
}
/*
* Change data bus width of a host.
*/
void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
{
mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE);
host->ios.bus_width = width;
mmc_set_ios(host);
}
/**
......@@ -944,6 +932,38 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
return ocr;
}
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11)
{
struct mmc_command cmd = {0};
int err = 0;
BUG_ON(!host);
/*
* Send CMD11 only if the request is to switch the card to
* 1.8V signalling.
*/
if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) {
cmd.opcode = SD_SWITCH_VOLTAGE;
cmd.arg = 0;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
err = mmc_wait_for_cmd(host, &cmd, 0);
if (err)
return err;
if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
return -EIO;
}
host->ios.signal_voltage = signal_voltage;
if (host->ops->start_signal_voltage_switch)
err = host->ops->start_signal_voltage_switch(host, &host->ios);
return err;
}
/*
* Select timing parameters for host.
*/
......@@ -953,6 +973,15 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
mmc_set_ios(host);
}
/*
* Select appropriate driver type for host.
*/
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
{
host->ios.drv_type = drv_type;
mmc_set_ios(host);
}
/*
* Apply power to the MMC stack. This is a two-stage process.
* First, we enable power to the card without the clock running.
......@@ -1187,9 +1216,8 @@ void mmc_init_erase(struct mmc_card *card)
}
}
static void mmc_set_mmc_erase_timeout(struct mmc_card *card,
struct mmc_command *cmd,
unsigned int arg, unsigned int qty)
static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
unsigned int arg, unsigned int qty)
{
unsigned int erase_timeout;
......@@ -1246,44 +1274,48 @@ static void mmc_set_mmc_erase_timeout(struct mmc_card *card,
if (mmc_host_is_spi(card->host) && erase_timeout < 1000)
erase_timeout = 1000;
cmd->erase_timeout = erase_timeout;
return erase_timeout;
}
static void mmc_set_sd_erase_timeout(struct mmc_card *card,
struct mmc_command *cmd, unsigned int arg,
unsigned int qty)
static unsigned int mmc_sd_erase_timeout(struct mmc_card *card,
unsigned int arg,
unsigned int qty)
{
unsigned int erase_timeout;
if (card->ssr.erase_timeout) {
/* Erase timeout specified in SD Status Register (SSR) */
cmd->erase_timeout = card->ssr.erase_timeout * qty +
card->ssr.erase_offset;
erase_timeout = card->ssr.erase_timeout * qty +
card->ssr.erase_offset;
} else {
/*
* Erase timeout not specified in SD Status Register (SSR) so
* use 250ms per write block.
*/
cmd->erase_timeout = 250 * qty;
erase_timeout = 250 * qty;
}
/* Must not be less than 1 second */
if (cmd->erase_timeout < 1000)
cmd->erase_timeout = 1000;
if (erase_timeout < 1000)
erase_timeout = 1000;
return erase_timeout;
}
static void mmc_set_erase_timeout(struct mmc_card *card,
struct mmc_command *cmd, unsigned int arg,
unsigned int qty)
static unsigned int mmc_erase_timeout(struct mmc_card *card,
unsigned int arg,
unsigned int qty)
{
if (mmc_card_sd(card))
mmc_set_sd_erase_timeout(card, cmd, arg, qty);
return mmc_sd_erase_timeout(card, arg, qty);
else
mmc_set_mmc_erase_timeout(card, cmd, arg, qty);
return mmc_mmc_erase_timeout(card, arg, qty);
}
static int mmc_do_erase(struct mmc_card *card, unsigned int from,
unsigned int to, unsigned int arg)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
unsigned int qty = 0;
int err;
......@@ -1317,7 +1349,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
to <<= 9;
}
memset(&cmd, 0, sizeof(struct mmc_command));
if (mmc_card_sd(card))
cmd.opcode = SD_ERASE_WR_BLK_START;
else
......@@ -1351,7 +1382,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
cmd.opcode = MMC_ERASE;
cmd.arg = arg;
cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
mmc_set_erase_timeout(card, &cmd, arg, qty);
cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty);
err = mmc_wait_for_cmd(card->host, &cmd, 0);
if (err) {
printk(KERN_ERR "mmc_erase: erase error %d, status %#x\n",
......@@ -1487,12 +1518,11 @@ EXPORT_SYMBOL(mmc_erase_group_aligned);
int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card))
return 0;
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SET_BLOCKLEN;
cmd.arg = blocklen;
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
......@@ -1578,7 +1608,7 @@ void mmc_rescan(struct work_struct *work)
for (i = 0; i < ARRAY_SIZE(freqs); i++) {
if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
break;
if (freqs[i] < host->f_min)
if (freqs[i] <= host->f_min)
break;
}
mmc_release_host(host);
......@@ -1746,7 +1776,7 @@ int mmc_suspend_host(struct mmc_host *host)
}
mmc_bus_put(host);
if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
if (!err && !mmc_card_keep_power(host))
mmc_power_off(host);
return err;
......@@ -1764,7 +1794,7 @@ int mmc_resume_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
if (!mmc_card_keep_power(host)) {
mmc_power_up(host);
mmc_select_voltage(host, host->ocr);
/*
......@@ -1789,6 +1819,7 @@ int mmc_resume_host(struct mmc_host *host)
err = 0;
}
}
host->pm_flags &= ~MMC_PM_KEEP_POWER;
mmc_bus_put(host);
return err;
......
......@@ -38,10 +38,11 @@ void mmc_ungate_clock(struct mmc_host *host);
void mmc_set_ungated(struct mmc_host *host);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
unsigned int ddr);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
bool cmd11);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
static inline void mmc_delay(unsigned int ms)
{
......@@ -61,8 +62,6 @@ int mmc_attach_mmc(struct mmc_host *host);
int mmc_attach_sd(struct mmc_host *host);
int mmc_attach_sdio(struct mmc_host *host);
void mmc_fixup_device(struct mmc_card *card);
/* Module parameters */
extern int use_spi_crc;
......
......@@ -325,12 +325,12 @@ int mmc_add_host(struct mmc_host *host)
WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
!host->ops->enable_sdio_irq);
led_trigger_register_simple(dev_name(&host->class_dev), &host->led);
err = device_add(&host->class_dev);
if (err)
return err;
led_trigger_register_simple(dev_name(&host->class_dev), &host->led);
#ifdef CONFIG_DEBUG_FS
mmc_add_host_debugfs(host);
#endif
......
......@@ -20,6 +20,7 @@
#include "core.h"
#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
......@@ -173,14 +174,17 @@ static int mmc_decode_csd(struct mmc_card *card)
}
/*
* Read and decode extended CSD.
* Read extended CSD.
*/
static int mmc_read_ext_csd(struct mmc_card *card)
static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
{
int err;
u8 *ext_csd;
BUG_ON(!card);
BUG_ON(!new_ext_csd);
*new_ext_csd = NULL;
if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
return 0;
......@@ -198,12 +202,15 @@ static int mmc_read_ext_csd(struct mmc_card *card)
err = mmc_send_ext_csd(card, ext_csd);
if (err) {
kfree(ext_csd);
*new_ext_csd = NULL;
/* If the host or the card can't do the switch,
* fail more gracefully. */
if ((err != -EINVAL)
&& (err != -ENOSYS)
&& (err != -EFAULT))
goto out;
return err;
/*
* High capacity cards should have this "magic" size
......@@ -221,9 +228,23 @@ static int mmc_read_ext_csd(struct mmc_card *card)
mmc_hostname(card->host));
err = 0;
}
} else
*new_ext_csd = ext_csd;
goto out;
}
return err;
}
/*
* Decode extended CSD.
*/
static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
{
int err = 0;
BUG_ON(!card);
if (!ext_csd)
return 0;
/* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
if (card->csd.structure == 3) {
......@@ -288,6 +309,10 @@ static int mmc_read_ext_csd(struct mmc_card *card)
if (card->ext_csd.rev >= 3) {
u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG];
/* EXT_CSD value is in units of 10ms, but we store in ms */
card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
/* Sleep / awake timeout in 100ns units */
if (sa_shift > 0 && sa_shift <= 0x17)
......@@ -299,6 +324,14 @@ static int mmc_read_ext_csd(struct mmc_card *card)
ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
card->ext_csd.hc_erase_size =
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C];
/*
* There are two boot regions of equal size, defined in
* multiples of 128K.
*/
card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
}
if (card->ext_csd.rev >= 4) {
......@@ -350,14 +383,78 @@ static int mmc_read_ext_csd(struct mmc_card *card)
ext_csd[EXT_CSD_TRIM_MULT];
}
if (card->ext_csd.rev >= 5)
card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
card->erased_byte = 0xFF;
else
card->erased_byte = 0x0;
out:
return err;
}
static inline void mmc_free_ext_csd(u8 *ext_csd)
{
kfree(ext_csd);
}
static int mmc_compare_ext_csds(struct mmc_card *card, u8 *ext_csd,
unsigned bus_width)
{
u8 *bw_ext_csd;
int err;
err = mmc_get_ext_csd(card, &bw_ext_csd);
if (err)
return err;
if ((ext_csd == NULL || bw_ext_csd == NULL)) {
if (bus_width != MMC_BUS_WIDTH_1)
err = -EINVAL;
goto out;
}
if (bus_width == MMC_BUS_WIDTH_1)
goto out;
/* only compare read only fields */
err = (!(ext_csd[EXT_CSD_PARTITION_SUPPORT] ==
bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
(ext_csd[EXT_CSD_ERASED_MEM_CONT] ==
bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
(ext_csd[EXT_CSD_REV] ==
bw_ext_csd[EXT_CSD_REV]) &&
(ext_csd[EXT_CSD_STRUCTURE] ==
bw_ext_csd[EXT_CSD_STRUCTURE]) &&
(ext_csd[EXT_CSD_CARD_TYPE] ==
bw_ext_csd[EXT_CSD_CARD_TYPE]) &&
(ext_csd[EXT_CSD_S_A_TIMEOUT] ==
bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) &&
(ext_csd[EXT_CSD_HC_WP_GRP_SIZE] ==
bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
(ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] ==
bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) &&
(ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] ==
bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
(ext_csd[EXT_CSD_SEC_TRIM_MULT] ==
bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) &&
(ext_csd[EXT_CSD_SEC_ERASE_MULT] ==
bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) &&
(ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] ==
bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) &&
(ext_csd[EXT_CSD_TRIM_MULT] ==
bw_ext_csd[EXT_CSD_TRIM_MULT]) &&
memcmp(&ext_csd[EXT_CSD_SEC_CNT],
&bw_ext_csd[EXT_CSD_SEC_CNT],
4) != 0);
if (err)
err = -EINVAL;
out:
mmc_free_ext_csd(bw_ext_csd);
return err;
}
......@@ -422,6 +519,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
u32 cid[4];
unsigned int max_dtr;
u32 rocr;
u8 *ext_csd = NULL;
BUG_ON(!host);
WARN_ON(!host->claimed);
......@@ -520,7 +618,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
/*
* Fetch and process extended CSD.
*/
err = mmc_read_ext_csd(card);
err = mmc_get_ext_csd(card, &ext_csd);
if (err)
goto free_card;
err = mmc_read_ext_csd(card, ext_csd);
if (err)
goto free_card;
......@@ -542,7 +644,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*/
if (card->ext_csd.enhanced_area_en) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_ERASE_GROUP_DEF, 1);
EXT_CSD_ERASE_GROUP_DEF, 1, 0);
if (err && err != -EBADMSG)
goto free_card;
......@@ -567,13 +669,25 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
}
}
/*
* Ensure eMMC user default partition is enabled
*/
if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) {
card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG,
card->ext_csd.part_config,
card->ext_csd.part_time);
if (err && err != -EBADMSG)
goto free_card;
}
/*
* Activate high speed (if supported)
*/
if ((card->ext_csd.hs_max_dtr != 0) &&
(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, 1);
EXT_CSD_HS_TIMING, 1, 0);
if (err && err != -EBADMSG)
goto free_card;
......@@ -606,10 +720,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*/
if (mmc_card_highspeed(card)) {
if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
&& (host->caps & (MMC_CAP_1_8V_DDR)))
&& ((host->caps & (MMC_CAP_1_8V_DDR |
MMC_CAP_UHS_DDR50))
== (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
ddr = MMC_1_8V_DDR_MODE;
else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
&& (host->caps & (MMC_CAP_1_2V_DDR)))
&& ((host->caps & (MMC_CAP_1_2V_DDR |
MMC_CAP_UHS_DDR50))
== (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
ddr = MMC_1_2V_DDR_MODE;
}
......@@ -640,18 +758,22 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
ddr = 0; /* no DDR for 1-bit width */
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
ext_csd_bits[idx][0]);
ext_csd_bits[idx][0],
0);
if (!err) {
mmc_set_bus_width_ddr(card->host,
bus_width, MMC_SDR_MODE);
mmc_set_bus_width(card->host, bus_width);
/*
* If controller can't handle bus width test,
* use the highest bus width to maintain
* compatibility with previous MMC behavior.
* compare ext_csd previously read in 1 bit mode
* against ext_csd at new bus width
*/
if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
break;
err = mmc_bus_test(card, bus_width);
err = mmc_compare_ext_csds(card,
ext_csd,
bus_width);
else
err = mmc_bus_test(card, bus_width);
if (!err)
break;
}
......@@ -659,8 +781,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if (!err && ddr) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
ext_csd_bits[idx][1]);
EXT_CSD_BUS_WIDTH,
ext_csd_bits[idx][1],
0);
}
if (err) {
printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
......@@ -668,20 +791,43 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
1 << bus_width, ddr);
goto free_card;
} else if (ddr) {
/*
* eMMC cards can support 3.3V to 1.2V i/o (vccq)
* signaling.
*
* EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
*
* 1.8V vccq at 3.3V core voltage (vcc) is not required
* in the JEDEC spec for DDR.
*
* Do not force change in vccq since we are obviously
* working and no change to vccq is needed.
*
* WARNING: eMMC rules are NOT the same as SD DDR
*/
if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
err = mmc_set_signal_voltage(host,
MMC_SIGNAL_VOLTAGE_120, 0);
if (err)
goto err;
}
mmc_card_set_ddr_mode(card);
mmc_set_bus_width_ddr(card->host, bus_width, ddr);
mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50);
mmc_set_bus_width(card->host, bus_width);
}
}
if (!oldcard)
host->card = card;
mmc_free_ext_csd(ext_csd);
return 0;
free_card:
if (!oldcard)
mmc_remove_card(card);
err:
mmc_free_ext_csd(ext_csd);
return err;
}
......
......@@ -23,12 +23,10 @@
static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SELECT_CARD;
if (card) {
......@@ -60,15 +58,13 @@ int mmc_deselect_cards(struct mmc_host *host)
int mmc_card_sleepawake(struct mmc_host *host, int sleep)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
struct mmc_card *card = host->card;
int err;
if (sleep)
mmc_deselect_cards(host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SLEEP_AWAKE;
cmd.arg = card->rca << 16;
if (sleep)
......@@ -97,7 +93,7 @@ int mmc_card_sleepawake(struct mmc_host *host, int sleep)
int mmc_go_idle(struct mmc_host *host)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
/*
* Non-SPI hosts need to prevent chipselect going active during
......@@ -113,8 +109,6 @@ int mmc_go_idle(struct mmc_host *host)
mmc_delay(1);
}
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_GO_IDLE_STATE;
cmd.arg = 0;
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
......@@ -135,13 +129,11 @@ int mmc_go_idle(struct mmc_host *host)
int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
int i, err = 0;
BUG_ON(!host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SEND_OP_COND;
cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
......@@ -178,13 +170,11 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!host);
BUG_ON(!cid);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_ALL_SEND_CID;
cmd.arg = 0;
cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
......@@ -201,13 +191,11 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
int mmc_set_relative_addr(struct mmc_card *card)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!card);
BUG_ON(!card->host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SET_RELATIVE_ADDR;
cmd.arg = card->rca << 16;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
......@@ -223,13 +211,11 @@ static int
mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!host);
BUG_ON(!cxd);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = opcode;
cmd.arg = arg;
cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
......@@ -247,9 +233,9 @@ static int
mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
u32 opcode, void *buf, unsigned len)
{
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
void *data_buf;
......@@ -260,10 +246,6 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
if (data_buf == NULL)
return -ENOMEM;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
mrq.cmd = &cmd;
mrq.data = &data;
......@@ -355,11 +337,9 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
int err;
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SPI_READ_OCR;
cmd.arg = highcap ? (1 << 30) : 0;
cmd.flags = MMC_RSP_SPI_R3;
......@@ -372,11 +352,9 @@ int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
int err;
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SPI_CRC_ON_OFF;
cmd.flags = MMC_RSP_SPI_R1;
cmd.arg = use_crc;
......@@ -387,23 +365,34 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
return err;
}
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
/**
* mmc_switch - modify EXT_CSD register
* @card: the MMC card associated with the data transfer
* @set: cmd set values
* @index: EXT_CSD register index
* @value: value to program into EXT_CSD register
* @timeout_ms: timeout (ms) for operation performed by register write,
* timeout of zero implies maximum possible timeout
*
* Modifies the EXT_CSD register for selected card.
*/
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
u32 status;
BUG_ON(!card);
BUG_ON(!card->host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SWITCH;
cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(index << 16) |
(value << 8) |
set;
cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
cmd.cmd_timeout_ms = timeout_ms;
err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
if (err)
......@@ -433,17 +422,16 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
return 0;
}
EXPORT_SYMBOL_GPL(mmc_switch);
int mmc_send_status(struct mmc_card *card, u32 *status)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!card);
BUG_ON(!card->host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = MMC_SEND_STATUS;
if (!mmc_host_is_spi(card->host))
cmd.arg = card->rca << 16;
......@@ -466,9 +454,9 @@ static int
mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
u8 len)
{
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
u8 *data_buf;
u8 *test_buf;
......@@ -497,10 +485,6 @@ mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
if (opcode == MMC_BUS_TEST_W)
memcpy(data_buf, test_buf, len);
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
mrq.cmd = &cmd;
mrq.data = &data;
cmd.opcode = opcode;
......
......@@ -20,7 +20,6 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid);
int mmc_set_relative_addr(struct mmc_card *card);
int mmc_send_csd(struct mmc_card *card, u32 *csd);
int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value);
int mmc_send_status(struct mmc_card *card, u32 *status);
int mmc_send_cid(struct mmc_host *host, u32 *cid);
int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
......
/*
* This file contains work-arounds for many known sdio hardware
* bugs.
* This file contains work-arounds for many known SD/MMC
* and SDIO hardware bugs.
*
* Copyright (c) 2011 Andrei Warkentin <andreiw@motorola.com>
* Copyright (c) 2011 Pierre Tardy <tardyp@gmail.com>
* Inspired from pci fixup code:
* Copyright (c) 1999 Martin Mares <mj@ucw.cz>
......@@ -11,34 +12,14 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mmc/card.h>
#include <linux/mod_devicetable.h>
/*
* The world is not perfect and supplies us with broken mmc/sdio devices.
* For at least a part of these bugs we need a work-around
*/
struct mmc_fixup {
u16 vendor, device; /* You can use SDIO_ANY_ID here of course */
void (*vendor_fixup)(struct mmc_card *card, int data);
int data;
};
/*
* This hook just adds a quirk unconditionnally
*/
static void __maybe_unused add_quirk(struct mmc_card *card, int data)
{
card->quirks |= data;
}
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
#endif
/*
* This hook just removes a quirk unconditionnally
*/
static void __maybe_unused remove_quirk(struct mmc_card *card, int data)
{
card->quirks &= ~data;
}
#ifndef SDIO_DEVICE_ID_TI_WL1271
#define SDIO_DEVICE_ID_TI_WL1271 0x4076
#endif
/*
* This hook just adds a quirk for all sdio devices
......@@ -49,33 +30,47 @@ static void add_quirk_for_sdio_devices(struct mmc_card *card, int data)
card->quirks |= data;
}
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
#endif
#ifndef SDIO_DEVICE_ID_TI_WL1271
#define SDIO_DEVICE_ID_TI_WL1271 0x4076
#endif
static const struct mmc_fixup mmc_fixup_methods[] = {
/* by default sdio devices are considered CLK_GATING broken */
/* good cards will be whitelisted as they are tested */
{ SDIO_ANY_ID, SDIO_ANY_ID,
add_quirk_for_sdio_devices, MMC_QUIRK_BROKEN_CLK_GATING },
{ SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING },
{ 0 }
SDIO_FIXUP(SDIO_ANY_ID, SDIO_ANY_ID,
add_quirk_for_sdio_devices,
MMC_QUIRK_BROKEN_CLK_GATING),
SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING),
SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
add_quirk, MMC_QUIRK_NONSTD_FUNC_IF),
SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
add_quirk, MMC_QUIRK_DISABLE_CD),
END_FIXUP
};
void mmc_fixup_device(struct mmc_card *card)
void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table)
{
const struct mmc_fixup *f;
u64 rev = cid_rev_card(card);
/* Non-core specific workarounds. */
if (!table)
table = mmc_fixup_methods;
for (f = mmc_fixup_methods; f->vendor_fixup; f++) {
if ((f->vendor == card->cis.vendor
|| f->vendor == (u16) SDIO_ANY_ID) &&
(f->device == card->cis.device
|| f->device == (u16) SDIO_ANY_ID)) {
for (f = table; f->vendor_fixup; f++) {
if ((f->manfid == CID_MANFID_ANY ||
f->manfid == card->cid.manfid) &&
(f->oemid == CID_OEMID_ANY ||
f->oemid == card->cid.oemid) &&
(f->name == CID_NAME_ANY ||
!strncmp(f->name, card->cid.prod_name,
sizeof(card->cid.prod_name))) &&
(f->cis_vendor == card->cis.vendor ||
f->cis_vendor == (u16) SDIO_ANY_ID) &&
(f->cis_device == card->cis.device ||
f->cis_device == (u16) SDIO_ANY_ID) &&
rev >= f->rev_start && rev <= f->rev_end) {
dev_dbg(&card->dev, "calling %pF\n", f->vendor_fixup);
f->vendor_fixup(card, f->data);
}
......
......@@ -130,7 +130,7 @@ static int mmc_decode_csd(struct mmc_card *card)
break;
case 1:
/*
* This is a block-addressed SDHC card. Most
* This is a block-addressed SDHC or SDXC card. Most
* interesting fields are unused and have fixed
* values. To avoid getting tripped by buggy cards,
* we assume those fixed values ourselves.
......@@ -144,6 +144,11 @@ static int mmc_decode_csd(struct mmc_card *card)
e = UNSTUFF_BITS(resp, 96, 3);
csd->max_dtr = tran_exp[e] * tran_mant[m];
csd->cmdclass = UNSTUFF_BITS(resp, 84, 12);
csd->c_size = UNSTUFF_BITS(resp, 48, 22);
/* SDXC cards have a minimum C_SIZE of 0x00FFFF */
if (csd->c_size >= 0xFFFF)
mmc_card_set_ext_capacity(card);
m = UNSTUFF_BITS(resp, 48, 22);
csd->capacity = (1 + m) << 10;
......@@ -189,12 +194,17 @@ static int mmc_decode_scr(struct mmc_card *card)
scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
if (scr->sda_vsn == SCR_SPEC_VER_2)
/* Check if Physical Layer Spec v3.0 is supported */
scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
if (UNSTUFF_BITS(resp, 55, 1))
card->erased_byte = 0xFF;
else
card->erased_byte = 0x0;
if (scr->sda_spec3)
scr->cmds = UNSTUFF_BITS(resp, 32, 2);
return 0;
}
......@@ -274,29 +284,74 @@ static int mmc_read_switch(struct mmc_card *card)
status = kmalloc(64, GFP_KERNEL);
if (!status) {
printk(KERN_ERR "%s: could not allocate a buffer for "
"switch capabilities.\n", mmc_hostname(card->host));
"switch capabilities.\n",
mmc_hostname(card->host));
return -ENOMEM;
}
/* Find out the supported Bus Speed Modes. */
err = mmc_sd_switch(card, 0, 0, 1, status);
if (err) {
/* If the host or the card can't do the switch,
* fail more gracefully. */
if ((err != -EINVAL)
&& (err != -ENOSYS)
&& (err != -EFAULT))
/*
* If the host or the card can't do the switch,
* fail more gracefully.
*/
if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
goto out;
printk(KERN_WARNING "%s: problem reading switch "
"capabilities, performance might suffer.\n",
printk(KERN_WARNING "%s: problem reading Bus Speed modes.\n",
mmc_hostname(card->host));
err = 0;
goto out;
}
if (status[13] & 0x02)
card->sw_caps.hs_max_dtr = 50000000;
if (card->scr.sda_spec3) {
card->sw_caps.sd3_bus_mode = status[13];
/* Find out Driver Strengths supported by the card */
err = mmc_sd_switch(card, 0, 2, 1, status);
if (err) {
/*
* If the host or the card can't do the switch,
* fail more gracefully.
*/
if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
goto out;
printk(KERN_WARNING "%s: problem reading "
"Driver Strength.\n",
mmc_hostname(card->host));
err = 0;
goto out;
}
card->sw_caps.sd3_drv_type = status[9];
/* Find out Current Limits supported by the card */
err = mmc_sd_switch(card, 0, 3, 1, status);
if (err) {
/*
* If the host or the card can't do the switch,
* fail more gracefully.
*/
if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
goto out;
printk(KERN_WARNING "%s: problem reading "
"Current Limit.\n",
mmc_hostname(card->host));
err = 0;
goto out;
}
card->sw_caps.sd3_curr_limit = status[7];
} else {
if (status[13] & 0x02)
card->sw_caps.hs_max_dtr = 50000000;
}
out:
kfree(status);
......@@ -352,6 +407,232 @@ int mmc_sd_switch_hs(struct mmc_card *card)
return err;
}
static int sd_select_driver_type(struct mmc_card *card, u8 *status)
{
int host_drv_type = 0, card_drv_type = 0;
int err;
/*
* If the host doesn't support any of the Driver Types A,C or D,
* default Driver Type B is used.
*/
if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
| MMC_CAP_DRIVER_TYPE_D)))
return 0;
if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) {
host_drv_type = MMC_SET_DRIVER_TYPE_A;
if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A)
card_drv_type = MMC_SET_DRIVER_TYPE_A;
else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
card_drv_type = MMC_SET_DRIVER_TYPE_B;
else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
card_drv_type = MMC_SET_DRIVER_TYPE_C;
} else if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) {
host_drv_type = MMC_SET_DRIVER_TYPE_C;
if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
card_drv_type = MMC_SET_DRIVER_TYPE_C;
} else if (!(card->host->caps & MMC_CAP_DRIVER_TYPE_D)) {
/*
* If we are here, that means only the default driver type
* B is supported by the host.
*/
host_drv_type = MMC_SET_DRIVER_TYPE_B;
if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
card_drv_type = MMC_SET_DRIVER_TYPE_B;
else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
card_drv_type = MMC_SET_DRIVER_TYPE_C;
}
err = mmc_sd_switch(card, 1, 2, card_drv_type, status);
if (err)
return err;
if ((status[15] & 0xF) != card_drv_type) {
printk(KERN_WARNING "%s: Problem setting driver strength!\n",
mmc_hostname(card->host));
return 0;
}
mmc_set_driver_type(card->host, host_drv_type);
return 0;
}
static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
{
unsigned int bus_speed = 0, timing = 0;
int err;
/*
* If the host doesn't support any of the UHS-I modes, fallback on
* default speed.
*/
if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
return 0;
if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
bus_speed = UHS_SDR104_BUS_SPEED;
timing = MMC_TIMING_UHS_SDR104;
card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
bus_speed = UHS_DDR50_BUS_SPEED;
timing = MMC_TIMING_UHS_DDR50;
card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR50)) {
bus_speed = UHS_SDR50_BUS_SPEED;
timing = MMC_TIMING_UHS_SDR50;
card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
bus_speed = UHS_SDR25_BUS_SPEED;
timing = MMC_TIMING_UHS_SDR25;
card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR12)) {
bus_speed = UHS_SDR12_BUS_SPEED;
timing = MMC_TIMING_UHS_SDR12;
card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
}
card->sd_bus_speed = bus_speed;
err = mmc_sd_switch(card, 1, 0, bus_speed, status);
if (err)
return err;
if ((status[16] & 0xF) != bus_speed)
printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
mmc_hostname(card->host));
else {
mmc_set_timing(card->host, timing);
mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
}
return 0;
}
static int sd_set_current_limit(struct mmc_card *card, u8 *status)
{
int current_limit = 0;
int err;
/*
* Current limit switch is only defined for SDR50, SDR104, and DDR50
* bus speed modes. For other bus speed modes, we set the default
* current limit of 200mA.
*/
if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) ||
(card->sd_bus_speed == UHS_SDR104_BUS_SPEED) ||
(card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) {
if (card->host->caps & MMC_CAP_MAX_CURRENT_800) {
if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
current_limit = SD_SET_CURRENT_LIMIT_800;
else if (card->sw_caps.sd3_curr_limit &
SD_MAX_CURRENT_600)
current_limit = SD_SET_CURRENT_LIMIT_600;
else if (card->sw_caps.sd3_curr_limit &
SD_MAX_CURRENT_400)
current_limit = SD_SET_CURRENT_LIMIT_400;
else if (card->sw_caps.sd3_curr_limit &
SD_MAX_CURRENT_200)
current_limit = SD_SET_CURRENT_LIMIT_200;
} else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) {
if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
current_limit = SD_SET_CURRENT_LIMIT_600;
else if (card->sw_caps.sd3_curr_limit &
SD_MAX_CURRENT_400)
current_limit = SD_SET_CURRENT_LIMIT_400;
else if (card->sw_caps.sd3_curr_limit &
SD_MAX_CURRENT_200)
current_limit = SD_SET_CURRENT_LIMIT_200;
} else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) {
if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
current_limit = SD_SET_CURRENT_LIMIT_400;
else if (card->sw_caps.sd3_curr_limit &
SD_MAX_CURRENT_200)
current_limit = SD_SET_CURRENT_LIMIT_200;
} else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) {
if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
current_limit = SD_SET_CURRENT_LIMIT_200;
}
} else
current_limit = SD_SET_CURRENT_LIMIT_200;
err = mmc_sd_switch(card, 1, 3, current_limit, status);
if (err)
return err;
if (((status[15] >> 4) & 0x0F) != current_limit)
printk(KERN_WARNING "%s: Problem setting current limit!\n",
mmc_hostname(card->host));
return 0;
}
/*
* UHS-I specific initialization procedure
*/
static int mmc_sd_init_uhs_card(struct mmc_card *card)
{
int err;
u8 *status;
if (!card->scr.sda_spec3)
return 0;
if (!(card->csd.cmdclass & CCC_SWITCH))
return 0;
status = kmalloc(64, GFP_KERNEL);
if (!status) {
printk(KERN_ERR "%s: could not allocate a buffer for "
"switch capabilities.\n", mmc_hostname(card->host));
return -ENOMEM;
}
/* Set 4-bit bus width */
if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err)
goto out;
mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
}
/* Set the driver strength for the card */
err = sd_select_driver_type(card, status);
if (err)
goto out;
/* Set bus speed mode of the card */
err = sd_set_bus_speed_mode(card, status);
if (err)
goto out;
/* Set current limit for the card */
err = sd_set_current_limit(card, status);
if (err)
goto out;
/* SPI mode doesn't define CMD19 */
if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
err = card->host->ops->execute_tuning(card->host);
out:
kfree(status);
return err;
}
MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
card->raw_cid[2], card->raw_cid[3]);
MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
......@@ -400,7 +681,7 @@ struct device_type sd_type = {
/*
* Fetch CID from card.
*/
int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
{
int err;
......@@ -420,12 +701,39 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
*/
err = mmc_send_if_cond(host, ocr);
if (!err)
ocr |= 1 << 30;
ocr |= SD_OCR_CCS;
/*
* If the host supports one of UHS-I modes, request the card
* to switch to 1.8V signaling level.
*/
if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
ocr |= SD_OCR_S18R;
/* If the host can supply more than 150mA, XPC should be set to 1. */
if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
MMC_CAP_SET_XPC_180))
ocr |= SD_OCR_XPC;
err = mmc_send_app_op_cond(host, ocr, NULL);
try_again:
err = mmc_send_app_op_cond(host, ocr, rocr);
if (err)
return err;
/*
* In case CCS and S18A in the response is set, start Signal Voltage
* Switch procedure. SPI mode doesn't support CMD11.
*/
if (!mmc_host_is_spi(host) && rocr &&
((*rocr & 0x41000000) == 0x41000000)) {
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
if (err) {
ocr &= ~SD_OCR_S18R;
goto try_again;
}
}
if (mmc_host_is_spi(host))
err = mmc_send_cid(host, cid);
else
......@@ -553,11 +861,12 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
struct mmc_card *card;
int err;
u32 cid[4];
u32 rocr = 0;
BUG_ON(!host);
WARN_ON(!host->claimed);
err = mmc_sd_get_cid(host, ocr, cid);
err = mmc_sd_get_cid(host, ocr, cid, &rocr);
if (err)
return err;
......@@ -610,30 +919,47 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
if (err)
goto free_card;
/*
* Attempt to change to high-speed (if supported)
*/
err = mmc_sd_switch_hs(card);
if (err > 0)
mmc_sd_go_highspeed(card);
else if (err)
goto free_card;
/* Initialization sequence for UHS-I cards */
if (rocr & SD_ROCR_S18A) {
err = mmc_sd_init_uhs_card(card);
if (err)
goto free_card;
/*
* Set bus speed.
*/
mmc_set_clock(host, mmc_sd_get_max_clock(card));
/* Card is an ultra-high-speed card */
mmc_sd_card_set_uhs(card);
/*
* Switch to wider bus (if supported).
*/
if ((host->caps & MMC_CAP_4_BIT_DATA) &&
(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err)
/*
* Since initialization is now complete, enable preset
* value registers for UHS-I cards.
*/
if (host->ops->enable_preset_value)
host->ops->enable_preset_value(host, true);
} else {
/*
* Attempt to change to high-speed (if supported)
*/
err = mmc_sd_switch_hs(card);
if (err > 0)
mmc_sd_go_highspeed(card);
else if (err)
goto free_card;
mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
/*
* Set bus speed.
*/
mmc_set_clock(host, mmc_sd_get_max_clock(card));
/*
* Switch to wider bus (if supported).
*/
if ((host->caps & MMC_CAP_4_BIT_DATA) &&
(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err)
goto free_card;
mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
}
}
host->card = card;
......@@ -773,6 +1099,15 @@ int mmc_attach_sd(struct mmc_host *host)
BUG_ON(!host);
WARN_ON(!host->claimed);
/* Make sure we are at 3.3V signalling voltage */
err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, false);
if (err)
return err;
/* Disable preset value enable if already set since last time */
if (host->ops->enable_preset_value)
host->ops->enable_preset_value(host, false);
err = mmc_send_app_op_cond(host, 0, &ocr);
if (err)
return err;
......
......@@ -5,7 +5,7 @@
extern struct device_type sd_type;
int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid);
int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr);
int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card);
void mmc_decode_cid(struct mmc_card *card);
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
......
......@@ -21,10 +21,10 @@
#include "core.h"
#include "sd_ops.h"
static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!host);
BUG_ON(card && (card->host != host));
......@@ -49,6 +49,7 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
return 0;
}
EXPORT_SYMBOL_GPL(mmc_app_cmd);
/**
* mmc_wait_for_app_cmd - start an application command and wait for
......@@ -66,7 +67,7 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
struct mmc_command *cmd, int retries)
{
struct mmc_request mrq;
struct mmc_request mrq = {0};
int i, err;
......@@ -119,13 +120,11 @@ EXPORT_SYMBOL(mmc_wait_for_app_cmd);
int mmc_app_set_bus_width(struct mmc_card *card, int width)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!card);
BUG_ON(!card->host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_APP_SET_BUS_WIDTH;
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
......@@ -149,13 +148,11 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width)
int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
int i, err = 0;
BUG_ON(!host);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_APP_OP_COND;
if (mmc_host_is_spi(host))
cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
......@@ -194,7 +191,7 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
{
struct mmc_command cmd;
struct mmc_command cmd = {0};
int err;
static const u8 test_pattern = 0xAA;
u8 result_pattern;
......@@ -226,13 +223,11 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
{
int err;
struct mmc_command cmd;
struct mmc_command cmd = {0};
BUG_ON(!host);
BUG_ON(!rca);
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_SEND_RELATIVE_ADDR;
cmd.arg = 0;
cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
......@@ -249,9 +244,9 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
{
int err;
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
void *data_buf;
......@@ -272,10 +267,6 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
if (data_buf == NULL)
return -ENOMEM;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
mrq.cmd = &cmd;
mrq.data = &data;
......@@ -312,9 +303,9 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
int mmc_sd_switch(struct mmc_card *card, int mode, int group,
u8 value, u8 *resp)
{
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
BUG_ON(!card);
......@@ -325,10 +316,6 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,
mode = !!mode;
value &= 0xF;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
mrq.cmd = &cmd;
mrq.data = &data;
......@@ -361,9 +348,9 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,
int mmc_app_sd_status(struct mmc_card *card, void *ssr)
{
int err;
struct mmc_request mrq;
struct mmc_command cmd;
struct mmc_data data;
struct mmc_request mrq = {0};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
BUG_ON(!card);
......@@ -376,10 +363,6 @@ int mmc_app_sd_status(struct mmc_card *card, void *ssr)
if (err)
return err;
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
mrq.cmd = &cmd;
mrq.data = &data;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment