Commit 46b51ea2 authored by Linus Torvalds's avatar Linus Torvalds

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: (83 commits)
  mmc: fix compile error when CONFIG_BLOCK is not enabled
  mmc: core: Cleanup eMMC4.5 conditionals
  mmc: omap_hsmmc: if multiblock reads are broken, disable them
  mmc: core: add workaround for controllers with broken multiblock reads
  mmc: core: Prevent too long response times for suspend
  mmc: recognise SDIO cards with SDIO_CCCR_REV 3.00
  mmc: sd: Handle SD3.0 cards not supporting UHS-I bus speed mode
  mmc: core: support HPI send command
  mmc: core: Add cache control for eMMC4.5 device
  mmc: core: Modify the timeout value for writing power class
  mmc: core: new discard feature support at eMMC v4.5
  mmc: core: mmc sanitize feature support for v4.5
  mmc: dw_mmc: modify DATA register offset
  mmc: sdhci-pci: add flag for devices that can support runtime PM
  mmc: omap_hsmmc: ensure pbias configuration is always done
  mmc: core: Add Power Off Notify Feature eMMC 4.5
  mmc: sdhci-s3c: fix potential NULL dereference
  mmc: replace printk with appropriate display macro
  mmc: core: Add default timeout value for CMD6
  mmc: sdhci-pci: add runtime pm support
  ...
