MMC host:

- sdhci_am654: Disable HS400 for AM62P SR1.0 and SR1.1
  - sdhci-of-arasan: Ensure CD logic stabilization before power-up
  - sdhci-pci-gli: Mask the replay timer timeout of AER for GL9763e
 
 MEMSTICK:
  - Fix deadlock by moving removing flag earlier
 -----BEGIN PGP SIGNATURE-----
 
 iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmioRt4XHHVsZi5oYW5z
 c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCkW/w/+NeQhlSoTGr/eBWL2BqF3+b1J
 yxyS/DIW0CukTrpQNMqsu9yeWqRqqugBGm613/ffJ2elCOV8sfhyQt8tgvIur9WB
 mWEXui8PwReNa4ZLmUVbFMLfLL0uJO0MIYRXFxJB8CGk0OXsN4jffaomurVdmXsS
 4WkvzHcm64MmGINPkGnkWICMIHiErjAaQOZJBmasG7VxkdHVvJjbi0QFeWjnVExd
 7HXN2qPU1y8Vv7jgArGaGnL7ZElmzEjcDn7+ZCStC4Q6QjTsKE3FFjsEkiF08b1M
 1BBwx6NfB/KOBxBNy6g7vLmeD52oLIET2AQ8E4aQ2MpQF24323eDmY/TLR7d8SIq
 jctdi21qcqQLeaj2oStcgS+FTH2vpkSQBK4kv/cRTcEVpvun+KYrCNpFI0JDovY0
 0BHOukSHMkB0i0X1uyBmMXlxFGne67sDM42tynfkHVMfb6MTtk50EqyWi5shoYcJ
 PUPv/E+AemohyKzqLpU177Lx84pX3km9oK21tVGJS62Qv8ydgJLV2YXWU7IKQ+Mv
 d+X7Ks6AlHIbhMdo00/L/4nLNjvUiAzJ480QnAE1qt+luFhnKievFaZ0hX2z7E14
 WGnpPlph2S2UUfJpeA4JuM3Pb2nwvjVm4pl5CZYRg2cRJz4DGRK20NbcZ/waA02I
 umWZrQ1PzgyYOqYRmkE=
 =FuWR
 -----END PGP SIGNATURE-----

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

Pull MMC fixes from Ulf Hansson:
 "MMC host:
   - sdhci_am654: Disable HS400 for AM62P SR1.0 and SR1.1
   - sdhci-of-arasan: Ensure CD logic stabilization before power-up
   - sdhci-pci-gli: Mask the replay timer timeout of AER for GL9763e

  MEMSTICK:
   - Fix deadlock by moving removing flag earlier"

* tag 'mmc-v6.17-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc:
  mmc: sdhci_am654: Disable HS400 for AM62P SR1.0 and SR1.1
  memstick: Fix deadlock by moving removing flag earlier
  mmc: sdhci-of-arasan: Ensure CD logic stabilization before power-up
  mmc: sdhci-pci-gli: GL9763e: Mask the replay timer timeout of AER
  mmc: sdhci-pci-gli: GL9763e: Rename the gli_set_gl9763e() for consistency
  mmc: sdhci-pci-gli: Add a new function to simplify the code
This commit is contained in:
Linus Torvalds 2025-08-22 09:17:49 -04:00
commit afd58777de
5 changed files with 71 additions and 19 deletions

View File

