Skip to content

Commit

Permalink
Merge tag 'mmc-updates-for-3.12-rc1' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/cjb/mmc

Pull MMC updates from Chris Ball:
 "MMC highlights for 3.12:

  Core:
   - Support Allocation Units 8MB-64MB in SD3.0, previous max was 4MB.
   - The slot-gpio helper can now handle GPIO debouncing card-detect.
   - Read supported voltages from DT "voltage-ranges" property.

  Drivers:
   - dw_mmc: Add support for ARC architecture, and support exynos5420.
   - mmc_spi: Support CD/RO GPIOs.
   - sh_mobile_sdhi: Add compatibility for more Renesas SoCs.
   - sh_mmcif: Add DT support for DMA channels"

* tag 'mmc-updates-for-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (50 commits)
  Revert "mmc: tmio-mmc: Remove .set_pwr() callback from platform data"
  mmc: dw_mmc: Add support for ARC
  mmc: sdhci-s3c: initialize host->quirks2 for using quirks2
  mmc: sdhci-s3c: fix the wrong register value, when clock is disabled
  mmc: esdhc: add support to get voltage from device-tree
  mmc: sdhci: get voltage from sdhc host
  mmc: core: parse voltage from device-tree
  mmc: omap_hsmmc: use the generic config for omap2plus devices
  mmc: omap_hsmmc: clear status flags before starting a new command
  mmc: dw_mmc: exynos: Add a new compatible string for exynos5420
  mmc: sh_mmcif: revision-specific CLK_CTRL2 handling
  mmc: sh_mmcif: revision-specific Command Completion Signal handling
  mmc: sh_mmcif: add support for Device Tree DMA bindings
  mmc: sh_mmcif: move header include from header into .c
  mmc: SDHI: add DT compatibility strings for further SoCs
  mmc: dw_mmc-pci: enable bus-mastering mode
  mmc: dw_mmc-pci: get resources from a proper BAR
  mmc: tmio-mmc: Remove .set_pwr() callback from platform data
  mmc: tmio-mmc: Remove .get_cd() callback from platform data
  mmc: sh_mobile_sdhi: Remove .set_pwr() callback from platform data
  ...
  • Loading branch information
Linus Torvalds committed Sep 10, 2013
2 parents 7426d62 + 9d731e7 commit d0048f0
Show file tree
Hide file tree
Showing 42 changed files with 336 additions and 335 deletions.
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/mmc/fsl-esdhc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Optional properties:
"bus-width = <1>" property.
- sdhci,auto-cmd12: specifies that a controller can only handle auto
CMD12.
- voltage-ranges : two cells are required, first cell specifies minimum
slot voltage (mV), second cell specifies maximum slot voltage (mV).
Several ranges could be specified.

Example:

