Commit afd58777 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents e2d324af d2d7a96b
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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);

+31 −2
Original line number Diff line number Diff line
@@ -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")) {
+21 −16
Original line number Diff line number Diff line
@@ -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;
+18 −0
Original line number Diff line number Diff line
@@ -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;