static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
{
	/* Schedule a card detection after a debounce timeout */
	struct mmc_host *host = dev_id;
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int status;
	unsigned long duration =0;
	/*
	 * In case host->ops are not yet initialized return immediately.
	 * The card will get detected later when host driver calls
	 * mmc_add_host() after host->ops are initialized.
	 */
	if (!host->ops)
		goto out;

	if (host->ops->card_event)
		host->ops->card_event(host);

	status = mmc_gpio_get_status(host);
	if (unlikely(status < 0))
		goto out;

	if (status ^ ctx->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), ctx->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		ctx->status = status;
#ifdef CONFIG_HUAWEI_KERNEL
		duration = jiffies - msmsdcc_irqtime;
		/* current msmsdcc is present, add to handle dithering */
		if (status)
		{
			/* the distance of two interrupts can not less than 7 second */
			if (duration < (7 * HZ))
			{
				duration = (7 * HZ) - duration;
			}
			else
			{
				/* 100 millisecond */
				duration = msecs_to_jiffies(100);
			}
		}
		else
		{
			duration = msecs_to_jiffies(2000);
		}
		mmc_detect_change(host, duration);
		msmsdcc_irqtime = jiffies;
#else
		/* Schedule a card detection after a debounce timeout */
		mmc_detect_change(host, msecs_to_jiffies(200));
#endif
	}
out:

	return IRQ_HANDLED;
}
/**
 * mmc_gpio_request_cd - request a gpio for card-detection
 * @host: mmc host
 * @gpio: gpio number requested
 *
 * As devm_* managed functions are used in mmc_gpio_request_cd(), client
 * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up,
 * if the requesting and freeing are only needed at probing and unbinding time
 * for once.  However, if client drivers do something special like runtime
 * switching for card-detection, they are responsible for calling
 * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own.
 *
 * Returns zero on success, else an error.
 */
int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
{
	struct mmc_gpio *ctx;
	int irq = gpio_to_irq(gpio);
	int ret;

	ret = mmc_gpio_alloc(host);
	if (ret < 0)
		return ret;

	ctx = host->slot.handler_priv;

	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN,
				    ctx->cd_label);
	if (ret < 0)
		/*
		 * don't bother freeing memory. It might still get used by other
		 * slot functions, in any case it will be freed, when the device
		 * is destroyed.
		 */
		return ret;

	/*
	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
	 * still prefer to poll, e.g., because that IRQ number is already used
	 * by another unit and cannot be shared.
	 */
	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
		irq = -EINVAL;

	ctx->cd_gpio = gpio;
	host->slot.cd_irq = irq;

	ret = mmc_gpio_get_status(host);
	if (ret < 0)
		return ret;

	ctx->status = ret;
	if (irq >= 0) {
		ret = devm_request_threaded_irq(&host->class_dev, irq,
			NULL, mmc_gpio_cd_irqt,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
			ctx->cd_label, host);
		if (ret < 0)
			irq = ret;
#ifndef VENDOR_EDIT
//[email protected], 2014-07-10 Add for retry 5 times when new sdcard init error
    	enable_irq_wake(irq);
#endif /* VENDOR_EDIT */
	}

	if (irq < 0)
		host->caps |= MMC_CAP_NEEDS_POLL;

	return 0;
}
static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
{
	
	struct mmc_host *host = dev_id;
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int status;

	spin_lock(&host->lock_cd_pin);
	if (host->cd_pin_depth == 0) {
		if (enable_detection_workqueue) {
			disable_irq_nosync(host->slot.cd_irq);
			queue_delayed_work(enable_detection_workqueue, &host->enable_detect, msecs_to_jiffies(50));
			host->cd_pin_depth++;
		} else
			pr_err("%s detection workqueue is null\n", mmc_hostname(host));
	}
	spin_unlock(&host->lock_cd_pin);

	if (!host->ops)
		goto out;

	if (host->ops->card_event)
		host->ops->card_event(host);

	status = mmc_gpio_get_status(host);
	if (unlikely(status < 0))
		goto out;

	if (status ^ ctx->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), ctx->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		irq_set_irq_type(irq, (status == 0 ?
					IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING));
		ctx->status = status;
		
		host->caps |= host->caps_uhs;
		
		host->removed_cnt = 0;
		host->crc_count = 0;
		
		if (disable_auto_sd)
			goto out;
		
		mmc_detect_change(host, msecs_to_jiffies(host->extended_debounce + 200));
		mmc_gpio_send_uevent(host);
	}
out:

	return IRQ_HANDLED;
}
int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
{
	struct mmc_gpio *ctx;
	int irq = gpio_to_irq(gpio);
	int ret;
	int irq_trigger_type;

	ret = mmc_gpio_alloc(host);
	if (ret < 0)
		return ret;

	host->cd_pin_depth = 0;
	spin_lock_init(&host->lock_cd_pin);

	ctx = host->slot.handler_priv;

	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN,
				    ctx->cd_label);
	if (ret < 0) {
		return ret;
	}

	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
		irq = -EINVAL;

	ctx->cd_gpio = gpio;
	host->slot.cd_irq = irq;

	ret = mmc_gpio_get_status(host);
	if (ret < 0)
		return ret;

	irq_trigger_type = (ret == 0 ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING);
	ctx->status = ret;

	if (irq >= 0) {
		ret = devm_request_threaded_irq(&host->class_dev, irq,
			NULL, mmc_gpio_cd_irqt,
			irq_trigger_type | IRQF_ONESHOT,
			ctx->cd_label, host);
		if (ret < 0)
			irq = ret;
	}

	if (irq < 0)
		host->caps |= MMC_CAP_NEEDS_POLL;

	return 0;
}
int mmc_gpio_send_uevent(struct mmc_host *host)
{
	char *envp[2];
	char state_string[16];
	int status;

	status = mmc_gpio_get_status(host);
	if (unlikely(status < 0))
		goto out;

	snprintf(state_string, sizeof(state_string), "SWITCH_STATE=%d", status);
	envp[0] = state_string;
	envp[1] = NULL;
	kobject_uevent_env(&host->class_dev.kobj, KOBJ_ADD, envp);

out:
	return status;
}
static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
{
	/* Schedule a card detection after a debounce timeout */
	struct mmc_host *host = dev_id;
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int status;

	/*
	 * In case host->ops are not yet initialized return immediately.
	 * The card will get detected later when host driver calls
	 * mmc_add_host() after host->ops are initialized.
	 */
	if (!host->ops)
		goto out;

	if (host->ops->card_event)
		host->ops->card_event(host);

	status = mmc_gpio_get_status(host);
	if (unlikely(status < 0))
		goto out;

#ifdef VENDOR_EDIT
        //[email protected], 2014-07-10 Add for retry 5 times when new sdcard init error
        host->detect_change_retry = 5;
#endif /* VENDOR_EDIT */

	if (status ^ ctx->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), ctx->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		ctx->status = status;
		/* Schedule a card detection after a debounce timeout */
		mmc_detect_change(host, msecs_to_jiffies(200));
	}
out:

	return IRQ_HANDLED;
}