Example #1
0
static int
sdio_multi_read(int addr, unsigned char *buf, int num)
{
	unsigned int address, int_status, val;
	int ret, i, j;
	unsigned int *tmp_buf = (unsigned int *)buf;

	val = sdio_read(SDIO_BLOCK) & 0xffff;
	sdio_write(val | (num << 16), SDIO_BLOCK);

	if (*acc_mode) {
		address = addr;
	} else {
		address = addr * MMC_BLOCKLEN_VAL;
	}

	/* CMD18 : READ_MULTI_BLOCK */
	ret = sdio_send_cmd(18, address, MMC_RSP_R1, NULL);
	if (ret != 0) {
		return ret;
	}

	while (1) {
		/* wait read enable */
		int_status = sdio_read(SDIO_INT_STS);
		if (int_status & (SDIO_INT_RREADY | SDIO_INT_ALLERR)) {
			break;
		}
	}
	sdio_write(SDIO_INT_RREADY, SDIO_INT_STS);
	if (int_status & SDIO_INT_ALLERR) {
		sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
		return int_status;
	}

	for (i = 0 ; i < num; i++) {
		while ((sdio_read(SDIO_STATE) & SDIO_STATE_RDEN) == 0) {
			int_status = sdio_read(SDIO_INT_STS);
			if (int_status & (SDIO_INT_ALLERR)) {
				sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
				return int_status;
			}
		}
		for (j = 0; j < MMC_BLOCKLEN_VAL / 4; j++) {
			*tmp_buf++ = sdio_read(SDIO_BUF);
		}
	}

	/* wait for data read end */
	int_status = sdio_read(SDIO_INT_STS);
	while (!(int_status & SDIO_INT_TRANCOMP)) {
		int_status = sdio_read(SDIO_INT_STS);
		if (int_status & SDIO_INT_ALLERR){
			sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
			return int_status;
		}
	}
	sdio_write(int_status, SDIO_INT_STS);
	return 0;
}
Example #2
0
static int
sdio_single_write(int addr, unsigned char *buf)
{
	int i;
	int ret;
	unsigned int address, int_status;
	unsigned int *tmp_buf = (unsigned int *)buf;

	if (*acc_mode) {
		address = addr;
	} else {
		address = addr * MMC_BLOCKLEN_VAL;
	}

	/* CMD24 : WRITE_SINGLE_BLOCK */
	ret = sdio_send_cmd(24, address, MMC_RSP_R1, NULL);
	if (ret != 0){
		return ret;
	}
	while (1) {
		/* wait write enable */
		int_status = sdio_read(SDIO_INT_STS);
		if (int_status & (SDIO_INT_WREADY | SDIO_INT_ALLERR)) {
			break;
		}
	}
	sdio_write(SDIO_INT_WREADY, SDIO_INT_STS);
	if (int_status & SDIO_INT_ALLERR) {
		sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
		return -1;
	}

	if (buf != NULL) {
		/* 1block write */
		for (i = 0; i < MMC_BLOCKLEN_VAL / 4; i++) {
			sdio_write(*tmp_buf++, SDIO_BUF);
		}
	} else {
		/* 1block clear */
		for (i = 0; i < MMC_BLOCKLEN_VAL / 4; i++) {
			sdio_write(0, SDIO_BUF);
		}
	}

	/* wait for data write end */
	int_status = sdio_read(SDIO_INT_STS);
	while (!(int_status & SDIO_INT_TRANCOMP)) {
		int_status = sdio_read(SDIO_INT_STS);
		if (int_status & SDIO_INT_ALLERR){
			sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
			return -1;
		}
	}
	sdio_write(int_status, SDIO_INT_STS);
	return 0;
}
Example #3
0
static int
sdio_wait_response(void)
{
	int ret;
	unsigned int int_status;

	while (!(sdio_read(SDIO_INT_STS) & SDIO_INT_CMDCOMP)) {
		if (sdio_read(SDIO_INT_STS) & SDIO_INT_ALLERR) {
			break;
		}
	}
	int_status = sdio_read(SDIO_INT_STS);
	ret = int_status & SDIO_INT_ALLERR;
	if (ret != 0) {
		sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
		if (ret & SDIO_INT_CMD_TOUT) {
			ret = MMC_RES_TIMEOUT;
		}
		return ret;
	}

	if (sdio_read(SDIO_MODE_CMD) & SDIO_CMD_DATA) {
		sdio_write(SDIO_INT_CMDCOMP, SDIO_INT_STS);
	} else {
		sdio_write(int_status, SDIO_INT_STS);
	}
	return 0;
}
Example #4
0
static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
{
	host->f_init = freq;

#ifdef CONFIG_MMC_DEBUG
	pr_info("%s: %s: trying to init card at %u Hz\n",
		mmc_hostname(host), __func__, host->f_init);
#endif
	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/* Order's important: probe SDIO, then SD, then MMC */
	if (!mmc_attach_sdio(host))
		return 0;
	if (!mmc_attach_sd(host))
		return 0;
	if (!mmc_attach_mmc(host))
		return 0;

	mmc_power_off(host);
	return -EIO;
}
Example #5
0
static int
sdio_send_extcsd(unsigned char *buf)
{
	int i;
	int ret;
	unsigned int int_status;
	unsigned int *tmp_buf = (unsigned int *)buf;

	/* CMD8 : SEND_EXT_CSD */
	ret = sdio_send_cmd(8, 0, MMC_RSP_R1, NULL);
	if (ret != 0) {
		return ret;
	}

	while (1) {
		/* wait read enable */
		int_status = sdio_read(SDIO_INT_STS);
		if (int_status & (SDIO_INT_RREADY | SDIO_INT_ALLERR)) {
			break;
		}
	}
	sdio_write(SDIO_INT_RREADY, SDIO_INT_STS);
	if (int_status & SDIO_INT_ALLERR) {
		sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
		return -1;
	}

	/* 1block read */
	for (i = 0; i < MMC_BLOCKLEN_VAL / 4; i++) {
		*tmp_buf++ = sdio_read(SDIO_BUF);
	}

	/* wait for data read end */
	int_status = sdio_read(SDIO_INT_STS);
	while (!(int_status & SDIO_INT_TRANCOMP)) {
		int_status = sdio_read(SDIO_INT_STS);
		if (int_status & SDIO_INT_ALLERR){
			sdio_reset(SDIO_SOFTRST_CMD | SDIO_SOFTRST_DATA);
			return int_status;
		}
	}
	sdio_write(int_status, SDIO_INT_STS);
	return 0;
}
Example #6
0
static void
sdio_hw_init(void)
{
#if defined(EMXX_MINIBOOT)
	sdio_write(SDIO_INT_MASK, SDIO_INT_STSEN);
	sdio_write(SDIO_AMBA0_TMODE_SINGLE, SDIO_AMBA0);
#endif
#if 0
	unsigned int val;

	/* initialize SDIO */
	sdio_write(SDIO_MODEN_ENABLE, SDIO_MODEN);
	sdio_write(SDIO_DELAY_REVERSE, SDIO_DELAY);

	val = sdio_read(SDIO_GIO0);
	sdio_write((val & ~SDIO_GIO0_DETECT), SDIO_GIO0);

	udelay(1500);

	sdio_reset(SDIO_SOFTRST_ALL);

	val = (SDIO_POWER_VOLT_30 | SDIO_POWER_POWER);
	sdio_write(val, SDIO_HP_BW);

	sdio_write(SDIO_INT_MASK, SDIO_INT_STSEN);

	val = SDIO_CLK_CLKDIV64 | SDIO_CLK_CLKEN | SDIO_TIMEOUT_COUNT_MAX;
	sdio_write(val, SDIO_CLK_TOUT_RST);
	while (!((val = sdio_read(SDIO_CLK_TOUT_RST)) & SDIO_CLK_CLKSTA)) {
	}
	val |= SDIO_CLK_SDCLKEN;
	sdio_write(val, SDIO_CLK_TOUT_RST);

	udelay(1000);
#endif
}
Example #7
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err=0;
	unsigned long flags;
	int extend_wakelock = 0;

	printk("%s: %s start\n", mmc_hostname(host), __func__);
	spin_lock_irqsave(&host->lock, flags);

	if (host->rescan_disable) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}

	spin_unlock_irqrestore(&host->lock, flags);


	mmc_bus_get(host);

	/* if there is a card registered, check whether it is still present */
	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);

	/* If the card was removed the bus will be marked
	 * as dead - extend the wakelock so userspace
	 * can respond */
	if (host->bus_dead)
		extend_wakelock = 1;

	mmc_bus_put(host);


	mmc_bus_get(host);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	mmc_release_host(host);
	mmc_power_off(host);

