Exemplo n.º 1
0
static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
{
	struct mmc_host *host = dev_id;
	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
	int status;

	disable_irq_nosync(host->hotplug.irq);
	tasklet_schedule(&enable_detection_tasklet);

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

	if (status ^ cd->status) {
		printk_ratelimited(KERN_INFO "%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), cd->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		cd->status = status;
		
		host->caps |= host->caps_uhs;
		host->redetect_cnt = 0;
		
		mmc_detect_change(host, msecs_to_jiffies(100));
	}
out:
	return IRQ_HANDLED;
}
Exemplo n.º 2
0
static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
{
    struct mmc_host *host = dev_id;
    struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
    int status;

#ifdef VENDOR_EDIT
//[email protected], 2014/12/12, Add for hot plug Tf card system crash
    TF_CARD_STATUS = status = mmc_cd_get_status(host);
#endif /* VENDOR_EDIT */

    if (unlikely(status < 0))
        goto out;

    if (status ^ cd->status) {
        pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
                mmc_hostname(host), cd->status, status,
                (host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
                "HIGH" : "LOW");
        cd->status = status;

#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 */

        /* Schedule a card detection after a debounce timeout */
        mmc_detect_change(host, msecs_to_jiffies(100));
    }
out:
    return IRQ_HANDLED;
}
Exemplo n.º 3
0
static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
{
	struct mmc_host *host = dev_id;
	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
	int status;

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

#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
	cd->irq_detect = 1;
#endif

	if (status ^ cd->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), cd->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		cd->status = status;

#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
		cd->irq_detect = 0;
#endif
		/* Schedule a card detection after a debounce timeout */
		mmc_detect_change(host, msecs_to_jiffies(100));
	}
out:
	return IRQ_HANDLED;
}
Exemplo n.º 4
0
int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
{
    size_t len = strlen(dev_name(host->parent)) + 4;
    struct mmc_cd_gpio *cd;
    int irq = gpio_to_irq(gpio);
    int ret;

    if (irq < 0)
        return irq;

    cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
    if (!cd)
        return -ENOMEM;

    snprintf(cd->label, len, "%s cd", dev_name(host->parent));

    ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
    if (ret < 0)
        goto egpioreq;

    cd->gpio = gpio;
    host->hotplug.irq = irq;
    host->hotplug.handler_priv = cd;

    ret = mmc_cd_get_status(host);
    if (ret < 0)
        goto eirqreq;

    cd->status = ret;

    ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                               cd->label, host);
    if (ret < 0)
        goto eirqreq;

#if (defined(CONFIG_OPPO_MSM_14021) || defined(CONFIG_OPPO_MSM_14024))
//[email protected], 2014/09/24, Add for wakeup the phone when insert or pull out the micro sd card
#if 0
    if (get_pcb_version() >= HW_VERSION__32) {
        ret = enable_irq_wake(irq);
        if(ret < 0)
        {
            printk(KERN_ERR "%s, enable_irq_wake %d\n", __func__, ret);
        }
    }
#endif
#endif /* VENDOR_EDIT */

    return 0;

eirqreq:
    gpio_free(gpio);
egpioreq:
    kfree(cd);
    return ret;
}
static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
{
	struct mmc_host *host = dev_id;
	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
	int status;

#ifdef CONFIG_HUAWEI_KERNEL
	unsigned long duration;
#endif
	status = mmc_cd_get_status(host);
	if (unlikely(status < 0))
		goto out;

	if (status ^ cd->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), cd->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		cd->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(100));
#endif
	}