Expand All @@ -29,4 +32,5 @@ sdhci@2e000 {
interrupt-parent = <&ipic>;
/* Filled in by U-Boot */
clock-frequency = <0>;
voltage-ranges = <3300 3300>;
};
57 changes: 5 additions & 52 deletions arch/arm/mach-ep93xx/vision_ep9307.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,62 +224,15 @@ static struct ep93xx_spi_chip_ops vision_spi_flash_hw = {
#define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0)
#define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15

static struct gpio vision_spi_mmc_gpios[] = {
{ VISION_SPI_MMC_WP, GPIOF_DIR_IN, "mmc_spi:wp" },
{ VISION_SPI_MMC_CD, GPIOF_DIR_IN, "mmc_spi:cd" },
};

static int vision_spi_mmc_init(struct device *pdev,
irqreturn_t (*func)(int, void *), void *pdata)
{
int err;

err = gpio_request_array(vision_spi_mmc_gpios,
ARRAY_SIZE(vision_spi_mmc_gpios));
if (err)
return err;

err = gpio_set_debounce(VISION_SPI_MMC_CD, 1);
if (err)
goto exit_err;

err = request_irq(gpio_to_irq(VISION_SPI_MMC_CD), func,
IRQ_TYPE_EDGE_BOTH, "mmc_spi:cd", pdata);
if (err)
goto exit_err;

return 0;

exit_err:
gpio_free_array(vision_spi_mmc_gpios, ARRAY_SIZE(vision_spi_mmc_gpios));
return err;

}

static void vision_spi_mmc_exit(struct device *pdev, void *pdata)
{
free_irq(gpio_to_irq(VISION_SPI_MMC_CD), pdata);
gpio_free_array(vision_spi_mmc_gpios, ARRAY_SIZE(vision_spi_mmc_gpios));
}

static int vision_spi_mmc_get_ro(struct device *pdev)
{
return !!gpio_get_value(VISION_SPI_MMC_WP);
}

static int vision_spi_mmc_get_cd(struct device *pdev)
{
return !gpio_get_value(VISION_SPI_MMC_CD);
}

static struct mmc_spi_platform_data vision_spi_mmc_data = {
.init = vision_spi_mmc_init,
.exit = vision_spi_mmc_exit,
.get_ro = vision_spi_mmc_get_ro,
.get_cd = vision_spi_mmc_get_cd,
.detect_delay = 100,
.powerup_msecs = 100,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
.cd_gpio = VISION_SPI_MMC_CD,
.cd_debounce = 1,
.ro_gpio = VISION_SPI_MMC_WP,
.caps2 = MMC_CAP2_RO_ACTIVE_HIGH,
};

static int vision_spi_mmc_hw_setup(struct spi_device *spi)
Expand Down
89 changes: 8 additions & 81 deletions arch/sh/boards/mach-ecovec24/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,37 +600,13 @@ static struct platform_device sdhi0_power = {
},
};

static void sdhi0_set_pwr(struct platform_device *pdev, int state)
{
static int power_gpio = -EINVAL;

if (power_gpio < 0) {
int ret = gpio_request(GPIO_PTB6, NULL);
if (!ret) {
power_gpio = GPIO_PTB6;
gpio_direction_output(power_gpio, 0);
}
}

/*
* Toggle the GPIO regardless, whether we managed to grab it above or
* the fixed regulator driver did.
*/
gpio_set_value(GPIO_PTB6, state);
}

static int sdhi0_get_cd(struct platform_device *pdev)
{
return !gpio_get_value(GPIO_PTY7);
}

static struct sh_mobile_sdhi_info sdhi0_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
.set_pwr = sdhi0_set_pwr,
.tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
MMC_CAP_NEEDS_POLL,
.get_cd = sdhi0_get_cd,
.tmio_flags = TMIO_MMC_USE_GPIO_CD,
.cd_gpio = GPIO_PTY7,
};

static struct resource sdhi0_resources[] = {
Expand All @@ -656,39 +632,15 @@ static struct platform_device sdhi0_device = {
},
};

static void cn12_set_pwr(struct platform_device *pdev, int state)
{
static int power_gpio = -EINVAL;

if (power_gpio < 0) {
int ret = gpio_request(GPIO_PTB7, NULL);
if (!ret) {
power_gpio = GPIO_PTB7;
gpio_direction_output(power_gpio, 0);
}
}

/*
* Toggle the GPIO regardless, whether we managed to grab it above or
* the fixed regulator driver did.
*/
gpio_set_value(GPIO_PTB7, state);
}

#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
/* SDHI1 */
static int sdhi1_get_cd(struct platform_device *pdev)
{
return !gpio_get_value(GPIO_PTW7);
}

static struct sh_mobile_sdhi_info sdhi1_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
.tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD |
MMC_CAP_NEEDS_POLL,
.set_pwr = cn12_set_pwr,
.get_cd = sdhi1_get_cd,
.tmio_flags = TMIO_MMC_USE_GPIO_CD,
.cd_gpio = GPIO_PTW7,
};