out:
	printk("%s: %s rescann is out\n", mmc_hostname(host), __func__);
	if (extend_wakelock)
		wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
	else
		wake_unlock(&mmc_delayed_work_wake_lock);

	if (host->caps & MMC_CAP_NEEDS_POLL)
	{
		printk("%s : schedule host->detect(mmc_sd_detect)\n",__func__);
		mmc_schedule_delayed_work(&host->detect, HZ);
	}
}
Example #8
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;
	int extend_wakelock = 0;

	mmc_bus_get(host);

	/* if there is a card registered, check whether it is still present */
	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);

	/* If the card was removed the bus will be marked
	 * as dead - extend the wakelock so userspace
	 * can respond */
	if (host->bus_dead)
		extend_wakelock = 1;

	mmc_bus_put(host);

	//ruanmeisi_20100422
	wake_lock(&mmc_delayed_work_wake_lock);
	//end

	mmc_bus_get(host);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	mmc_release_host(host);
	mmc_power_off(host);

out:
	if (extend_wakelock)
		wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
	else
		wake_unlock(&mmc_delayed_work_wake_lock);

	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, 2 * HZ);
}
Example #9
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;
	unsigned long flags;
	int extend_wakelock = 0;

	spin_lock_irqsave(&host->lock, flags);

	if (host->rescan_disable) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}

	spin_unlock_irqrestore(&host->lock, flags);


	mmc_bus_get(host);

	/* if there is a card registered, check whether it is still present */
	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);

	/* If the card was removed the bus will be marked
	 * as dead - extend the wakelock so userspace
	 * can respond */
	if (host->bus_dead)
		extend_wakelock = 1;

	mmc_bus_put(host);


	mmc_bus_get(host);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
	#ifdef CONFIG_MACH_LGE_MMC_REFRESH
		if (mmc_attach_sd(host, ocr))
		{
		
			extern int omap_hsmmc_regulator_force_refresh(struct mmc_host *mmc);
						
		
			omap_hsmmc_regulator_force_refresh(host);
			printk(KERN_WARNING "%s: omap_hsmmc_regulator_force_refresh() done \n",mmc_hostname(host), err);
			
			mmc_claim_host(host);

			mmc_power_up(host);
			sdio_reset(host);
			mmc_go_idle(host);
			mmc_send_if_cond(host, host->ocr_avail);
			mmc_send_app_op_cond(host, 0, &ocr);
			if(mmc_attach_sd(host, ocr))
			{
				mmc_power_off(host);
				printk("[microSD]f=%s, line=%d, retry initialize FAIL  \n", __func__, __LINE__);	
			}
			else
				printk("[microSD]f=%s, line=%d, retry initialize SUCCESS  \n", __func__, __LINE__);	
		}
	#else
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
	#endif	//CONFIG_MACH_LGE_MMC_REFRESH
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	mmc_release_host(host);
	mmc_power_off(host);

