MMC core:
- Further fix thread wake-up for requests - Use a bounce buffer to fix DMA issue for SSR register read MMC host: - sdhci: Fix a regression for runtime PM - sdhci-cadence: Add a proper SoC specific DT compatible -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYWjTHAAoJEP4mhCVzWIwpQGIP/iYBC90rFPhoq8ba8fdngFuD RBuuw+yW+ueCcFuogrm7eSHnOS/FWWl4iYDnX6CJOuto4HYh+rexzLT3YlA2wbid jEFi59lVA3xDEP9hpBGavp1IJV7XVh4uCH4NsVbceQ9MoIpJwFkUxDY5zMdPmKG6 Pt4jaXsoxhcAYro5ORH5q4BzX4bfluUKSYsgBBUsQMxhOQy02CKgvfJ3/aR7+Tqg 3f/3tQVOXMmI+NhLC5y++VoxL5YoTos6WHgIoA7kuXPvVkVV89jxvLWZKzbsNVHC iZ6DNdaMwmSSK5BwfSzSXReAA4zce+yw55O0j/dTc+EKdJJ7/oW3y/fpda6lrGy7 dRG4RXumBrVUqOAobx6J/KibM94gIsdaOZ4sCptn48x1NeRafsGc4fq+76tpIvHe 16dn9xIqcz4hZU4GsQSgNpo4DFJCE6K4yuYgtuKP+qvUGBFyRoGzwo5mf6hxJovT YviqLmqsOjaZ6F202HMaJtYgSQBv/lScL9vp40H7T5yrIbR2mx4ww2FyNWLWXqRY 4IJ6F8gwu1xUafCi5LUNk+pU1J1bjIKTSeR3enRIpudEzmy9/oroQDOtLh+1T4Z6 CVkdxmgd6jrs7sK9pPURKhDuMgZH7hUAuFxg3JMRMEdCOzsTwuAHnDq0DtrjSOC9 hYw+dqDJHut0To290N5r =PDPZ -----END PGP SIGNATURE----- Merge tag 'mmc-v4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc Pull MMC fixes from Ulf Hansson: "MMC core: - further fix thread wake-up for requests - use a bounce buffer to fix DMA issue for SSR register read MMC host: - sdhci: Fix a regression for runtime PM - sdhci-cadence: Add a proper SoC specific DT compatible" * tag 'mmc-v4.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sd: Meet alignment requirements for raw_ssr DMA mmc: core: Further fix thread wake-up mmc: sdhci: Fix to handle MMC_POWER_UNDEFINED mmc: sdhci-cadence: add Socionext UniPhier specific compatible string
This commit is contained in:
commit
8d86cf8879
5 changed files with 39 additions and 25 deletions
|
@ -1,7 +1,9 @@
|
|||
* Cadence SD/SDIO/eMMC Host Controller
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "cdns,sd4hc".
|
||||
- compatible: should be one of the following:
|
||||
"cdns,sd4hc" - default of the IP
|
||||
"socionext,uniphier-sd4hc" - for Socionext UniPhier SoCs
|
||||
- reg: offset and length of the register set for the device.
|
||||
- interrupts: a single interrupt specifier.
|
||||
- clocks: phandle to the input clock.
|
||||
|
@ -19,7 +21,7 @@ if supported. See mmc.txt for details.
|
|||
|
||||
Example:
|
||||
emmc: sdhci@5a000000 {
|
||||
compatible = "cdns,sd4hc";
|
||||
compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc";
|
||||
reg = <0x5a000000 0x400>;
|
||||
interrupts = <0 78 4>;
|
||||
clocks = <&clk 4>;
|
||||
|
|
|
@ -496,8 +496,7 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
|
|||
* Returns enum mmc_blk_status after checking errors.
|
||||
*/
|
||||
static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host,
|
||||
struct mmc_request *mrq,
|
||||
struct mmc_async_req *next_req)
|
||||
struct mmc_request *mrq)
|
||||
{
|
||||
struct mmc_command *cmd;
|
||||
struct mmc_context_info *context_info = &host->context_info;
|
||||
|
@ -507,7 +506,7 @@ static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host,
|
|||
wait_event_interruptible(context_info->wait,
|
||||
(context_info->is_done_rcv ||
|
||||
context_info->is_new_req));
|
||||
context_info->is_waiting_last_req = false;
|
||||
|
||||
if (context_info->is_done_rcv) {
|
||||
context_info->is_done_rcv = false;
|
||||
cmd = mrq->cmd;
|
||||
|
@ -527,10 +526,9 @@ static enum mmc_blk_status mmc_wait_for_data_req_done(struct mmc_host *host,
|
|||
__mmc_start_request(host, mrq);
|
||||
continue; /* wait for done/new event again */
|
||||
}
|
||||
} else if (context_info->is_new_req) {
|
||||
if (!next_req)
|
||||
return MMC_BLK_NEW_REQUEST;
|
||||
}
|
||||
|
||||
return MMC_BLK_NEW_REQUEST;
|
||||
}
|
||||
mmc_retune_release(host);
|
||||
return status;
|
||||
|
@ -660,7 +658,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
|
|||
mmc_pre_req(host, areq->mrq);
|
||||
|
||||
if (host->areq) {
|
||||
status = mmc_wait_for_data_req_done(host, host->areq->mrq, areq);
|
||||
status = mmc_wait_for_data_req_done(host, host->areq->mrq);
|
||||
if (status == MMC_BLK_NEW_REQUEST) {
|
||||
if (ret_stat)
|
||||
*ret_stat = status;
|
||||
|
|
|
@ -223,6 +223,7 @@ static int mmc_decode_scr(struct mmc_card *card)
|
|||
static int mmc_read_ssr(struct mmc_card *card)
|
||||
{
|
||||
unsigned int au, es, et, eo;
|
||||
u32 *raw_ssr;
|
||||
int i;
|
||||
|
||||
if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
|
||||
|
@ -231,14 +232,21 @@ static int mmc_read_ssr(struct mmc_card *card)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (mmc_app_sd_status(card, card->raw_ssr)) {
|
||||
raw_ssr = kmalloc(sizeof(card->raw_ssr), GFP_KERNEL);
|
||||
if (!raw_ssr)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mmc_app_sd_status(card, raw_ssr)) {
|
||||
pr_warn("%s: problem reading SD Status register\n",
|
||||
mmc_hostname(card->host));
|
||||
kfree(raw_ssr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
card->raw_ssr[i] = be32_to_cpu(card->raw_ssr[i]);
|
||||
card->raw_ssr[i] = be32_to_cpu(raw_ssr[i]);
|
||||
|
||||
kfree(raw_ssr);
|
||||
|
||||
/*
|
||||
* UNSTUFF_BITS only works with four u32s so we have to offset the
|
||||
|
|
|
@ -262,6 +262,7 @@ disable_clk:
|
|||
}
|
||||
|
||||
static const struct of_device_id sdhci_cdns_match[] = {
|
||||
{ .compatible = "socionext,uniphier-sd4hc" },
|
||||
{ .compatible = "cdns,sd4hc" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
|
|
@ -1576,6 +1576,9 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
unsigned long flags;
|
||||
u8 ctrl;
|
||||
|
||||
if (ios->power_mode == MMC_POWER_UNDEFINED)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
if (host->flags & SDHCI_DEVICE_DEAD) {
|
||||
|
@ -2938,23 +2941,25 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
|
|||
|
||||
sdhci_init(host, 0);
|
||||
|
||||
/* Force clock and power re-program */
|
||||
host->pwr = 0;
|
||||
host->clock = 0;
|
||||
mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
|
||||
mmc->ops->set_ios(mmc, &mmc->ios);
|
||||
if (mmc->ios.power_mode != MMC_POWER_UNDEFINED) {
|
||||
/* Force clock and power re-program */
|
||||
host->pwr = 0;
|
||||
host->clock = 0;
|
||||
mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios);
|
||||
mmc->ops->set_ios(mmc, &mmc->ios);
|
||||
|
||||
if ((host_flags & SDHCI_PV_ENABLED) &&
|
||||
!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
sdhci_enable_preset_value(host, true);
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
if ((host_flags & SDHCI_PV_ENABLED) &&
|
||||
!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) {
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
sdhci_enable_preset_value(host, true);
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
if ((mmc->caps2 & MMC_CAP2_HS400_ES) &&
|
||||
mmc->ops->hs400_enhanced_strobe)
|
||||
mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios);
|
||||
}
|
||||
|
||||
if ((mmc->caps2 & MMC_CAP2_HS400_ES) &&
|
||||
mmc->ops->hs400_enhanced_strobe)
|
||||
mmc->ops->hs400_enhanced_strobe(mmc, &mmc->ios);
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
host->runtime_suspended = false;
|
||||
|
|
Loading…
Reference in a new issue