mmc: sdhci: Use sdhci-caps-mask and sdhci-caps to change the caps read during __sdhci_read_caps
The sdhci capabilities register can be incorrect. The sdhci-caps-mask and sdhci-caps dt properties specify which bits of the register are incorrect and what their values should be. This patch makes the sdhci driver use those properties to correct the caps during __sdhci_read_caps. During __sdhci_read_caps Use the sdhci-caps-mask property to turn off the incorrect bits of the sdhci register after reading them. Use the sdhci-caps to turn on bits after using sdhci-caps-mask to turn off the incorrect ones. Signed-off-by: Zach Brown <zach.brown@ni.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
parent
426ad97523
commit
92e0c44b92
@ -22,6 +22,7 @@
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/leds.h>
|
||||
|
||||
@ -3007,6 +3008,8 @@ static int sdhci_set_dma_mask(struct sdhci_host *host)
|
||||
void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 *caps1)
|
||||
{
|
||||
u16 v;
|
||||
u64 dt_caps_mask = 0;
|
||||
u64 dt_caps = 0;
|
||||
|
||||
if (host->read_caps)
|
||||
return;
|
||||
@ -3021,18 +3024,35 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 *caps1)
|
||||
|
||||
sdhci_do_reset(host, SDHCI_RESET_ALL);
|
||||
|
||||
of_property_read_u64(mmc_dev(host->mmc)->of_node,
|
||||
"sdhci-caps-mask", &dt_caps_mask);
|
||||
of_property_read_u64(mmc_dev(host->mmc)->of_node,
|
||||
"sdhci-caps", &dt_caps);
|
||||
|
||||
v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT;
|
||||
|
||||
if (host->quirks & SDHCI_QUIRK_MISSING_CAPS)
|
||||
return;
|
||||
|
||||
host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||
if (caps) {
|
||||
host->caps = *caps;
|
||||
} else {
|
||||
host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||
host->caps &= ~lower_32_bits(dt_caps_mask);
|
||||
host->caps |= lower_32_bits(dt_caps);
|
||||
}
|
||||
|
||||
if (host->version < SDHCI_SPEC_300)
|
||||
return;
|
||||
|
||||
host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1);
|
||||
if (caps1) {
|
||||
host->caps1 = *caps1;
|
||||
} else {
|
||||
host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
|
||||
host->caps1 &= ~upper_32_bits(dt_caps_mask);
|
||||
host->caps1 |= upper_32_bits(dt_caps);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__sdhci_read_caps);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user