out:
	if (extend_wakelock)
		wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
	else
		wake_unlock(&mmc_delayed_work_wake_lock);

	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
Example #10
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);

	if (host->rescan_disable) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}

	spin_unlock_irqrestore(&host->lock, flags);


	mmc_bus_get(host);

	/* if there is a card registered, check whether it is still present */
	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);

	mmc_bus_put(host);


	mmc_bus_get(host);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr)) {
			mmc_claim_host(host);
			/* try SDMEM (but not MMC) even if SDIO is broken */
			if (mmc_send_app_op_cond(host, 0, &ocr))
				goto out_fail;

			if (mmc_attach_sd(host, ocr))
				mmc_power_off(host);
		}
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		goto out;
	}

out_fail:
	mmc_release_host(host);
	mmc_power_off(host);

out:
	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
Example #11
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;
	struct mmc_card card;

	mmc_bus_get(host);

	/* if there is a card registered, check whether it is still present */
	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
		host->bus_ops->detect(host);

	mmc_bus_put(host);


	mmc_bus_get(host);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	// Change for EP7
	card.host = host;
	mmc_io_rw_direct(&card, 1, 0, SDIO_CCCR_ABORT, 0x08, NULL);

	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr))
			mmc_power_off(host);
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		goto out;
	}

	mmc_release_host(host);
	mmc_power_off(host);

out:
	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
Example #12
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;
	int extend_wakelock = 0;
	int ret;

	unsigned long flags;

	/*
        * Add checking gpio pin status before initialization of bus.
        * If the GPIO pin status is changed, check gpio pin status again.
        * Should check until it's stable.
        * [email protected], 2010-09-27
        */
	if (host->ops->get_status){
		ret = host->ops->get_status(host);
		if (ret == 1) {
			mmc_schedule_delayed_work(&host->detect, HZ / 3);
			return;
		}
	}

	spin_lock_irqsave(&host->lock, flags);
	if (host->rescan_disable) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}
	spin_unlock_irqrestore(&host->lock, flags);

	mmc_bus_get(host);

	/*
	 * if there is a _removable_ card registered, check whether it is
	 * still present
	 */
	if (host->bus_ops && host->bus_ops->detect && !host->bus_dead
	    && !(host->caps & MMC_CAP_NONREMOVABLE)) {
		host->bus_ops->detect(host);
		/* If the card was removed the bus will be marked
		 * as dead - extend the wakelock so userspace
		 * can respond */
		if (host->bus_dead)
			extend_wakelock = 1;
	}

	mmc_bus_put(host);


	mmc_bus_get(host);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	mmc_release_host(host);
	mmc_power_off(host);