@ -555,7 +555,6 @@ EXPORT_SYMBOL(memstick_add_host);
*/
void memstick_remove_host(struct memstick_host *host)
{
host->removing = 1;
flush_workqueue(workqueue);
mutex_lock(&host->lock);
if (host->card)

View File

@ -812,6 +812,7 @@ static void rtsx_usb_ms_drv_remove(struct platform_device *pdev)
int err;
host->eject = true;
msh->removing = true;
cancel_work_sync(&host->handle_req);
cancel_delayed_work_sync(&host->poll_card);

View File

@ -99,6 +99,9 @@
#define HIWORD_UPDATE(val, mask, shift) \
((val) << (shift) | (mask) << ((shift) + 16))
#define CD_STABLE_TIMEOUT_US 1000000
#define CD_STABLE_MAX_SLEEP_US 10
/**
* struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map
*
@ -206,12 +209,15 @@ struct sdhci_arasan_data {
* 19MHz instead
*/
#define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2)
/* Enable CD stable check before power-up */
#define SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE BIT(3)
};
struct sdhci_arasan_of_data {
const struct sdhci_arasan_soc_ctl_map *soc_ctl_map;
const struct sdhci_pltfm_data *pdata;
const struct sdhci_arasan_clk_ops *clk_ops;
u32 quirks;
};
static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = {
@ -514,6 +520,24 @@ static int sdhci_arasan_voltage_switch(struct mmc_host *mmc,
return -EINVAL;
}
static void sdhci_arasan_set_power_and_bus_voltage(struct sdhci_host *host, unsigned char mode,
unsigned short vdd)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
u32 reg;
/*
* Ensure that the card detect logic has stabilized before powering up, this is
* necessary after a host controller reset.
*/
if (mode == MMC_POWER_UP && sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE)
read_poll_timeout(sdhci_readl, reg, reg & SDHCI_CD_STABLE, CD_STABLE_MAX_SLEEP_US,
CD_STABLE_TIMEOUT_US, false, host, SDHCI_PRESENT_STATE);
sdhci_set_power_and_bus_voltage(host, mode, vdd);
}
static const struct sdhci_ops sdhci_arasan_ops = {
.set_clock = sdhci_arasan_set_clock,
.get_max_clock = sdhci_pltfm_clk_get_max_clock,
@ -521,7 +545,7 @@ static const struct sdhci_ops sdhci_arasan_ops = {
.set_bus_width = sdhci_set_bus_width,
.reset = sdhci_arasan_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
.set_power = sdhci_set_power_and_bus_voltage,
.set_power = sdhci_arasan_set_power_and_bus_voltage,
.hw_reset = sdhci_arasan_hw_reset,
};
@ -570,7 +594,7 @@ static const struct sdhci_ops sdhci_arasan_cqe_ops = {
.set_bus_width = sdhci_set_bus_width,
.reset = sdhci_arasan_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
.set_power = sdhci_set_power_and_bus_voltage,
.set_power = sdhci_arasan_set_power_and_bus_voltage,
.irq = sdhci_arasan_cqhci_irq,
};
@ -1447,6 +1471,7 @@ static const struct sdhci_arasan_clk_ops zynqmp_clk_ops = {
static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = {
.pdata = &sdhci_arasan_zynqmp_pdata,
.clk_ops = &zynqmp_clk_ops,
.quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE,
};
static const struct sdhci_arasan_clk_ops versal_clk_ops = {
@ -1457,6 +1482,7 @@ static const struct sdhci_arasan_clk_ops versal_clk_ops = {
static struct sdhci_arasan_of_data sdhci_arasan_versal_data = {
.pdata = &sdhci_arasan_zynqmp_pdata,
.clk_ops = &versal_clk_ops,
.quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE,
};
static const struct sdhci_arasan_clk_ops versal_net_clk_ops = {
@ -1467,6 +1493,7 @@ static const struct sdhci_arasan_clk_ops versal_net_clk_ops = {
static struct sdhci_arasan_of_data sdhci_arasan_versal_net_data = {
.pdata = &sdhci_arasan_versal_net_pdata,
.clk_ops = &versal_net_clk_ops,
.quirks = SDHCI_ARASAN_QUIRK_ENSURE_CD_STABLE,
};
static struct sdhci_arasan_of_data intel_keembay_emmc_data = {
@ -1937,6 +1964,8 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
if (of_device_is_compatible(np, "rockchip,rk3399-sdhci-5.1"))
sdhci_arasan_update_clockmultiplier(host, 0x0);
sdhci_arasan->quirks |= data->quirks;
if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {

View File

@ -287,6 +287,20 @@
#define GLI_MAX_TUNING_LOOP 40
/* Genesys Logic chipset */
static void sdhci_gli_mask_replay_timer_timeout(struct pci_dev *pdev)
{
int aer;
u32 value;
/* mask the replay timer timeout of AER */
aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
if (aer) {
pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value);
value |= PCI_ERR_COR_REP_TIMER;
pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value);
}
}
static inline void gl9750_wt_on(struct sdhci_host *host)
{
u32 wt_value;
@ -607,7 +621,6 @@ static void gl9750_hw_setting(struct sdhci_host *host)
{
struct sdhci_pci_slot *slot = sdhci_priv(host);
struct pci_dev *pdev;
int aer;
u32 value;
pdev = slot->chip->pdev;
@ -626,12 +639,7 @@ static void gl9750_hw_setting(struct sdhci_host *host)
pci_set_power_state(pdev, PCI_D0);
/* mask the replay timer timeout of AER */
aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
if (aer) {
pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value);
value |= PCI_ERR_COR_REP_TIMER;
pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value);
}
sdhci_gli_mask_replay_timer_timeout(pdev);
gl9750_wt_off(host);
}
@ -806,7 +814,6 @@ static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock)
static void gl9755_hw_setting(struct sdhci_pci_slot *slot)
{
struct pci_dev *pdev = slot->chip->pdev;
int aer;
u32 value;
gl9755_wt_on(pdev);
@ -841,12 +848,7 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot)
pci_set_power_state(pdev, PCI_D0);
/* mask the replay timer timeout of AER */
aer = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
if (aer) {
pci_read_config_dword(pdev, aer + PCI_ERR_COR_MASK, &value);
value |= PCI_ERR_COR_REP_TIMER;
pci_write_config_dword(pdev, aer + PCI_ERR_COR_MASK, value);
}
sdhci_gli_mask_replay_timer_timeout(pdev);
gl9755_wt_off(pdev);
}
@ -1751,7 +1753,7 @@ static int gl9763e_add_host(struct sdhci_pci_slot *slot)
return ret;
}
static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
static void gl9763e_hw_setting(struct sdhci_pci_slot *slot)
{
struct pci_dev *pdev = slot->chip->pdev;
u32 value;
@ -1780,6 +1782,9 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
value |= FIELD_PREP(GLI_9763E_HS400_RXDLY, GLI_9763E_HS400_RXDLY_5);
pci_write_config_dword(pdev, PCIE_GLI_9763E_CLKRXDLY, value);
/* mask the replay timer timeout of AER */
sdhci_gli_mask_replay_timer_timeout(pdev);
pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value);
value &= ~GLI_9763E_VHS_REV;
value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R);
@ -1923,7 +1928,7 @@ static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)
gli_pcie_enable_msi(slot);
host->mmc_host_ops.hs400_enhanced_strobe =
gl9763e_hs400_enhanced_strobe;
gli_set_gl9763e(slot);
gl9763e_hw_setting(slot);
sdhci_enable_v4_mode(host);
return 0;

