Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94b3cc1b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: core: Fix card remove detect when use extcon"

parents ea17f797 56902d5e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3586,6 +3586,7 @@ void mmc_start_host(struct mmc_host *host)
	}

	mmc_gpiod_request_cd_irq(host);
	mmc_register_extcon(host);
	_mmc_detect_change(host, 0, false);
}

@@ -3615,6 +3616,7 @@ void mmc_stop_host(struct mmc_host *host)
	}
	mmc_bus_put(host);

	mmc_unregister_extcon(host);
	mmc_claim_host(host);
	mmc_power_off(host);
	mmc_release_host(host);
+57 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/mmc/slot-gpio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/extcon.h>

#include "slot-gpio.h"

@@ -80,7 +81,15 @@ int mmc_gpio_get_cd(struct mmc_host *host)
{
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int cansleep;
	int ret;

	if (host->extcon) {
		ret =  extcon_get_state(host->extcon, EXTCON_MECHANICAL);
		if (ret < 0)
			dev_err(mmc_dev(host), "%s: Extcon failed to check card state, ret=%d\n",
					__func__, ret);
		return ret;
	}
	if (!ctx || !ctx->cd_gpio)
		return -ENOSYS;

@@ -162,6 +171,54 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host)
}
EXPORT_SYMBOL(mmc_gpiod_request_cd_irq);

static int mmc_card_detect_notifier(struct notifier_block *nb,
				       unsigned long event, void *ptr)
{
	struct mmc_host *host = container_of(nb, struct mmc_host,
					     card_detect_nb);

	host->trigger_card_event = true;
	mmc_detect_change(host, 0);

	return NOTIFY_DONE;
}

void mmc_register_extcon(struct mmc_host *host)
{
	struct extcon_dev *extcon = host->extcon;
	int err;

	if (!extcon)
		return;

	host->card_detect_nb.notifier_call = mmc_card_detect_notifier;
	err = extcon_register_notifier(extcon, EXTCON_MECHANICAL,
				       &host->card_detect_nb);
	if (err) {
		dev_err(mmc_dev(host), "%s: extcon_register_notifier() failed ret=%d\n",
			__func__, err);
		host->caps |= MMC_CAP_NEEDS_POLL;
	}
}
EXPORT_SYMBOL(mmc_register_extcon);

void mmc_unregister_extcon(struct mmc_host *host)
{
	struct extcon_dev *extcon = host->extcon;
	int err;

	if (!extcon)
		return;

	err = extcon_unregister_notifier(extcon, EXTCON_MECHANICAL,
					 &host->card_detect_nb);
	if (err)
		dev_err(mmc_dev(host), "%s: extcon_unregister_notifier() failed ret=%d\n",
			__func__, err);
}
EXPORT_SYMBOL(mmc_unregister_extcon);


int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on)
{
	int ret = 0;
+2 −0
Original line number Diff line number Diff line
@@ -120,6 +120,8 @@ config MMC_SDHCI_ACPI
config MMC_SDHCI_PLTFM
	tristate "SDHCI platform and OF driver helper"
	depends on MMC_SDHCI
	select EXTCON
	select EXTCON_GPIO
	help
	  This selects the common helper functions support for Secure Digital
	  Host Controller Interface based platform and OF drivers.
+10 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
	struct resource *iomem;
	void __iomem *ioaddr;
	int irq, ret;
	struct extcon_dev *extcon;

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ioaddr = devm_ioremap_resource(&pdev->dev, iomem);
@@ -156,6 +157,15 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
		host->quirks2 = pdata->quirks2;
	}

	extcon = extcon_get_edev_by_phandle(&pdev->dev, 0);
	if (IS_ERR(extcon) && PTR_ERR(extcon) != -ENODEV) {
		ret = PTR_ERR(extcon);
		goto err;
	}
	if (!IS_ERR(extcon))
		host->mmc->extcon = extcon;


	platform_set_drvdata(pdev, host);

	return host;
+2 −0
Original line number Diff line number Diff line
@@ -35,5 +35,7 @@ int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on);
void mmc_gpiod_request_cd_irq(struct mmc_host *host);
bool mmc_can_gpio_cd(struct mmc_host *host);
bool mmc_can_gpio_ro(struct mmc_host *host);
void mmc_register_extcon(struct mmc_host *host);
void mmc_unregister_extcon(struct mmc_host *host);

#endif