static struct resource sdhi1_resources[] = {
Expand Down Expand Up @@ -718,27 +670,19 @@ static struct platform_device sdhi1_device = {
#else

/* MMC SPI */
static int mmc_spi_get_ro(struct device *dev)
{
return gpio_get_value(GPIO_PTY6);
}

static int mmc_spi_get_cd(struct device *dev)
{
return !gpio_get_value(GPIO_PTY7);
}

static void mmc_spi_setpower(struct device *dev, unsigned int maskval)
{
gpio_set_value(GPIO_PTB6, maskval ? 1 : 0);
}

static struct mmc_spi_platform_data mmc_spi_info = {
.get_ro = mmc_spi_get_ro,
.get_cd = mmc_spi_get_cd,
.caps = MMC_CAP_NEEDS_POLL,
.caps2 = MMC_CAP2_RO_ACTIVE_HIGH,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */
.setpower = mmc_spi_setpower,
.flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
.cd_gpio = GPIO_PTY7,
.ro_gpio = GPIO_PTY6,
};

static struct spi_board_info spi_bus[] = {
Expand Down Expand Up @@ -998,11 +942,6 @@ static struct platform_device vou_device = {

#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
/* SH_MMCIF */
static void mmcif_down_pwr(struct platform_device *pdev)
{
cn12_set_pwr(pdev, 0);
}

static struct resource sh_mmcif_resources[] = {
[0] = {
.name = "SH_MMCIF",
Expand All @@ -1023,8 +962,6 @@ static struct resource sh_mmcif_resources[] = {
};

static struct sh_mmcif_plat_data sh_mmcif_plat = {
.set_pwr = cn12_set_pwr,
.down_pwr = mmcif_down_pwr,
.sup_pclk = 0, /* SH7724: Max Pclk/2 */
.caps = MMC_CAP_4_BIT_DATA |
MMC_CAP_8_BIT_DATA |
Expand Down Expand Up @@ -1341,10 +1278,6 @@ static int __init arch_setup(void)
gpio_direction_input(GPIO_PTR6);

/* SD-card slot CN11 */
/* Card-detect, used on CN11, either with SDHI0 or with SPI */
gpio_request(GPIO_PTY7, NULL);
gpio_direction_input(GPIO_PTY7);

#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
/* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
gpio_request(GPIO_FN_SDHI0WP, NULL);
Expand All @@ -1363,8 +1296,6 @@ static int __init arch_setup(void)
gpio_direction_output(GPIO_PTM4, 1); /* active low CS */
gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */
gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */
gpio_request(GPIO_PTY6, NULL); /* write protect */
gpio_direction_input(GPIO_PTY6);

spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus));
#endif
Expand Down Expand Up @@ -1394,10 +1325,6 @@ static int __init arch_setup(void)
gpio_request(GPIO_FN_SDHI1D1, NULL);
gpio_request(GPIO_FN_SDHI1D0, NULL);

/* Card-detect, used on CN12 with SDHI1 */
gpio_request(GPIO_PTW7, NULL);
gpio_direction_input(GPIO_PTW7);

cn12_enabled = true;
#endif

Expand Down
47 changes: 43 additions & 4 deletions drivers/mmc/card/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error,
* Otherwise we don't understand what happened, so abort.
*/
static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
struct mmc_blk_request *brq, int *ecc_err)
struct mmc_blk_request *brq, int *ecc_err, int *gen_err)
{
bool prev_cmd_status_valid = true;
u32 status, stop_status = 0;
Expand Down Expand Up @@ -850,6 +850,16 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
(brq->cmd.resp[0] & R1_CARD_ECC_FAILED))
*ecc_err = 1;

/* Flag General errors */
if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ)
if ((status & R1_ERROR) ||
(brq->stop.resp[0] & R1_ERROR)) {
pr_err("%s: %s: general error sending stop or status command, stop cmd response %#x, card status %#x\n",
req->rq_disk->disk_name, __func__,
brq->stop.resp[0], status);
*gen_err = 1;
}

/*
* Check the current card state. If it is in some data transfer
* mode, tell it to stop (and hopefully transition back to TRAN.)
Expand All @@ -869,6 +879,13 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
return ERR_ABORT;
if (stop_status & R1_CARD_ECC_FAILED)
*ecc_err = 1;
if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ)
if (stop_status & R1_ERROR) {
pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n",
req->rq_disk->disk_name, __func__,
stop_status);
*gen_err = 1;
}
}

/* Check for set block count errors */
Expand Down Expand Up @@ -1097,7 +1114,7 @@ static int mmc_blk_err_check(struct mmc_card *card,
mmc_active);
struct mmc_blk_request *brq = &mq_mrq->brq;
struct request *req = mq_mrq->req;
int ecc_err = 0;
int ecc_err = 0, gen_err = 0;

/*
* sbc.error indicates a problem with the set block count
Expand All @@ -1111,7 +1128,7 @@ static int mmc_blk_err_check(struct mmc_card *card,
*/
if (brq->sbc.error || brq->cmd.error || brq->stop.error ||
brq->data.error) {
switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err)) {
switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err, &gen_err)) {
case ERR_RETRY:
return MMC_BLK_RETRY;
case ERR_ABORT:
Expand Down Expand Up @@ -1143,6 +1160,14 @@ static int mmc_blk_err_check(struct mmc_card *card,
u32 status;
unsigned long timeout;

/* Check stop command response */
if (brq->stop.resp[0] & R1_ERROR) {
pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n",
req->rq_disk->disk_name, __func__,
brq->stop.resp[0]);
gen_err = 1;
}

timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
do {
int err = get_card_status(card, &status, 5);
Expand All @@ -1152,6 +1177,13 @@ static int mmc_blk_err_check(struct mmc_card *card,
return MMC_BLK_CMD_ERR;
}

if (status & R1_ERROR) {
pr_err("%s: %s: general error sending status command, card status %#x\n",
req->rq_disk->disk_name, __func__,
status);
gen_err = 1;
}

/* Timeout if the device never becomes ready for data
* and never leaves the program state.
*/
Expand All @@ -1171,6 +1203,13 @@ static int mmc_blk_err_check(struct mmc_card *card,
(R1_CURRENT_STATE(status) == R1_STATE_PRG));
}

/* if general error occurs, retry the write operation. */
if (gen_err) {
pr_warn("%s: retrying write for general error\n",
req->rq_disk->disk_name);
return MMC_BLK_RETRY;
}

if (brq->data.error) {
pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
req->rq_disk->disk_name, brq->data.error,
Expand Down Expand Up @@ -2191,10 +2230,10 @@ static void mmc_blk_remove_req(struct mmc_blk_data *md)
* is freeing the queue that stops new requests
* from being accepted.
*/
card = md->queue.card;
mmc_cleanup_queue(&md->queue);
if (md->flags & MMC_BLK_PACKED_CMD)
mmc_packed_clean(&md->queue);
card = md->queue.card;
if (md->disk->flags & GENHD_FL_UP) {
device_remove_file(disk_to_dev(md->disk), &md->force_ro);
if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
Expand Down
14 changes: 4 additions & 10 deletions drivers/mmc/card/mmc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2849,18 +2849,12 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf,
struct seq_file *sf = (struct seq_file *)file->private_data;
struct mmc_card *card = (struct mmc_card *)sf->private;
struct mmc_test_card *test;
char lbuf[12];
long testcase;
int ret;

if (count >= sizeof(lbuf))
return -EINVAL;

if (copy_from_user(lbuf, buf, count))
return -EFAULT;
lbuf[count] = '\0';

if (strict_strtol(lbuf, 10, &testcase))
return -EINVAL;
ret = kstrtol_from_user(buf, count, 10, &testcase);
if (ret)
return ret;

test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL);
if (!test)
Expand Down
Loading

0 comments on commit d0048f0

Please sign in to comment.