out:
	if (extend_wakelock)
		wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
	else
		wake_unlock(&mmc_delayed_work_wake_lock);

	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
Example #13
0
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;
	unsigned long flags;
	int extend_wakelock = 0;

	spin_lock_irqsave(&host->lock, flags);

	if (host->rescan_disable) {
		spin_unlock_irqrestore(&host->lock, flags);
		if (atomic_dec_return(&wakelock_refs) > 0) {
			printk(KERN_DEBUG "Another host want the wakelock : %d\n", atomic_read(&wakelock_refs));
		}else {
			printk(KERN_DEBUG "unlock case1 : mmc%d: wake_lock_timeout 0.5 sec %d\n", host->index, atomic_read(&wakelock_refs));
			wake_lock_timeout(&mmc_delayed_work_wake_lock, msecs_to_jiffies(500));
		}
		return;
	}

	spin_unlock_irqrestore(&host->lock, flags);

//[NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion
//	mutex_lock(&host->carddetect_lock); 
//]NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion	

	mmc_bus_get(host);

	/* if there is a card registered, check whether it is still present */
	if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead) {
		if(host->ops->get_cd && host->ops->get_cd(host) == 0) {
			if(host->bus_ops->remove)
				host->bus_ops->remove(host);

			mmc_claim_host(host);
			mmc_detach_bus(host);
			mmc_release_host(host);
		}
		else
			host->bus_ops->detect(host);
	}

	/* If the card was removed the bus will be marked
	 * as dead - extend the wakelock so userspace
	 * can respond */
	if (host->bus_dead)
		extend_wakelock = 1;

	mmc_bus_put(host);


	mmc_bus_get(host);

	printk(KERN_DEBUG "*** DEBUG : start %s (mmc%d)***\n", __func__, host->index);

	/* if there still is a card present, stop here */
	if (host->bus_ops != NULL) {
		mmc_bus_put(host);
		goto out;
	}

	/* detect a newly inserted card */

	/*
	 * Only we can add a new handler, so it's safe to
	 * release the lock here.
	 */
	mmc_bus_put(host);

	if (host->ops->get_cd && host->ops->get_cd(host) == 0)
		goto out;

	mmc_claim_host(host);

	mmc_power_up(host);
	sdio_reset(host);
	mmc_go_idle(host);

	mmc_send_if_cond(host, host->ocr_avail);

	/*
	 * First we search for SDIO...
	 */
	printk(KERN_DEBUG "*** DEBUG : First we search for SDIO...(%d)***\n", host->index);
	err = mmc_send_io_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sdio(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...then normal SD...
	 */
	printk(KERN_DEBUG "*** DEBUG : ...then normal SD...(%d) ***\n", host->index);
	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_sd(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	/*
	 * ...and finally MMC.
	 */
	printk(KERN_DEBUG "*** DEBUG : ...and finally MMC. (%d)***\n", host->index);
	err = mmc_send_op_cond(host, 0, &ocr);
	if (!err) {
		if (mmc_attach_mmc(host, ocr))
			mmc_power_off(host);
		extend_wakelock = 1;
		goto out;
	}

	printk(KERN_DEBUG "*** DEBUG : end %s (mmc%d)***\n", __func__, host->index);

	mmc_release_host(host);
	mmc_power_off(host);

out:
#if 0
	//if (extend_wakelock)
	//	wake_lock_timeout(&mmc_delayed_work_wake_lock, HZ / 2);
	//else
	//	wake_unlock(&mmc_delayed_work_wake_lock);
#else
	if (atomic_dec_return(&wakelock_refs) > 0) {
		printk(KERN_DEBUG "Another host want the wakelock : %d\n", atomic_read(&wakelock_refs));
	}
	else {
		printk(KERN_DEBUG "unlock case2 : mmc%d: wake_lock_timeout 0.5 sec %d\n", host->index, atomic_read(&wakelock_refs));
		wake_lock_timeout(&mmc_delayed_work_wake_lock, msecs_to_jiffies(500));
	}
#endif

	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
//[NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion
//	mutex_unlock(&host->carddetect_lock); 
//]NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion

}