out:
	return IRQ_HANDLED;
}
Exemplo n.º 6
0
int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
{
	size_t len = strlen(dev_name(host->parent)) + 4;
	struct mmc_cd_gpio *cd;
	int irq = gpio_to_irq(gpio);
	int ret;

	if (irq < 0)
		return irq;

	tasklet_init(&enable_detection_tasklet,
		mmc_enable_detection_tasklet, (unsigned long)host);

	irq_set_irq_wake(irq, 1);

	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
	if (!cd)
		return -ENOMEM;

	snprintf(cd->label, len, "%s cd", dev_name(host->parent));

	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
	if (ret < 0)
		goto egpioreq;

	cd->gpio = gpio;
	host->hotplug.irq = irq;
	host->hotplug.handler_priv = cd;

	ret = mmc_cd_get_status(host);
	if (ret < 0)
		goto eirqreq;

	cd->status = ret;

	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
				   cd->label, host);
	if (ret < 0)
		goto eirqreq;

	return 0;

eirqreq:
	gpio_free(gpio);
egpioreq:
	kfree(cd);
	tasklet_kill(&enable_detection_tasklet);
	return ret;
}
Exemplo n.º 7
0
int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
{
	size_t len = strlen(dev_name(host->parent)) + 4;
	struct mmc_cd_gpio *cd;
	int irq = gpio_to_irq(gpio);
	int ret;

	if (irq < 0)
		return irq;

	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
	if (!cd)
		return -ENOMEM;

	snprintf(cd->label, len, "%s cd", dev_name(host->parent));

	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
	if (ret < 0)
		goto egpioreq;

	cd->gpio = gpio;
	host->hotplug.irq = irq;
	host->hotplug.handler_priv = cd;

	ret = mmc_cd_get_status(host);
	if (ret < 0)
		goto eirqreq;

	cd->status = ret;

#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
	cd->pending_detect = false;
	cd->suspended = false;
#endif

	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				   cd->label, host);
	if (ret < 0)
		goto eirqreq;

	return 0;

eirqreq:
	gpio_free(gpio);
egpioreq:
	kfree(cd);
	return ret;
}
Exemplo n.º 8
0
static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
{
	struct mmc_host *host = dev_id;
	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
	unsigned long flags;
#endif
	int status;

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

#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
	if (cd->suspended) {
		/*
		 * host->rescan_disable is normally set to 0 in mmc_resume_bus
		 * but in case of a deferred resume we might get IRQ before
		 * it is called.
		 */
		spin_lock_irqsave(&host->lock, flags);
		host->rescan_disable = 0;
		spin_unlock_irqrestore(&host->lock, flags);

		/*
		 * We've got IRQ just after resuming device but the status
		 * did not change; card might have been swapped, force
		 * redetection.
		 */
		if (status == cd->status)
			status = 2;
	}
	cd->suspended = false;
#endif

	if (status ^ cd->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), cd->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		cd->status = status;

		/* Schedule a card detection after a debounce timeout */
		mmc_detect_change(host, msecs_to_jiffies(100));
	}
out:
	return IRQ_HANDLED;
}
Exemplo n.º 9
0
int mmc_cd_slot_status_changed(struct mmc_host *host)
{
	int status;
	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;

	if (!cd)
		goto out;

	status = mmc_cd_get_status(host);
	if (unlikely(status < 0))
		return 1;

	if ((cd->irq_detect && status) || (!status && host->card)) {
		cd->irq_detect = 0;
		return 1;
	}

out:
	return 0;
}
Exemplo n.º 10
0
static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
{
	struct mmc_host *host = dev_id;
	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
	int status;

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

	if (status ^ cd->status) {
		pr_info("%s: slot status change detected (%d -> %d), GPIO_ACTIVE_%s\n",
				mmc_hostname(host), cd->status, status,
				(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH) ?
				"HIGH" : "LOW");
		cd->status = status;

#ifdef CONFIG_MACH_LGE
		if(!status )   //active high & active low  status value is low when sdcard ejected . 
		{
			mmc_gpio_irq_flag =1;	
		}
		
		else 
		{
			mmc_gpio_irq_flag =0;	
		}
		pr_info("%s: mmc_gpio_irq_flagd !!!!! %d\n",mmc_hostname(host),mmc_gpio_irq_flag );
		
#endif 
		/* Schedule a card detection after a debounce timeout */
		mmc_detect_change(host, msecs_to_jiffies(100));
	}
out:
	return IRQ_HANDLED;
}