parents 1fdb24e9 a6029e1f
* NVIDIA Tegra Secure Digital Host Controller
This controller on Tegra family SoCs provides an interface for MMC, SD,
and SDIO types of memory cards.
Required properties:
- compatible : Should be "nvidia,<chip>-sdhci"
- reg : Should contain SD/MMC registers location and length
- interrupts : Should contain SD/MMC interrupt
Optional properties:
- cd-gpios : Specify GPIOs for card detection
- wp-gpios : Specify GPIOs for write protection
- power-gpios : Specify GPIOs for power control
- support-8bit : Boolean, indicates if 8-bit mode should be used.
Example:
sdhci@c8000200 {
compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000200 0x200>;
interrupts = <47>;
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 155 0>; /* gpio PT3 */
support-8bit;
};
......@@ -21,6 +21,11 @@ o fail_make_request
/sys/block/<device>/make-it-fail or
/sys/block/<device>/<partition>/make-it-fail. (generic_make_request())
o fail_mmc_request
injects MMC data errors on devices permitted by setting
debugfs entries under /sys/kernel/debug/mmc0/fail_mmc_request
Configure fault-injection capabilities behavior
-----------------------------------------------
......@@ -115,7 +120,8 @@ use the boot option:
failslab=
fail_page_alloc=
fail_make_request=<interval>,<probability>,<space>,<times>
fail_make_request=
mmc_core.fail_request=<interval>,<probability>,<space>,<times>
How to add new fault injection capability
-----------------------------------------
......
......@@ -319,7 +319,7 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
if (!data)
return;
for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
if (data->slot[i].bus_width) {
/* input/irq */
if (data->slot[i].detect_pin) {
......
......@@ -175,12 +175,6 @@ static struct resource resources_sdc1[] = {
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC1_1,
.end = INT_SDC1_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
......@@ -203,12 +197,6 @@ static struct resource resources_sdc2[] = {
.end = INT_SDC2_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC2_1,
.end = INT_SDC2_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
......@@ -232,12 +220,6 @@ static struct resource resources_sdc3[] = {
.end = INT_SDC3_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC3_1,
.end = INT_SDC3_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
......@@ -261,12 +243,6 @@ static struct resource resources_sdc4[] = {
.end = INT_SDC4_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC4_1,
.end = INT_SDC4_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
......
......@@ -139,12 +139,6 @@ static struct resource resources_sdc1[] = {
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC1_1,
.end = INT_SDC1_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
.name = "status_irq"
......@@ -167,12 +161,6 @@ static struct resource resources_sdc2[] = {
.end = INT_SDC2_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC2_1,
.end = INT_SDC2_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
......@@ -196,12 +184,6 @@ static struct resource resources_sdc3[] = {
.end = INT_SDC3_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC3_1,
.end = INT_SDC3_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
......@@ -225,12 +207,6 @@ static struct resource resources_sdc4[] = {
.end = INT_SDC4_0,
.flags = IORESOURCE_IRQ,
.name = "cmd_irq",
},
{
.start = INT_SDC4_1,
.end = INT_SDC4_1,
.flags = IORESOURCE_IRQ,
.name = "pio_irq",
},
{
.flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
......
......@@ -8,13 +8,6 @@
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
struct embedded_sdio_data {
struct sdio_cis cis;
struct sdio_cccr cccr;
struct sdio_embedded_func *funcs;
int num_funcs;
};
struct msm_mmc_gpio {
unsigned no;
const char *name;
......@@ -29,9 +22,9 @@ struct msm_mmc_platform_data {
unsigned int ocr_mask; /* available voltages */
u32 (*translate_vdd)(struct device *, unsigned int);
unsigned int (*status)(struct device *);
struct embedded_sdio_data *embedded_sdio;
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
struct msm_mmc_gpio_data *gpio_data;
void (*init_card)(struct mmc_card *card);
};
#endif
......@@ -355,14 +355,17 @@ static struct resource sdhi0_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
.start = gic_spi(83),
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = SH_MOBILE_SDHI_IRQ_SDCARD,
.start = gic_spi(84),
.flags = IORESOURCE_IRQ,
},
[3] = {
.name = SH_MOBILE_SDHI_IRQ_SDIO,
.start = gic_spi(85),
.flags = IORESOURCE_IRQ,
},
......@@ -398,14 +401,17 @@ static struct resource sdhi1_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
.start = gic_spi(87),
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = SH_MOBILE_SDHI_IRQ_SDCARD,
.start = gic_spi(88),
.flags = IORESOURCE_IRQ,
},
[3] = {
.name = SH_MOBILE_SDHI_IRQ_SDIO,
.start = gic_spi(89),
.flags = IORESOURCE_IRQ,
},
......
......@@ -1072,14 +1072,17 @@ static struct resource sdhi1_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
.start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = SH_MOBILE_SDHI_IRQ_SDCARD,
.start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
.flags = IORESOURCE_IRQ,
},
[3] = {
.name = SH_MOBILE_SDHI_IRQ_SDIO,
.start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
.flags = IORESOURCE_IRQ,
},
......@@ -1123,14 +1126,17 @@ static struct resource sdhi2_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
.start = evt2irq(0x1200), /* SDHI2_SDHI2I0 */
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = SH_MOBILE_SDHI_IRQ_SDCARD,
.start = evt2irq(0x1220), /* SDHI2_SDHI2I1 */
.flags = IORESOURCE_IRQ,
},
[3] = {
.name = SH_MOBILE_SDHI_IRQ_SDIO,
.start = evt2irq(0x1240), /* SDHI2_SDHI2I2 */
.flags = IORESOURCE_IRQ,
},
......
......@@ -31,7 +31,24 @@
#define OMAP_MMC_MAX_SLOTS 2
#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT BIT(1)
/*
* struct omap_mmc_dev_attr.flags possibilities
*
* OMAP_HSMMC_SUPPORTS_DUAL_VOLT: Some HSMMC controller instances can
* operate with either 1.8Vdc or 3.0Vdc card voltages; this flag
* should be set if this is the case. See for example Section 22.5.3
* "MMC/SD/SDIO1 Bus Voltage Selection" of the OMAP34xx Multimedia
* Device Silicon Revision 3.1.x Revision ZR (July 2011) (SWPU223R).
*
* OMAP_HSMMC_BROKEN_MULTIBLOCK_READ: Multiple-block read transfers
* don't work correctly on some MMC controller instances on some
* OMAP3 SoCs; this flag should be set if this is the case. See
* for example Advisory 2.1.1.128 "MMC: Multiple Block Read
* Operation Issue" in _OMAP3530/3525/3515/3503 Silicon Errata_
* Revision F (October 2010) (SPRZ278F).
*/
#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT BIT(0)
#define OMAP_HSMMC_BROKEN_MULTIBLOCK_READ BIT(1)
struct omap_mmc_dev_attr {
u8 flags;
......
This diff is collapsed.
......@@ -22,6 +22,7 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>
#include <linux/module.h>
#define RESULT_OK 0
#define RESULT_FAIL 1
......@@ -250,7 +251,7 @@ static int mmc_test_wait_busy(struct mmc_test_card *test)
if (!busy && mmc_test_busy(&cmd)) {
busy = 1;
if (test->card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
printk(KERN_INFO "%s: Warning: Host did not "
pr_info("%s: Warning: Host did not "
"wait for busy state to end.\n",
mmc_hostname(test->card->host));
}
......@@ -552,7 +553,7 @@ static void mmc_test_print_rate(struct mmc_test_card *test, uint64_t bytes,
rate = mmc_test_rate(bytes, &ts);
iops = mmc_test_rate(100, &ts); /* I/O ops per sec x 100 */
printk(KERN_INFO "%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu "
pr_info("%s: Transfer of %u sectors (%u%s KiB) took %lu.%09lu "
"seconds (%u kB/s, %u KiB/s, %u.%02u IOPS)\n",
mmc_hostname(test->card->host), sectors, sectors >> 1,
(sectors & 1 ? ".5" : ""), (unsigned long)ts.tv_sec,
......@@ -578,7 +579,7 @@ static void mmc_test_print_avg_rate(struct mmc_test_card *test, uint64_t bytes,
rate = mmc_test_rate(tot, &ts);
iops = mmc_test_rate(count * 100, &ts); /* I/O ops per sec x 100 */
printk(KERN_INFO "%s: Transfer of %u x %u sectors (%u x %u%s KiB) took "
pr_info("%s: Transfer of %u x %u sectors (%u x %u%s KiB) took "
"%lu.%09lu seconds (%u kB/s, %u KiB/s, "
"%u.%02u IOPS, sg_len %d)\n",
mmc_hostname(test->card->host), count, sectors, count,
......@@ -1408,7 +1409,7 @@ static int mmc_test_multi_read_high(struct mmc_test_card *test)
static int mmc_test_no_highmem(struct mmc_test_card *test)
{
printk(KERN_INFO "%s: Highmem not configured - test skipped\n",
pr_info("%s: Highmem not configured - test skipped\n",
mmc_hostname(test->card->host));
return 0;
}
......@@ -1435,7 +1436,7 @@ static int mmc_test_area_map(struct mmc_test_card *test, unsigned long sz,
t->max_seg_sz, &t->sg_len, min_sg_len);
}
if (err)
printk(KERN_INFO "%s: Failed to map sg list\n",
pr_info("%s: Failed to map sg list\n",
mmc_hostname(test->card->host));
return err;
}
......@@ -2135,7 +2136,7 @@ static int mmc_test_rw_multiple(struct mmc_test_card *test,
return ret;
err:
printk(KERN_INFO "[%s] error\n", __func__);
pr_info("[%s] error\n", __func__);
return ret;
}
......@@ -2149,7 +2150,7 @@ static int mmc_test_rw_multiple_size(struct mmc_test_card *test,
if (rw->do_nonblock_req &&
((!pre_req && post_req) || (pre_req && !post_req))) {
printk(KERN_INFO "error: only one of pre/post is defined\n");
pr_info("error: only one of pre/post is defined\n");
return -EINVAL;
}
......@@ -2328,6 +2329,31 @@ static int mmc_test_profile_sglen_r_nonblock_perf(struct mmc_test_card *test)
return mmc_test_rw_multiple_sg_len(test, &test_data);
}
/*
* eMMC hardware reset.
*/
static int mmc_test_hw_reset(struct mmc_test_card *test)
{
struct mmc_card *card = test->card;
struct mmc_host *host = card->host;
int err;
err = mmc_hw_reset_check(host);
if (!err)
return RESULT_OK;
if (err == -ENOSYS)
return RESULT_FAIL;
if (err != -EOPNOTSUPP)
return err;
if (!mmc_can_reset(card))
return RESULT_UNSUP_CARD;
return RESULT_UNSUP_HOST;
}
static const struct mmc_test_case mmc_test_cases[] = {
{
.name = "Basic write (no data verification)",
......@@ -2650,6 +2676,11 @@ static const struct mmc_test_case mmc_test_cases[] = {
.run = mmc_test_profile_sglen_r_nonblock_perf,
.cleanup = mmc_test_area_cleanup,
},
{
.name = "eMMC hardware reset",
.run = mmc_test_hw_reset,
},
};
static DEFINE_MUTEX(mmc_test_lock);
......@@ -2660,7 +2691,7 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
{
int i, ret;
printk(KERN_INFO "%s: Starting tests of card %s...\n",
pr_info("%s: Starting tests of card %s...\n",
mmc_hostname(test->card->host), mmc_card_id(test->card));
mmc_claim_host(test->card->host);
......@@ -2671,14 +2702,14 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
if (testcase && ((i + 1) != testcase))
continue;
printk(KERN_INFO "%s: Test case %d. %s...\n",
pr_info("%s: Test case %d. %s...\n",
mmc_hostname(test->card->host), i + 1,
mmc_test_cases[i].name);
if (mmc_test_cases[i].prepare) {
ret = mmc_test_cases[i].prepare(test);
if (ret) {
printk(KERN_INFO "%s: Result: Prepare "
pr_info("%s: Result: Prepare "
"stage failed! (%d)\n",
mmc_hostname(test->card->host),
ret);
......@@ -2708,25 +2739,25 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
ret = mmc_test_cases[i].run(test);
switch (ret) {
case RESULT_OK:
printk(KERN_INFO "%s: Result: OK\n",
pr_info("%s: Result: OK\n",
mmc_hostname(test->card->host));
break;
case RESULT_FAIL:
printk(KERN_INFO "%s: Result: FAILED\n",
pr_info("%s: Result: FAILED\n",
mmc_hostname(test->card->host));
break;
case RESULT_UNSUP_HOST:
printk(KERN_INFO "%s: Result: UNSUPPORTED "
pr_info("%s: Result: UNSUPPORTED "
"(by host)\n",
mmc_hostname(test->card->host));
break;
case RESULT_UNSUP_CARD:
printk(KERN_INFO "%s: Result: UNSUPPORTED "
pr_info("%s: Result: UNSUPPORTED "
"(by card)\n",
mmc_hostname(test->card->host));
break;
default:
printk(KERN_INFO "%s: Result: ERROR (%d)\n",
pr_info("%s: Result: ERROR (%d)\n",
mmc_hostname(test->card->host), ret);
}
......@@ -2737,7 +2768,7 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
if (mmc_test_cases[i].cleanup) {
ret = mmc_test_cases[i].cleanup(test);
if (ret) {
printk(KERN_INFO "%s: Warning: Cleanup "
pr_info("%s: Warning: Cleanup "
"stage failed! (%d)\n",
mmc_hostname(test->card->host),
ret);
......@@ -2747,7 +2778,7 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase)
mmc_release_host(test->card->host);
printk(KERN_INFO "%s: Tests completed.\n",
pr_info("%s: Tests completed.\n",
mmc_hostname(test->card->host));
}
......
......@@ -108,7 +108,7 @@ static void mmc_request(struct request_queue *q)
wake_up_process(mq->thread);
}
struct scatterlist *mmc_alloc_sg(int sg_len, int *err)
static struct scatterlist *mmc_alloc_sg(int sg_len, int *err)
{
struct scatterlist *sg;
......@@ -140,7 +140,7 @@ static void mmc_queue_setup_discard(struct request_queue *q,
/* granularity must not be greater than max. discard */
if (card->pref_erase > max_discard)
q->limits.discard_granularity = 0;
if (mmc_can_secure_erase_trim(card))
if (mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))
queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
}
......@@ -197,13 +197,13 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
if (bouncesz > 512) {
mqrq_cur->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
if (!mqrq_cur->bounce_buf) {
printk(KERN_WARNING "%s: unable to "
pr_warning("%s: unable to "
"allocate bounce cur buffer\n",
mmc_card_name(card));
}
mqrq_prev->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
if (!mqrq_prev->bounce_buf) {
printk(KERN_WARNING "%s: unable to "
pr_warning("%s: unable to "
"allocate bounce prev buffer\n",
mmc_card_name(card));
kfree(mqrq_cur->bounce_buf);
......
......@@ -1082,7 +1082,7 @@ static int sdio_uart_probe(struct sdio_func *func,
return -ENOMEM;
if (func->class == SDIO_CLASS_UART) {
printk(KERN_WARNING "%s: need info on UART class basic setup\n",
pr_warning("%s: need info on UART class basic setup\n",
sdio_func_id(func));
kfree(port);
return -ENOSYS;
......@@ -1101,23 +1101,23 @@ static int sdio_uart_probe(struct sdio_func *func,
break;
}
if (!tpl) {
printk(KERN_WARNING
pr_warning(
"%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
sdio_func_id(func));
kfree(port);
return -EINVAL;
}
printk(KERN_DEBUG "%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",
pr_debug("%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",
sdio_func_id(func), tpl->data[2], tpl->data[3]);
port->regs_offset = (tpl->data[4] << 0) |
(tpl->data[5] << 8) |
(tpl->data[6] << 16);
printk(KERN_DEBUG "%s: regs offset = 0x%x\n",
pr_debug("%s: regs offset = 0x%x\n",
sdio_func_id(func), port->regs_offset);
port->uartclk = tpl->data[7] * 115200;
if (port->uartclk == 0)
port->uartclk = 115200;
printk(KERN_DEBUG "%s: clk %d baudcode %u 4800-div %u\n",
pr_debug("%s: clk %d baudcode %u 4800-div %u\n",
sdio_func_id(func), port->uartclk,
tpl->data[7], tpl->data[8] | (tpl->data[9] << 8));
} else {
......
......@@ -295,7 +295,7 @@ int mmc_add_card(struct mmc_card *card)
}
if (mmc_host_is_spi(card->host)) {
printk(KERN_INFO "%s: new %s%s%s card on SPI\n",
pr_info("%s: new %s%s%s card on SPI\n",
mmc_hostname(card->host),
mmc_card_highspeed(card) ? "high speed " : "",
mmc_card_ddr_mode(card) ? "DDR " : "",
......@@ -334,10 +334,10 @@ void mmc_remove_card(struct mmc_card *card)
if (mmc_card_present(card)) {
if (mmc_host_is_spi(card->host)) {
printk(KERN_INFO "%s: SPI card removed\n",
pr_info("%s: SPI card removed\n",
mmc_hostname(card->host));
} else {
printk(KERN_INFO "%s: card %04x removed\n",
pr_info("%s: card %04x removed\n",
mmc_hostname(card->host), card->rca);
}
device_del(&card->dev);
......
This diff is collapsed.
......@@ -43,6 +43,7 @@ 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);
void mmc_power_off(struct mmc_host *host);
static inline void mmc_delay(unsigned int ms)
{
......
......@@ -7,11 +7,13 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/moduleparam.h>
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/fault-inject.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
......@@ -19,6 +21,14 @@
#include "core.h"
#include "mmc_ops.h"
#ifdef CONFIG_FAIL_MMC_REQUEST
static DECLARE_FAULT_ATTR(fail_default_attr);
static char *fail_request;
module_param(fail_request, charp, 0);
#endif /* CONFIG_FAIL_MMC_REQUEST */
/* The debugfs functions are optimized away when CONFIG_DEBUG_FS isn't set. */
static int mmc_ios_show(struct seq_file *s, void *data)
{
......@@ -113,6 +123,15 @@ static int mmc_ios_show(struct seq_file *s, void *data)
case MMC_TIMING_SD_HS:
str = "sd high-speed";
break;
case MMC_TIMING_UHS_SDR50:
str = "sd uhs SDR50";
break;
case MMC_TIMING_UHS_SDR104:
str = "sd uhs SDR104";
break;
case MMC_TIMING_UHS_DDR50:
str = "sd uhs DDR50";
break;
default:
str = "invalid";
break;
......@@ -187,6 +206,15 @@ void mmc_add_host_debugfs(struct mmc_host *host)
if (!debugfs_create_u32("clk_delay", (S_IRUSR | S_IWUSR),
root, &host->clk_delay))
goto err_node;
#endif
#ifdef CONFIG_FAIL_MMC_REQUEST
if (fail_request)
setup_fault_attr(&fail_default_attr, fail_request);
host->fail_mmc_request = fail_default_attr;
if (IS_ERR(fault_create_debugfs_attr("fail_mmc_request",
root,
&host->fail_mmc_request)))
goto err_node;
#endif
return;
......
......@@ -301,6 +301,17 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
host->max_blk_size = 512;
host->max_blk_count = PAGE_CACHE_SIZE / 512;
/*
* Enable runtime power management by default. This flag was added due
* to runtime power management causing disruption for some users, but
* the power on/off code has been improved since then.
*
* We'll enable this flag by default as an experiment, and if no
* problems are reported, we will follow up later and remove the flag
* altogether.
*/
host->caps = MMC_CAP_POWER_OFF_CARD;
return host;
free:
......
This diff is collapsed.
......@@ -233,7 +233,7 @@ static int
mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
u32 opcode, void *buf, unsigned len)
{
struct mmc_request mrq = {0};
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
......@@ -414,7 +414,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
return -EBADMSG;
} else {
if (status & 0xFDFFA000)
printk(KERN_WARNING "%s: unexpected status %#x after "
pr_warning("%s: unexpected status %#x after "
"switch", mmc_hostname(card->host), status);
if (status & R1_SWITCH_ERROR)
return -EBADMSG;
......@@ -454,7 +454,7 @@ static int
mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
u8 len)
{
struct mmc_request mrq = {0};
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
......@@ -476,7 +476,7 @@ mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
else if (len == 4)
test_buf = testdata_4bit;
else {
printk(KERN_ERR "%s: Invalid bus_width %d\n",
pr_err("%s: Invalid bus_width %d\n",
mmc_hostname(host), len);
kfree(data_buf);
return -EINVAL;
......@@ -547,3 +547,34 @@ int mmc_bus_test(struct mmc_card *card, u8 bus_width)
err = mmc_send_bus_test(card, card->host, MMC_BUS_TEST_R, width);
return err;
}
int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status)
{
struct mmc_command cmd = {0};
unsigned int opcode;
unsigned int flags;
int err;
opcode = card->ext_csd.hpi_cmd;
if (opcode == MMC_STOP_TRANSMISSION)
flags = MMC_RSP_R1 | MMC_CMD_AC;
else if (opcode == MMC_SEND_STATUS)
flags = MMC_RSP_R1 | MMC_CMD_AC;
cmd.opcode = opcode;
cmd.arg = card->rca << 16 | 1;
cmd.flags = flags;
cmd.cmd_timeout_ms = card->ext_csd.out_of_int_time;
err = mmc_wait_for_cmd(card->host, &cmd, 0);
if (err) {
pr_warn("%s: error %d interrupting operation. "
"HPI command response %#x\n", mmc_hostname(card->host),
err, cmd.resp[0]);
return err;
}
if (status)
*status = cmd.resp[0];
return 0;
}
......@@ -26,6 +26,7 @@ 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);
int mmc_card_sleepawake(struct mmc_host *host, int sleep);
int mmc_bus_test(struct mmc_card *card, u8 bus_width);
int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
#endif
......@@ -21,6 +21,14 @@
#define SDIO_DEVICE_ID_TI_WL1271 0x4076
#endif
#ifndef SDIO_VENDOR_ID_STE
#define SDIO_VENDOR_ID_STE 0x0020
#endif
#ifndef SDIO_DEVICE_ID_STE_CW1200
#define SDIO_DEVICE_ID_STE_CW1200 0x2280
#endif
/*
* This hook just adds a quirk for all sdio devices
*/
......@@ -46,6 +54,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = {
SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
add_quirk, MMC_QUIRK_DISABLE_CD),
SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200,
add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512),
END_FIXUP
};
......
......@@ -163,7 +163,7 @@ static int mmc_decode_csd(struct mmc_card *card)
csd->erase_size = 1;
break;
default:
printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
pr_err("%s: unrecognised CSD structure version %d\n",
mmc_hostname(card->host), csd_struct);
return -EINVAL;
}
......@@ -187,7 +187,7 @@ static int mmc_decode_scr(struct mmc_card *card)
scr_struct = UNSTUFF_BITS(resp, 60, 4);
if (scr_struct != 0) {
printk(KERN_ERR "%s: unrecognised SCR structure version %d\n",
pr_err("%s: unrecognised SCR structure version %d\n",
mmc_hostname(card->host), scr_struct);
return -EINVAL;
}
......@@ -218,7 +218,7 @@ static int mmc_read_ssr(struct mmc_card *card)
u32 *ssr;
if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
printk(KERN_WARNING "%s: card lacks mandatory SD Status "
pr_warning("%s: card lacks mandatory SD Status "
"function.\n", mmc_hostname(card->host));
return 0;
}
......@@ -229,7 +229,7 @@ static int mmc_read_ssr(struct mmc_card *card)
err = mmc_app_sd_status(card, ssr);
if (err) {
printk(KERN_WARNING "%s: problem reading SD Status "
pr_warning("%s: problem reading SD Status "
"register.\n", mmc_hostname(card->host));
err = 0;
goto out;
......@@ -253,7 +253,7 @@ static int mmc_read_ssr(struct mmc_card *card)
card->ssr.erase_offset = eo * 1000;
}
} else {
printk(KERN_WARNING "%s: SD Status: Invalid Allocation Unit "
pr_warning("%s: SD Status: Invalid Allocation Unit "
"size.\n", mmc_hostname(card->host));
}
out:
......@@ -273,7 +273,7 @@ static int mmc_read_switch(struct mmc_card *card)
return 0;
if (!(card->csd.cmdclass & CCC_SWITCH)) {
printk(KERN_WARNING "%s: card lacks mandatory switch "
pr_warning("%s: card lacks mandatory switch "
"function, performance might suffer.\n",
mmc_hostname(card->host));
return 0;
......@@ -283,7 +283,7 @@ 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 "
pr_err("%s: could not allocate a buffer for "
"switch capabilities.\n",
mmc_hostname(card->host));
return -ENOMEM;
......@@ -299,13 +299,16 @@ static int mmc_read_switch(struct mmc_card *card)
if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
goto out;
printk(KERN_WARNING "%s: problem reading Bus Speed modes.\n",
pr_warning("%s: problem reading Bus Speed modes.\n",
mmc_hostname(card->host));
err = 0;
goto out;
}
if (status[13] & UHS_SDR50_BUS_SPEED)
card->sw_caps.hs_max_dtr = 50000000;
if (card->scr.sda_spec3) {
card->sw_caps.sd3_bus_mode = status[13];
......@@ -319,7 +322,7 @@ static int mmc_read_switch(struct mmc_card *card)
if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
goto out;
printk(KERN_WARNING "%s: problem reading "
pr_warning("%s: problem reading "
"Driver Strength.\n",
mmc_hostname(card->host));
err = 0;
......@@ -339,7 +342,7 @@ static int mmc_read_switch(struct mmc_card *card)
if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
goto out;
printk(KERN_WARNING "%s: problem reading "
pr_warning("%s: problem reading "
"Current Limit.\n",
mmc_hostname(card->host));
err = 0;
......@@ -348,9 +351,6 @@ static int mmc_read_switch(struct mmc_card *card)
}
card->sw_caps.sd3_curr_limit = status[7];
} else {
if (status[13] & 0x02)
card->sw_caps.hs_max_dtr = 50000000;
}
out:
......@@ -383,7 +383,7 @@ int mmc_sd_switch_hs(struct mmc_card *card)
status = kmalloc(64, GFP_KERNEL);
if (!status) {
printk(KERN_ERR "%s: could not allocate a buffer for "
pr_err("%s: could not allocate a buffer for "
"switch capabilities.\n", mmc_hostname(card->host));
return -ENOMEM;
}
......@@ -393,7 +393,7 @@ int mmc_sd_switch_hs(struct mmc_card *card)
goto out;
if ((status[16] & 0xF) != 1) {
printk(KERN_WARNING "%s: Problem switching card "
pr_warning("%s: Problem switching card "
"into high-speed mode!\n",
mmc_hostname(card->host));
err = 0;
......@@ -459,7 +459,7 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status)
return err;
if ((status[15] & 0xF) != drive_strength) {
printk(KERN_WARNING "%s: Problem setting drive strength!\n",
pr_warning("%s: Problem setting drive strength!\n",
mmc_hostname(card->host));
return 0;
}
......@@ -538,7 +538,7 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
return err;
if ((status[16] & 0xF) != card->sd_bus_speed)
printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
pr_warning("%s: Problem setting bus speed mode!\n",
mmc_hostname(card->host));
else {
mmc_set_timing(card->host, timing);
......@@ -600,7 +600,7 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
return err;
if (((status[15] >> 4) & 0x0F) != current_limit)
printk(KERN_WARNING "%s: Problem setting current limit!\n",
pr_warning("%s: Problem setting current limit!\n",
mmc_hostname(card->host));
return 0;
......@@ -622,7 +622,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
status = kmalloc(64, GFP_KERNEL);
if (!status) {
printk(KERN_ERR "%s: could not allocate a buffer for "
pr_err("%s: could not allocate a buffer for "
"switch capabilities.\n", mmc_hostname(card->host));
return -ENOMEM;
}
......@@ -852,7 +852,7 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
ro = host->ops->get_ro(host);
if (ro < 0) {
printk(KERN_WARNING "%s: host does not "
pr_warning("%s: host does not "
"support reading read-only "
"switch. assuming write-enable.\n",
mmc_hostname(host));
......@@ -929,8 +929,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
err = mmc_send_relative_addr(host, &card->rca);
if (err)
return err;
mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
}
if (!oldcard) {
......@@ -1043,6 +1041,7 @@ static void mmc_sd_detect(struct mmc_host *host)
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
mmc_release_host(host);
}
}
......@@ -1167,7 +1166,7 @@ int mmc_attach_sd(struct mmc_host *host)
* support.
*/
if (ocr & 0x7F) {
printk(KERN_WARNING "%s: card claims to support voltages "
pr_warning("%s: card claims to support voltages "
"below the defined range. These will be ignored.\n",
mmc_hostname(host));
ocr &= ~0x7F;
......@@ -1175,7 +1174,7 @@ int mmc_attach_sd(struct mmc_host *host)
if ((ocr & MMC_VDD_165_195) &&
!(host->ocr_avail_sd & MMC_VDD_165_195)) {
printk(KERN_WARNING "%s: SD card claims to support the "
pr_warning("%s: SD card claims to support the "
"incompletely defined 'low voltage range'. This "
"will be ignored.\n", mmc_hostname(host));
ocr &= ~MMC_VDD_165_195;
......@@ -1214,7 +1213,7 @@ int mmc_attach_sd(struct mmc_host *host)
err:
mmc_detach_bus(host);
printk(KERN_ERR "%s: error %d whilst initialising SD card\n",
pr_err("%s: error %d whilst initialising SD card\n",
mmc_hostname(host), err);
return err;
......
......@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(mmc_app_cmd);
int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
struct mmc_command *cmd, int retries)
{
struct mmc_request mrq = {0};
struct mmc_request mrq = {NULL};
int i, err;
......@@ -244,7 +244,7 @@ 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 = {0};
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
......@@ -303,7 +303,7 @@ 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 = {0};
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
......@@ -348,7 +348,7 @@ 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 = {0};
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
......
......@@ -111,8 +111,8 @@ static int sdio_read_cccr(struct mmc_card *card)
cccr_vsn = data & 0x0f;
if (cccr_vsn > SDIO_CCCR_REV_1_20) {
printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n",
if (cccr_vsn > SDIO_CCCR_REV_3_00) {
pr_err("%s: unrecognised CCCR structure version %d\n",
mmc_hostname(card->host), cccr_vsn);
return -EINVAL;
}
......@@ -408,8 +408,6 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
*/
if (oldcard)
oldcard->rca = card->rca;
mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
}
/*
......@@ -597,6 +595,7 @@ static void mmc_sdio_detect(struct mmc_host *host)
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
mmc_release_host(host);
}
}
......@@ -778,7 +777,7 @@ int mmc_attach_sdio(struct mmc_host *host)
* support.
*/
if (ocr & 0x7F) {
printk(KERN_WARNING "%s: card claims to support voltages "
pr_warning("%s: card claims to support voltages "
"below the defined range. These will be ignored.\n",
mmc_hostname(host));
ocr &= ~0x7F;
......@@ -875,7 +874,7 @@ int mmc_attach_sdio(struct mmc_host *host)
err:
mmc_detach_bus(host);
printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n",
pr_err("%s: error %d whilst initialising SDIO card\n",
mmc_hostname(host), err);
return err;
......
......@@ -173,7 +173,7 @@ static int sdio_bus_remove(struct device *dev)
drv->remove(func);
if (func->irq_handler) {
printk(KERN_WARNING "WARNING: driver %s did not remove "
pr_warning("WARNING: driver %s did not remove "
"its interrupt handler!\n", drv->name);
sdio_claim_host(func);
sdio_release_irq(func);
......
......@@ -132,7 +132,7 @@ static int cis_tpl_parse(struct mmc_card *card, struct sdio_func *func,
ret = -EINVAL;
}
if (ret && ret != -EILSEQ && ret != -ENOENT) {
printk(KERN_ERR "%s: bad %s tuple 0x%02x (%u bytes)\n",
pr_err("%s: bad %s tuple 0x%02x (%u bytes)\n",
mmc_hostname(card->host), tpl_descr, code, size);
}
} else {
......@@ -313,7 +313,7 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
if (ret == -ENOENT) {
/* warn about unknown tuples */
printk(KERN_WARNING "%s: queuing unknown"
pr_warning("%s: queuing unknown"
" CIS tuple 0x%02x (%u bytes)\n",
mmc_hostname(card->host),
tpl_code, tpl_link);
......
......@@ -45,7 +45,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card)
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
if (ret) {
printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
pr_debug("%s: error %d reading SDIO_CCCR_INTx\n",
mmc_card_id(card), ret);
return ret;
}
......@@ -55,7 +55,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card)
if (pending & (1 << i)) {
func = card->sdio_func[i - 1];
if (!func) {
printk(KERN_WARNING "%s: pending IRQ for "
pr_warning("%s: pending IRQ for "
"non-existent function\n",
mmc_card_id(card));
ret = -EINVAL;
......@@ -63,7 +63,7 @@ static int process_sdio_pending_irqs(struct mmc_card *card)
func->irq_handler(func);
count++;
} else {
printk(KERN_WARNING "%s: pending IRQ with no handler\n",
pr_warning("%s: pending IRQ with no handler\n",
sdio_func_id(func));
ret = -EINVAL;
}
......
......@@ -121,7 +121,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
{
struct mmc_request mrq = {0};
struct mmc_request mrq = {NULL};
struct mmc_command cmd = {0};
struct mmc_data data = {0};
struct scatterlist sg;
......@@ -144,8 +144,11 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
cmd.arg |= fn << 28;
cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
cmd.arg |= addr << 9;
if (blocks == 1 && blksz <= 512)
cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */
if (blocks == 1 && blksz < 512)
cmd.arg |= blksz; /* byte mode */
else if (blocks == 1 && blksz == 512 &&
!(mmc_card_broken_byte_mode_512(card)))
cmd.arg |= 0; /* byte mode, 0==512 */
else
cmd.arg |= 0x08000000 | blocks; /* block mode */
cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
......
......@@ -130,13 +130,13 @@ config MMC_SDHCI_CNS3XXX
If unsure, say N.
config MMC_SDHCI_ESDHC_IMX
tristate "SDHCI platform support for the Freescale eSDHC i.MX controller"
depends on ARCH_MX25 || ARCH_MX35 || ARCH_MX5
tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
depends on ARCH_MXC
depends on MMC_SDHCI_PLTFM
select MMC_SDHCI_IO_ACCESSORS
help
This selects the Freescale eSDHC controller support on the platform
bus, found on platforms like mx35/51.
This selects the Freescale eSDHC/uSDHC controller support
found on i.MX25, i.MX35 i.MX5x and i.MX6x.
If you have a controller with this interface, say Y or M here.
......@@ -326,11 +326,11 @@ config MMC_MSM
support for SDIO devices.
config MMC_MXC
tristate "Freescale i.MX2/3 Multimedia Card Interface support"
depends on MACH_MX21 || MACH_MX27 || ARCH_MX31
tristate "Freescale i.MX21/27/31 Multimedia Card Interface support"
depends on ARCH_MXC
help
This selects the Freescale i.MX2/3 Multimedia card Interface.
If you have a i.MX platform with a Multimedia Card slot,
This selects the Freescale i.MX21, i.MX27 and i.MX31 Multimedia card
Interface. If you have a i.MX platform with a Multimedia Card slot,
say Y or M here.
If unsure, say N.
......
......@@ -869,7 +869,11 @@ static irqreturn_t at91_mci_irq(int irq, void *devid)
static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
{
struct at91mci_host *host = _host;
int present = !gpio_get_value(irq_to_gpio(irq));
int present;
/* entering this ISR means that we have configured det_pin:
* we can use its value in board structure */
present = !gpio_get_value(host->board->det_pin);
/*
* we expect this irq on both insert and remove,
......
This diff is collapsed.
This diff is collapsed.
......@@ -55,7 +55,7 @@
#ifdef DEBUG
#define DBG(fmt, idx, args...) \
printk(KERN_DEBUG "au1xmmc(%d): DEBUG: " fmt, idx, ##args)
pr_debug("au1xmmc(%d): DEBUG: " fmt, idx, ##args)
#else
#define DBG(fmt, idx, args...) do {} while (0)
#endif
......@@ -268,7 +268,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
mmccmd |= SD_CMD_RT_3;
break;
default:
printk(KERN_INFO "au1xmmc: unhandled response type %02x\n",
pr_info("au1xmmc: unhandled response type %02x\n",
mmc_resp_type(cmd));
return -EINVAL;
}
......@@ -1031,7 +1031,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
#ifdef CONFIG_SOC_AU1200
ret = au1xmmc_dbdma_init(host);
if (ret)
printk(KERN_INFO DRIVER_NAME ": DBDMA init failed; using PIO\n");
pr_info(DRIVER_NAME ": DBDMA init failed; using PIO\n");
#endif
#ifdef CONFIG_LEDS_CLASS
......@@ -1056,7 +1056,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X"
pr_info(DRIVER_NAME ": MMC Controller %d set up at %8.8X"
" (mode=%s)\n", pdev->id, host->iobase,
host->flags & HOST_F_DMA ? "dma" : "pio");
......@@ -1188,7 +1188,7 @@ static int __init au1xmmc_init(void)
*/
memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
if (!memid)
printk(KERN_ERR "au1xmmc: cannot add memory dbdma dev\n");
pr_err("au1xmmc: cannot add memory dbdma dev\n");
#endif
return platform_driver_register(&au1xmmc_driver);
}
......
......@@ -764,11 +764,29 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
return present;
}
static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
{
struct dw_mci_slot *slot = mmc_priv(mmc);
struct dw_mci *host = slot->host;
u32 int_mask;
/* Enable/disable Slot Specific SDIO interrupt */
int_mask = mci_readl(host, INTMASK);
if (enb) {
mci_writel(host, INTMASK,
(int_mask | (1 << SDMMC_INT_SDIO(slot->id))));
} else {
mci_writel(host, INTMASK,
(int_mask & ~(1 << SDMMC_INT_SDIO(slot->id))));
}
}
static const struct mmc_host_ops dw_mci_ops = {
.request = dw_mci_request,
.set_ios = dw_mci_set_ios,
.get_ro = dw_mci_get_ro,
.get_cd = dw_mci_get_cd,
.request = dw_mci_request,
.set_ios = dw_mci_set_ios,
.get_ro = dw_mci_get_ro,
.get_cd = dw_mci_get_cd,
.enable_sdio_irq = dw_mci_enable_sdio_irq,
};
static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
......@@ -1025,7 +1043,8 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
buf += len;
cnt -= len;
if (!sg_next(host->sg) || host->part_buf_count == 2) {
mci_writew(host, DATA, host->part_buf16);
mci_writew(host, DATA(host->data_offset),
host->part_buf16);
host->part_buf_count = 0;
}
}
......@@ -1042,21 +1061,23 @@ static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt)
cnt -= len;
/* push data from aligned buffer into fifo */
for (i = 0; i < items; ++i)
mci_writew(host, DATA, aligned_buf[i]);
mci_writew(host, DATA(host->data_offset),
aligned_buf[i]);
}
} else
#endif
{
u16 *pdata = buf;
for (; cnt >= 2; cnt -= 2)
mci_writew(host, DATA, *pdata++);
mci_writew(host, DATA(host->data_offset), *pdata++);
buf = pdata;
}
/* put anything remaining in the part_buf */
if (cnt) {
dw_mci_set_part_bytes(host, buf, cnt);
if (!sg_next(host->sg))
mci_writew(host, DATA, host->part_buf16);
mci_writew(host, DATA(host->data_offset),
host->part_buf16);
}
}
......@@ -1071,7 +1092,8 @@ static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt)
int items = len >> 1;
int i;
for (i = 0; i < items; ++i)
aligned_buf[i] = mci_readw(host, DATA);
aligned_buf[i] = mci_readw(host,
DATA(host->data_offset));
/* memcpy from aligned buffer into output buffer */
memcpy(buf, aligned_buf, len);
buf += len;
......@@ -1082,11 +1104,11 @@ static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt)
{
u16 *pdata = buf;
for (; cnt >= 2; cnt -= 2)
*pdata++ = mci_readw(host, DATA);
*pdata++ = mci_readw(host, DATA(host->data_offset));
buf = pdata;
}
if (cnt) {
host->part_buf16 = mci_readw(host, DATA);
host->part_buf16 = mci_readw(host, DATA(host->data_offset));
dw_mci_pull_final_bytes(host, buf, cnt);
}
}
......@@ -1099,7 +1121,8 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
buf += len;
cnt -= len;
if (!sg_next(host->sg) || host->part_buf_count == 4) {
mci_writel(host, DATA, host->part_buf32);
mci_writel(host, DATA(host->data_offset),
host->part_buf32);
host->part_buf_count = 0;
}
}
......@@ -1116,21 +1139,23 @@ static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt)
cnt -= len;
/* push data from aligned buffer into fifo */
for (i = 0; i < items; ++i)
mci_writel(host, DATA, aligned_buf[i]);
mci_writel(host, DATA(host->data_offset),
aligned_buf[i]);
}
} else
#endif
{
u32 *pdata = buf;
for (; cnt >= 4; cnt -= 4)
mci_writel(host, DATA, *pdata++);
mci_writel(host, DATA(host->data_offset), *pdata++);
buf = pdata;
}
/* put anything remaining in the part_buf */
if (cnt) {
dw_mci_set_part_bytes(host, buf, cnt);
if (!sg_next(host->sg))
mci_writel(host, DATA, host->part_buf32);
mci_writel(host, DATA(host->data_offset),
host->part_buf32);
}
}
......@@ -1145,7 +1170,8 @@ static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt)
int items = len >> 2;
int i;
for (i = 0; i < items; ++i)
aligned_buf[i] = mci_readl(host, DATA);
aligned_buf[i] = mci_readl(host,
DATA(host->data_offset));
/* memcpy from aligned buffer into output buffer */
memcpy(buf, aligned_buf, len);
buf += len;
......@@ -1156,11 +1182,11 @@ static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt)
{
u32 *pdata = buf;
for (; cnt >= 4; cnt -= 4)
*pdata++ = mci_readl(host, DATA);
*pdata++ = mci_readl(host, DATA(host->data_offset));
buf = pdata;
}
if (cnt) {
host->part_buf32 = mci_readl(host, DATA);
host->part_buf32 = mci_readl(host, DATA(host->data_offset));
dw_mci_pull_final_bytes(host, buf, cnt);
}
}
......@@ -1173,7 +1199,8 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
buf += len;
cnt -= len;
if (!sg_next(host->sg) || host->part_buf_count == 8) {
mci_writew(host, DATA, host->part_buf);
mci_writew(host, DATA(host->data_offset),
host->part_buf);
host->part_buf_count = 0;
}
}
......@@ -1190,21 +1217,23 @@ static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt)
cnt -= len;
/* push data from aligned buffer into fifo */
for (i = 0; i < items; ++i)
mci_writeq(host, DATA, aligned_buf[i]);
mci_writeq(host, DATA(host->data_offset),
aligned_buf[i]);
}
} else
#endif
{
u64 *pdata = buf;
for (; cnt >= 8; cnt -= 8)
mci_writeq(host, DATA, *pdata++);
mci_writeq(host, DATA(host->data_offset), *pdata++);
buf = pdata;
}
/* put anything remaining in the part_buf */
if (cnt) {
dw_mci_set_part_bytes(host, buf, cnt);
if (!sg_next(host->sg))
mci_writeq(host, DATA, host->part_buf);
mci_writeq(host, DATA(host->data_offset),
host->part_buf);
}
}
......@@ -1219,7 +1248,8 @@ static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt)
int items = len >> 3;
int i;
for (i = 0; i < items; ++i)
aligned_buf[i] = mci_readq(host, DATA);
aligned_buf[i] = mci_readq(host,
DATA(host->data_offset));
/* memcpy from aligned buffer into output buffer */
memcpy(buf, aligned_buf, len);
buf += len;
......@@ -1230,11 +1260,11 @@ static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt)
{
u64 *pdata = buf;
for (; cnt >= 8; cnt -= 8)
*pdata++ = mci_readq(host, DATA);
*pdata++ = mci_readq(host, DATA(host->data_offset));
buf = pdata;
}
if (cnt) {
host->part_buf = mci_readq(host, DATA);
host->part_buf = mci_readq(host, DATA(host->data_offset));
dw_mci_pull_final_bytes(host, buf, cnt);
}
}
......@@ -1406,6 +1436,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
struct dw_mci *host = dev_id;
u32 status, pending;
unsigned int pass_count = 0;
int i;
do {
status = mci_readl(host, RINTSTS);
......@@ -1477,6 +1508,15 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
queue_work(dw_mci_card_workqueue, &host->card_work);
}
/* Handle SDIO Interrupts */
for (i = 0; i < host->num_slots; i++) {
struct dw_mci_slot *slot = host->slot[i];
if (pending & SDMMC_INT_SDIO(i)) {
mci_writel(host, RINTSTS, SDMMC_INT_SDIO(i));
mmc_signal_sdio_irq(slot->mmc);
}
}
} while (pass_count++ < 5);
#ifdef CONFIG_MMC_DW_IDMAC
......@@ -1673,7 +1713,7 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
if (IS_ERR(host->vmmc)) {
printk(KERN_INFO "%s: no vmmc regulator found\n", mmc_hostname(mmc));
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
host->vmmc = NULL;
} else
regulator_enable(host->vmmc);
......@@ -1923,6 +1963,18 @@ static int dw_mci_probe(struct platform_device *pdev)
}
}
/*
* In 2.40a spec, Data offset is changed.
* Need to check the version-id and set data-offset for DATA register.
*/
host->verid = SDMMC_GET_VERID(mci_readl(host, VERID));
dev_info(&pdev->dev, "Version ID is %04x\n", host->verid);
if (host->verid < DW_MMC_240A)
host->data_offset = DATA_OFFSET;
else
host->data_offset = DATA_240A_OFFSET;
/*
* Enable interrupts for command done, data over, data empty, card det,
* receive ready and error such as transmit, receive timeout, crc error
......
......@@ -14,6 +14,8 @@
#ifndef _DW_MMC_H_
#define _DW_MMC_H_
#define DW_MMC_240A 0x240a
#define SDMMC_CTRL 0x000
#define SDMMC_PWREN 0x004
#define SDMMC_CLKDIV 0x008
......@@ -51,7 +53,14 @@
#define SDMMC_IDINTEN 0x090
#define SDMMC_DSCADDR 0x094
#define SDMMC_BUFADDR 0x098
#define SDMMC_DATA 0x100
#define SDMMC_DATA(x) (x)
/*
* Data offset is difference according to Version
* Lower than 2.40a : data register offest is 0x100
*/
#define DATA_OFFSET 0x100
#define DATA_240A_OFFSET 0x200
/* shift bit field */
#define _SBF(f, v) ((v) << (f))
......@@ -82,7 +91,7 @@
#define SDMMC_CTYPE_4BIT BIT(0)
#define SDMMC_CTYPE_1BIT 0
/* Interrupt status & mask register defines */
#define SDMMC_INT_SDIO BIT(16)
#define SDMMC_INT_SDIO(n) BIT(16 + (n))
#define SDMMC_INT_EBE BIT(15)
#define SDMMC_INT_ACD BIT(14)
#define SDMMC_INT_SBE BIT(13)
......@@ -130,6 +139,8 @@
#define SDMMC_IDMAC_ENABLE BIT(7)
#define SDMMC_IDMAC_FB BIT(1)
#define SDMMC_IDMAC_SWRESET BIT(0)
/* Version ID register define */
#define SDMMC_GET_VERID(x) ((x) & 0xFFFF)
/* Register access macros */
#define mci_readl(dev, reg) \
......
......@@ -942,7 +942,7 @@ static int __init imxmci_probe(struct platform_device *pdev)
int ret = 0, irq;
u16 rev_no;
printk(KERN_INFO "i.MX mmc driver\n");
pr_info("i.MX mmc driver\n");
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
......
......@@ -27,6 +27,7 @@
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/dma-mapping.h>
#include <linux/crc7.h>
......
......@@ -466,7 +466,7 @@ static void mmci_get_next_data(struct mmci_host *host, struct mmc_data *data)
struct mmci_host_next *next = &host->next_data;
if (data->host_cookie && data->host_cookie != next->cookie) {
printk(KERN_WARNING "[%s] invalid cookie: data->host_cookie %d"
pr_warning("[%s] invalid cookie: data->host_cookie %d"
" host->next_data.cookie %d\n",
__func__, data->host_cookie, host->next_data.cookie);
data->host_cookie = 0;
......@@ -531,7 +531,7 @@ static void mmci_post_request(struct mmc_host *mmc, struct mmc_request *mrq,
if (chan) {
if (err)
dmaengine_terminate_all(chan);
if (err || data->host_cookie)
if (data->host_cookie)
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, dir);
mrq->data->host_cookie = 0;
......
......@@ -213,7 +213,8 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd)
msmsdcc_writel(host, host->cmd_timeout, MMCIDATATIMER);
msmsdcc_writel(host, (unsigned int)host->curr.xfer_size,
MMCIDATALENGTH);
msmsdcc_writel(host, host->cmd_pio_irqmask, MMCIMASK1);
msmsdcc_writel(host, (msmsdcc_readl(host, MMCIMASK0) &
(~MCI_IRQ_PIO)) | host->cmd_pio_irqmask, MMCIMASK0);
msmsdcc_writel(host, host->cmd_datactrl, MMCIDATACTRL);
if (host->cmd_cmd) {
......@@ -388,7 +389,7 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
host->dma.num_ents, host->dma.dir);
if (n == 0) {
printk(KERN_ERR "%s: Unable to map in all sg elements\n",
pr_err("%s: Unable to map in all sg elements\n",
mmc_hostname(host->mmc));
host->dma.sg = NULL;
host->dma.num_ents = 0;
......@@ -474,7 +475,7 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host,
*c |= MCI_CSPM_MCIABORT;
if (host->curr.cmd != NULL) {
printk(KERN_ERR "%s: Overlapping command requests\n",
pr_err("%s: Overlapping command requests\n",
mmc_hostname(host->mmc));
}
host->curr.cmd = cmd;
......@@ -543,7 +544,9 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data,
msmsdcc_writel(host, host->curr.xfer_size, MMCIDATALENGTH);
msmsdcc_writel(host, pio_irqmask, MMCIMASK1);
msmsdcc_writel(host, (msmsdcc_readl(host, MMCIMASK0) &
(~MCI_IRQ_PIO)) | pio_irqmask, MMCIMASK0);
msmsdcc_writel(host, datactrl, MMCIDATACTRL);
if (cmd) {
......@@ -659,8 +662,13 @@ msmsdcc_pio_irq(int irq, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
uint32_t status;
u32 mci_mask0;
status = msmsdcc_readl(host, MMCISTATUS);
mci_mask0 = msmsdcc_readl(host, MMCIMASK0);
if (((mci_mask0 & status) & MCI_IRQ_PIO) == 0)
return IRQ_NONE;
do {
unsigned long flags;
......@@ -719,10 +727,12 @@ msmsdcc_pio_irq(int irq, void *dev_id)
} while (1);
if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE)
msmsdcc_writel(host, MCI_RXDATAAVLBLMASK, MMCIMASK1);
msmsdcc_writel(host, (mci_mask0 & (~MCI_IRQ_PIO)) |
MCI_RXDATAAVLBLMASK, MMCIMASK0);
if (!host->curr.xfer_remain)
msmsdcc_writel(host, 0, MMCIMASK1);
msmsdcc_writel(host, (mci_mask0 & (~MCI_IRQ_PIO)) | 0,
MMCIMASK0);
return IRQ_HANDLED;
}
......@@ -854,6 +864,8 @@ msmsdcc_irq(int irq, void *dev_id)
do {
status = msmsdcc_readl(host, MMCISTATUS);
status &= msmsdcc_readl(host, MMCIMASK0);
if ((status & (~MCI_IRQ_PIO)) == 0)
break;
msmsdcc_writel(host, status, MMCICLEAR);
if (status & MCI_SDIOINTR)
......@@ -939,7 +951,7 @@ static void msmsdcc_setup_gpio(struct msmsdcc_host *host, bool enable)
struct msm_mmc_gpio_data *curr;
int i, rc = 0;
if (!host->plat->gpio_data && host->gpio_config_status == enable)
if (!host->plat->gpio_data || host->gpio_config_status == enable)
return;
curr = host->plat->gpio_data;
......@@ -1052,10 +1064,19 @@ static void msmsdcc_enable_sdio_irq(struct mmc_host *mmc, int enable)
spin_unlock_irqrestore(&host->lock, flags);
}
static void msmsdcc_init_card(struct mmc_host *mmc, struct mmc_card *card)
{
struct msmsdcc_host *host = mmc_priv(mmc);
if (host->plat->init_card)
host->plat->init_card(card);
}
static const struct mmc_host_ops msmsdcc_ops = {
.request = msmsdcc_request,
.set_ios = msmsdcc_set_ios,
.enable_sdio_irq = msmsdcc_enable_sdio_irq,
.init_card = msmsdcc_init_card,
};
static void
......@@ -1092,7 +1113,7 @@ msmsdcc_platform_status_irq(int irq, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
printk(KERN_DEBUG "%s: %d\n", __func__, irq);
pr_debug("%s: %d\n", __func__, irq);
msmsdcc_check_status((unsigned long) host);
return IRQ_HANDLED;
}
......@@ -1102,7 +1123,7 @@ msmsdcc_status_notify_cb(int card_present, void *dev_id)
{
struct msmsdcc_host *host = dev_id;
printk(KERN_DEBUG "%s: card_present %d\n", mmc_hostname(host->mmc),
pr_debug("%s: card_present %d\n", mmc_hostname(host->mmc),
card_present);
msmsdcc_check_status((unsigned long) host);
}
......@@ -1150,7 +1171,6 @@ msmsdcc_probe(struct platform_device *pdev)
struct msmsdcc_host *host;
struct mmc_host *mmc;
struct resource *cmd_irqres = NULL;
struct resource *pio_irqres = NULL;
struct resource *stat_irqres = NULL;
struct resource *memres = NULL;
struct resource *dmares = NULL;
......@@ -1175,12 +1195,10 @@ msmsdcc_probe(struct platform_device *pdev)
dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
cmd_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
"cmd_irq");
pio_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
"pio_irq");
stat_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
"status_irq");
if (!cmd_irqres || !pio_irqres || !memres) {
if (!cmd_irqres || !memres) {
pr_err("%s: Invalid resource\n", __func__);
return -ENXIO;
}
......@@ -1200,17 +1218,20 @@ msmsdcc_probe(struct platform_device *pdev)
host->plat = plat;
host->mmc = mmc;
host->curr.cmd = NULL;
init_timer(&host->busclk_timer);
host->busclk_timer.data = (unsigned long) host;
host->busclk_timer.function = msmsdcc_busclk_expired;
host->cmdpoll = 1;
host->base = ioremap(memres->start, PAGE_SIZE);
if (!host->base) {
ret = -ENOMEM;
goto out;
goto host_free;
}
host->cmd_irqres = cmd_irqres;
host->pio_irqres = pio_irqres;
host->memres = memres;
host->dmares = dmares;
spin_lock_init(&host->lock);
......@@ -1221,13 +1242,19 @@ msmsdcc_probe(struct platform_device *pdev)
/*
* Setup DMA
*/
msmsdcc_init_dma(host);
if (host->dmares) {
ret = msmsdcc_init_dma(host);
if (ret)
goto ioremap_free;
} else {
host->dma.channel = -1;
}
/* Get our clocks */
host->pclk = clk_get(&pdev->dev, "sdc_pclk");
if (IS_ERR(host->pclk)) {
ret = PTR_ERR(host->pclk);
goto host_free;
goto dma_free;
}
host->clk = clk_get(&pdev->dev, "sdc_clk");
......@@ -1236,17 +1263,17 @@ msmsdcc_probe(struct platform_device *pdev)
goto pclk_put;
}
/* Enable clocks */
ret = msmsdcc_enable_clocks(host);
if (ret)
goto clk_put;
ret = clk_set_rate(host->clk, msmsdcc_fmin);
if (ret) {
pr_err("%s: Clock rate set failed (%d)\n", __func__, ret);
goto clk_disable;
goto clk_put;
}
/* Enable clocks */
ret = msmsdcc_enable_clocks(host);
if (ret)
goto clk_put;
host->pclk_rate = clk_get_rate(host->pclk);
host->clk_rate = clk_get_rate(host->clk);
......@@ -1316,16 +1343,12 @@ msmsdcc_probe(struct platform_device *pdev)
host->eject = !host->oldstat;
}
init_timer(&host->busclk_timer);
host->busclk_timer.data = (unsigned long) host;
host->busclk_timer.function = msmsdcc_busclk_expired;
ret = request_irq(cmd_irqres->start, msmsdcc_irq, IRQF_SHARED,
DRIVER_NAME " (cmd)", host);
if (ret)
goto stat_irq_free;
ret = request_irq(pio_irqres->start, msmsdcc_pio_irq, IRQF_SHARED,
ret = request_irq(cmd_irqres->start, msmsdcc_pio_irq, IRQF_SHARED,
DRIVER_NAME " (pio)", host);
if (ret)
goto cmd_irq_free;
......@@ -1368,6 +1391,13 @@ msmsdcc_probe(struct platform_device *pdev)
clk_put(host->clk);
pclk_put:
clk_put(host->pclk);
dma_free:
if (host->dmares)
dma_free_coherent(NULL, sizeof(struct msmsdcc_nc_dmadata),
host->dma.nc, host->dma.nc_busaddr);
ioremap_free:
tasklet_kill(&host->dma_tlet);
iounmap(host->base);
host_free:
mmc_free_host(mmc);
out:
......
......@@ -140,6 +140,11 @@
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK)
#define MCI_IRQ_PIO \
(MCI_RXDATAAVLBLMASK | MCI_TXDATAAVLBLMASK | MCI_RXFIFOEMPTYMASK | \
MCI_TXFIFOEMPTYMASK | MCI_RXFIFOFULLMASK | MCI_TXFIFOFULLMASK | \
MCI_RXFIFOHALFFULLMASK | MCI_TXFIFOHALFEMPTYMASK | \
MCI_RXACTIVEMASK | MCI_TXACTIVEMASK)
/*
* The size of the FIFO in bytes.
*/
......@@ -202,7 +207,6 @@ struct msmsdcc_stats {
struct msmsdcc_host {
struct resource *cmd_irqres;
struct resource *pio_irqres;
struct resource *memres;
struct resource *dmares;
void __iomem *base;
......
This diff is collapsed.
......@@ -842,7 +842,7 @@ static int mxcmci_probe(struct platform_device *pdev)
int ret = 0, irq;
dma_cap_mask_t mask;
printk(KERN_INFO "i.MX SDHC driver\n");
pr_info("i.MX SDHC driver\n");
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
......
......@@ -37,6 +37,7 @@
#include <linux/mmc/sdio.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
#include <mach/mxs.h>
#include <mach/common.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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