Commit 91f152e7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson:
 "Here's a couple of MMC and MEMSTICK fixes:

  MMC host:
   - sdhci: Fix SDIO IRQ thread deadlock
   - sdhci-tegra: Fix a warning message
   - sdhci_am654: Fix SLOTTYPE write
   - meson-gx: Fix IRQ ack
   - tmio: Fix SCC error handling to avoid false positive CRC error

  MEMSTICK core:
   - mspro_block: Fix returning a correct error code"

* tag 'mmc-v5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci_am654: Fix SLOTTYPE write
  mmc: sdhci: Fix SDIO IRQ thread deadlock
  mmc: meson-gx: fix irq ack
  mmc: tmio: fix SCC error handling to avoid false positive CRC error
  mmc: tegra: Fix a warning message
  memstick: mspro_block: Fix an error code in mspro_block_issue_req()
parents a373ec23 73979931
...@@ -694,13 +694,13 @@ static void h_mspro_block_setup_cmd(struct memstick_dev *card, u64 offset, ...@@ -694,13 +694,13 @@ static void h_mspro_block_setup_cmd(struct memstick_dev *card, u64 offset,
/*** Data transfer ***/ /*** Data transfer ***/
static int mspro_block_issue_req(struct memstick_dev *card, bool chunk) static int mspro_block_issue_req(struct memstick_dev *card)
{ {
struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_block_data *msb = memstick_get_drvdata(card);
u64 t_off; u64 t_off;
unsigned int count; unsigned int count;
while (chunk) { while (true) {
msb->current_page = 0; msb->current_page = 0;
msb->current_seg = 0; msb->current_seg = 0;
msb->seg_count = blk_rq_map_sg(msb->block_req->q, msb->seg_count = blk_rq_map_sg(msb->block_req->q,
...@@ -709,6 +709,7 @@ static int mspro_block_issue_req(struct memstick_dev *card, bool chunk) ...@@ -709,6 +709,7 @@ static int mspro_block_issue_req(struct memstick_dev *card, bool chunk)
if (!msb->seg_count) { if (!msb->seg_count) {
unsigned int bytes = blk_rq_cur_bytes(msb->block_req); unsigned int bytes = blk_rq_cur_bytes(msb->block_req);
bool chunk;
chunk = blk_update_request(msb->block_req, chunk = blk_update_request(msb->block_req,
BLK_STS_RESOURCE, BLK_STS_RESOURCE,
...@@ -718,7 +719,7 @@ static int mspro_block_issue_req(struct memstick_dev *card, bool chunk) ...@@ -718,7 +719,7 @@ static int mspro_block_issue_req(struct memstick_dev *card, bool chunk)
__blk_mq_end_request(msb->block_req, __blk_mq_end_request(msb->block_req,
BLK_STS_RESOURCE); BLK_STS_RESOURCE);
msb->block_req = NULL; msb->block_req = NULL;
break; return -EAGAIN;
} }
t_off = blk_rq_pos(msb->block_req); t_off = blk_rq_pos(msb->block_req);
...@@ -735,8 +736,6 @@ static int mspro_block_issue_req(struct memstick_dev *card, bool chunk) ...@@ -735,8 +736,6 @@ static int mspro_block_issue_req(struct memstick_dev *card, bool chunk)
memstick_new_req(card->host); memstick_new_req(card->host);
return 0; return 0;
} }
return 1;
} }
static int mspro_block_complete_req(struct memstick_dev *card, int error) static int mspro_block_complete_req(struct memstick_dev *card, int error)
...@@ -779,7 +778,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error) ...@@ -779,7 +778,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
chunk = blk_update_request(msb->block_req, chunk = blk_update_request(msb->block_req,
errno_to_blk_status(error), t_len); errno_to_blk_status(error), t_len);
if (chunk) { if (chunk) {
error = mspro_block_issue_req(card, chunk); error = mspro_block_issue_req(card);
if (!error) if (!error)
goto out; goto out;
} else { } else {
...@@ -849,7 +848,7 @@ static blk_status_t mspro_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -849,7 +848,7 @@ static blk_status_t mspro_queue_rq(struct blk_mq_hw_ctx *hctx,
msb->block_req = bd->rq; msb->block_req = bd->rq;
blk_mq_start_request(bd->rq); blk_mq_start_request(bd->rq);
if (mspro_block_issue_req(card, true)) if (mspro_block_issue_req(card))
msb->block_req = NULL; msb->block_req = NULL;
spin_unlock_irq(&msb->q_lock); spin_unlock_irq(&msb->q_lock);
......
...@@ -859,6 +859,9 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) ...@@ -859,6 +859,9 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
if (WARN_ON(!host) || WARN_ON(!host->cmd)) if (WARN_ON(!host) || WARN_ON(!host->cmd))
return IRQ_NONE; return IRQ_NONE;
/* ack all raised interrupts */
writel(status, host->regs + SD_EMMC_STATUS);
cmd = host->cmd; cmd = host->cmd;
data = cmd->data; data = cmd->data;
cmd->error = 0; cmd->error = 0;
...@@ -905,9 +908,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) ...@@ -905,9 +908,6 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
if (ret == IRQ_HANDLED) if (ret == IRQ_HANDLED)
meson_mmc_request_done(host->mmc, cmd->mrq); meson_mmc_request_done(host->mmc, cmd->mrq);
/* ack all raised interrupts */
writel(status, host->regs + SD_EMMC_STATUS);
return ret; return ret;
} }
......
...@@ -865,7 +865,7 @@ static void tegra_sdhci_tap_correction(struct sdhci_host *host, u8 thd_up, ...@@ -865,7 +865,7 @@ static void tegra_sdhci_tap_correction(struct sdhci_host *host, u8 thd_up,
} }
if (!first_fail) { if (!first_fail) {
WARN_ON("no edge detected, continue with hw tuned delay.\n"); WARN(1, "no edge detected, continue with hw tuned delay.\n");
} else if (first_pass) { } else if (first_pass) {
/* set tap location at fixed tap relative to the first edge */ /* set tap location at fixed tap relative to the first edge */
edge1 = first_fail_tap + (first_pass_tap - first_fail_tap) / 2; edge1 = first_fail_tap + (first_pass_tap - first_fail_tap) / 2;
......
...@@ -2133,6 +2133,17 @@ void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) ...@@ -2133,6 +2133,17 @@ void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
} }
EXPORT_SYMBOL_GPL(sdhci_enable_sdio_irq); EXPORT_SYMBOL_GPL(sdhci_enable_sdio_irq);
static void sdhci_ack_sdio_irq(struct mmc_host *mmc)
{
struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
sdhci_enable_sdio_irq_nolock(host, true);
spin_unlock_irqrestore(&host->lock, flags);
}
int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
struct mmc_ios *ios) struct mmc_ios *ios)
{ {
...@@ -2581,6 +2592,7 @@ static const struct mmc_host_ops sdhci_ops = { ...@@ -2581,6 +2592,7 @@ static const struct mmc_host_ops sdhci_ops = {
.get_ro = sdhci_get_ro, .get_ro = sdhci_get_ro,
.hw_reset = sdhci_hw_reset, .hw_reset = sdhci_hw_reset,
.enable_sdio_irq = sdhci_enable_sdio_irq, .enable_sdio_irq = sdhci_enable_sdio_irq,
.ack_sdio_irq = sdhci_ack_sdio_irq,
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch, .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
.prepare_hs400_tuning = sdhci_prepare_hs400_tuning, .prepare_hs400_tuning = sdhci_prepare_hs400_tuning,
.execute_tuning = sdhci_execute_tuning, .execute_tuning = sdhci_execute_tuning,
...@@ -3083,8 +3095,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -3083,8 +3095,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if ((intmask & SDHCI_INT_CARD_INT) && if ((intmask & SDHCI_INT_CARD_INT) &&
(host->ier & SDHCI_INT_CARD_INT)) { (host->ier & SDHCI_INT_CARD_INT)) {
sdhci_enable_sdio_irq_nolock(host, false); sdhci_enable_sdio_irq_nolock(host, false);
host->thread_isr |= SDHCI_INT_CARD_INT; sdio_signal_irq(host->mmc);
result = IRQ_WAKE_THREAD;
} }
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
...@@ -3156,15 +3167,6 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) ...@@ -3156,15 +3167,6 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id)
mmc_detect_change(mmc, msecs_to_jiffies(200)); mmc_detect_change(mmc, msecs_to_jiffies(200));
} }
if (isr & SDHCI_INT_CARD_INT) {
sdio_run_irqs(host->mmc);
spin_lock_irqsave(&host->lock, flags);
if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
sdhci_enable_sdio_irq_nolock(host, true);
spin_unlock_irqrestore(&host->lock, flags);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -231,7 +231,7 @@ static int sdhci_am654_init(struct sdhci_host *host) ...@@ -231,7 +231,7 @@ static int sdhci_am654_init(struct sdhci_host *host)
ctl_cfg_2 = SLOTTYPE_EMBEDDED; ctl_cfg_2 = SLOTTYPE_EMBEDDED;
regmap_update_bits(sdhci_am654->base, CTL_CFG_2, regmap_update_bits(sdhci_am654->base, CTL_CFG_2,
ctl_cfg_2, SLOTTYPE_MASK); SLOTTYPE_MASK, ctl_cfg_2);
return sdhci_add_host(host); return sdhci_add_host(host);
} }
......
...@@ -842,8 +842,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) ...@@ -842,8 +842,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
if (mrq->cmd->error || (mrq->data && mrq->data->error)) if (mrq->cmd->error || (mrq->data && mrq->data->error))
tmio_mmc_abort_dma(host); tmio_mmc_abort_dma(host);
/* SCC error means retune, but executed command was still successful */
if (host->check_scc_error && host->check_scc_error(host)) if (host->check_scc_error && host->check_scc_error(host))
mrq->cmd->error = -EILSEQ; mmc_retune_needed(host->mmc);
/* If SET_BLOCK_COUNT, continue with main command */ /* If SET_BLOCK_COUNT, continue with main command */
if (host->mrq && !mrq->cmd->error) { if (host->mrq && !mrq->cmd->error) {
......
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