View File

@ -156,6 +156,7 @@ struct sdhci_am654_data {
#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
#define SDHCI_AM654_QUIRK_SUPPRESS_V1P8_ENA BIT(1)
#define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(2)
};
struct window {
@ -765,6 +766,7 @@ static int sdhci_am654_init(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
struct device *dev = mmc_dev(host->mmc);
u32 ctl_cfg_2 = 0;
u32 mask;
u32 val;
@ -820,6 +822,12 @@ static int sdhci_am654_init(struct sdhci_host *host)
if (ret)
goto err_cleanup_host;
if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_DISABLE_HS400 &&
host->mmc->caps2 & (MMC_CAP2_HS400 | MMC_CAP2_HS400_ES)) {
dev_info(dev, "HS400 mode not supported on this silicon revision, disabling it\n");
host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES);
}
ret = __sdhci_add_host(host);
if (ret)
goto err_cleanup_host;
@ -883,6 +891,12 @@ static int sdhci_am654_get_of_property(struct platform_device *pdev,
return 0;
}
static const struct soc_device_attribute sdhci_am654_descope_hs400[] = {
{ .family = "AM62PX", .revision = "SR1.0" },
{ .family = "AM62PX", .revision = "SR1.1" },
{ /* sentinel */ }
};
static const struct of_device_id sdhci_am654_of_match[] = {
{
.compatible = "ti,am654-sdhci-5.1",
@ -970,6 +984,10 @@ static int sdhci_am654_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "parsing dt failed\n");
soc = soc_device_match(sdhci_am654_descope_hs400);
if (soc)
sdhci_am654->quirks |= SDHCI_AM654_QUIRK_DISABLE_HS400;
host->mmc_host_ops.start_signal_voltage_switch = sdhci_am654_start_signal_voltage_switch;
host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning;