コード例 #1
0
ファイル: core.c プロジェクト: mike1980/lge-kernel-msm7x27
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);
}
コード例 #2
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 int eint0msk = 0;	
	int ext_CD_int = 0;

	ext_CD_int = readl(S3C64XX_GPNDAT);
	ext_CD_int &= 0x40;	/* GPN6 */
	if( system_rev >= 0x20 )
		ext_CD_int = !ext_CD_int;

	mmc_bus_get(host);
    printk("kimhyuns mmc_rescan hostindex=%d\n", host->index);

	if (host->bus_ops == NULL) {
	    printk("kimhyuns mmc_rescan host->bus_ops == NULL \n");
		/*
		 * 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);
		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);
			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);
	}
	else 
	{
    printk("kimhyuns mmc_rescan else \n");	
		if (host->bus_ops->detect && !host->bus_dead)
			host->bus_ops->detect(host);

		mmc_bus_put(host);

		if(host->index ==0 && g_rescan_retry)
		{
			ext_CD_int = readl(S3C64XX_GPNDAT);
			ext_CD_int &= 0x40;	/* GPN6 */
			if( system_rev >= 0x20 )
				ext_CD_int = !ext_CD_int;

			if (!ext_CD_int)
			{
				mmc_detect_change(host, msecs_to_jiffies(200));
				g_rescan_retry = 0;
//		if(is_inited_wake_lock==1) //kimhyuns probe에서 수정함.
				{
					printk("kimhyuns mmc_rescan unlock 1 \n");					
					wake_unlock(&sdcard_scan_wake_lock);//kimhyuns_add
				}
			}
		}
	}

	if (!ext_CD_int)
	{
		eint0msk = __raw_readl(S3C64XX_EINT0MASK);
		eint0msk &= 0x0FFFFFFF & ~(1 << 6);
		__raw_writel(eint0msk, S3C64XX_EINT0MASK);
	}
		
out:
	if(host->index ==0 && g_rescan_retry)
	{
		g_rescan_retry = 0;
//		if(is_inited_wake_lock==1) //kimhyuns probe에서 수정함.
		{
			printk("kimhyuns mmc_rescan unlock 2 \n");					
			//wake_unlock(&sdcard_scan_wake_lock);//kimhyuns_add
			wake_lock_timeout(&sdcard_scan_wake_lock, msecs_to_jiffies(5000)); //give some timer for the media scanner to run
		}
	}
	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
コード例 #3
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);

#ifdef CONFIG_MMC_AUTO_SUSPEND
	if (!mmc_auto_suspend(host, 0)) { /* i.e resumed */
		mmc_bus_put(host);
		goto out;
	}
#endif
	/* 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);
	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);
}
コード例 #4
0
/*
 * Handle the detection and initialisation of a card.
 *
 * In the case of a resume, "oldcard" will contain the card
 * we're trying to reinitialise.
 */
static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                            struct mmc_card *oldcard)
{
    struct mmc_card *card;
    int err;
    u32 cid[4];
    unsigned int max_dtr;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
    int retries;
#endif
    BUG_ON(!host);
    WARN_ON(!host->claimed);

    /*
     * Since we're changing the OCR value, we seem to
     * need to tell some cards to go back to the idle
     * state.  We wait 1ms to give cards time to
     * respond.
     */
    mmc_go_idle(host);

    /*
     * If SD_SEND_IF_COND indicates an SD 2.0
     * compliant card and we should set bit 30
     * of the ocr to indicate that we can handle
     * block-addressed SDHC cards.
     */
    err = mmc_send_if_cond(host, ocr);
    if (!err)
        ocr |= 1 << 30;

    err = mmc_send_app_op_cond(host, ocr, NULL);
    if (err)
        goto err;

    /*
     * For SPI, enable CRC as appropriate.
     */
    if (mmc_host_is_spi(host)) {
        err = mmc_spi_set_crc(host, use_spi_crc);
        if (err)
            goto err;
    }

    /*
     * Fetch CID from card.
     */
    if (mmc_host_is_spi(host))
        err = mmc_send_cid(host, cid);
    else
        err = mmc_all_send_cid(host, cid);
    if (err)
        goto err;

    if (oldcard) {
        if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
            err = -ENOENT;
            goto err;
        }

        card = oldcard;
    } else {
        /*
         * Allocate card structure.
         */
        card = mmc_alloc_card(host, &sd_type);
        if (IS_ERR(card)) {
            err = PTR_ERR(card);
            goto err;
        }

        card->type = MMC_TYPE_SD;
        memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
    }

    /*
     * For native busses:  get card RCA and quit open drain mode.
     */
    if (!mmc_host_is_spi(host)) {
        err = mmc_send_relative_addr(host, &card->rca);
        if (err)
            goto free_card;

        mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
    }

    if (!oldcard) {
        /*
         * Fetch CSD from card.
         */
        err = mmc_send_csd(card, card->raw_csd);
        if (err)
            goto free_card;

        err = mmc_decode_csd(card);
        if (err)
            goto free_card;

        mmc_decode_cid(card);
    }

    /*
     * Select card, as all following commands rely on that.
     */
    if (!mmc_host_is_spi(host)) {
        err = mmc_select_card(card);
        if (err)
            goto free_card;
    }

    if (!oldcard) {
        /*
         * Fetch SCR from card.
         */
        err = mmc_app_send_scr(card, card->raw_scr);
        if (err)
            goto free_card;

        err = mmc_decode_scr(card);
        if (err < 0)
            goto free_card;
        /*
         * Fetch switch information from card.
         */
#ifdef CONFIG_MMC_PARANOID_SD_INIT
        for (retries = 1; retries <= 3; retries++) {
            err = mmc_read_switch(card);
            if (!err) {
                if (retries > 1) {
                    printk(KERN_WARNING
                           "%s: recovered\n",
                           mmc_hostname(host));
                }
                break;
            } else {
                printk(KERN_WARNING
                       "%s: read switch failed (attempt %d)\n",
                       mmc_hostname(host), retries);
            }
        }
#else
        err = mmc_read_switch(card);
#endif

        if (err)
            goto free_card;
    }

    /*
     * Attempt to change to high-speed (if supported)
     */
    err = mmc_switch_hs(card);
    if (err)
        goto free_card;

    /*
     * Compute bus speed.
     */
    max_dtr = (unsigned int)-1;

    if (mmc_card_highspeed(card)) {
        if (max_dtr > card->sw_caps.hs_max_dtr)
            max_dtr = card->sw_caps.hs_max_dtr;
    } else if (max_dtr > card->csd.max_dtr) {
        max_dtr = card->csd.max_dtr;
    }

    mmc_set_clock(host, max_dtr);

    /*
     * Switch to wider bus (if supported).
     */
    if ((host->caps & MMC_CAP_4_BIT_DATA) &&
            (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
        err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
        if (err)
            goto free_card;

        mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
    }

    /*
     * Check if read-only switch is active.
     */
    if (!oldcard) {
        if (!host->ops->get_ro || host->ops->get_ro(host) < 0) {
            printk(KERN_WARNING "%s: host does not "
                   "support reading read-only "
                   "switch. assuming write-enable.\n",
                   mmc_hostname(host));
        } else {
            if (host->ops->get_ro(host) > 0)
                mmc_card_set_readonly(card);
        }
    }

    if (!oldcard)
        host->card = card;

    return 0;

free_card:
    if (!oldcard)
        mmc_remove_card(card);
err:

    return err;
}
コード例 #5
0
ファイル: core.c プロジェクト: miettal/armadillo420_standard
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;

	mmc_bus_get(host);

	if (host->bus_ops == NULL) {
		/*
		 * 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);
		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);
			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);
	} else {
		if (host->bus_ops->detect && !host->bus_dead)
			host->bus_ops->detect(host);

		mmc_bus_put(host);
	}
out:
	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
コード例 #6
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

}
コード例 #7
0
ファイル: sd.c プロジェクト: WizBang/kernel_acer_a500
/*
 * Starting point for SD card init.
 */
int mmc_attach_sd(struct mmc_host *host)
{
	int err;
	u32 ocr;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	int retries;
#endif

	BUG_ON(!host);
	WARN_ON(!host->claimed);

	/* Make sure we are at 3.3V signalling voltage */
	err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330);
	if (err)
		return err;

	err = mmc_send_app_op_cond(host, 0, &ocr);
	if (err)
		return err;

	mmc_sd_attach_bus_ops(host);
	if (host->ocr_avail_sd)
		host->ocr_avail = host->ocr_avail_sd;

	/*
	 * We need to get OCR a different way for SPI.
	 */
	if (mmc_host_is_spi(host)) {
		mmc_go_idle(host);

		err = mmc_spi_read_ocr(host, 0, &ocr);
		if (err)
			goto err;
	}

	/*
	 * Sanity check the voltages that the card claims to
	 * support.
	 */
	if (ocr & 0x7F) {
		printk(KERN_WARNING "%s: card claims to support voltages "
		       "below the defined range. These will be ignored.\n",
		       mmc_hostname(host));
		ocr &= ~0x7F;
	}

	if ((ocr & MMC_VDD_165_195) &&
	    !(host->ocr_avail_sd & MMC_VDD_165_195)) {
		printk(KERN_WARNING "%s: SD card claims to support the "
		       "incompletely defined 'low voltage range'. This "
		       "will be ignored.\n", mmc_hostname(host));
		ocr &= ~MMC_VDD_165_195;
	}

	host->ocr = mmc_select_voltage(host, ocr);

	/*
	 * Can we support the voltage(s) of the card(s)?
	 */
	if (!host->ocr) {
		err = -EINVAL;
		goto err;
	}

	/*
	 * Detect and init the card.
	 */
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	retries = 5;
	while (retries) {
		err = mmc_sd_init_card(host, host->ocr, NULL);
		if (err) {
			retries--;
			continue;
		}
		break;
	}

	if (!retries) {
		printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n",
		       mmc_hostname(host), err);
		goto err;
	}
#else
	err = mmc_sd_init_card(host, host->ocr, NULL);
	if (err)
		goto err;
#endif

	mmc_release_host(host);
	err = mmc_add_card(host->card);
	mmc_claim_host(host);
	if (err)
		goto remove_card;

	return 0;

remove_card:
	mmc_release_host(host);
	mmc_remove_card(host->card);
	host->card = NULL;
	mmc_claim_host(host);
err:
	mmc_detach_bus(host);

	printk(KERN_ERR "%s: error %d whilst initialising SD card\n",
		mmc_hostname(host), err);

	return err;
}
コード例 #8
0
ファイル: core.c プロジェクト: knone1/Pinaslang-Kernel
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);
	}
}
コード例 #9
0
ファイル: core.c プロジェクト: waninkoko/hero-kernel-2.6.35
void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err = 0;
	int extend_wakelock = 0;
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	int retries = 2;
#endif

	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;
retry:
	mmc_claim_host(host);

	mmc_power_up(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:
#ifdef CONFIG_MMC_PARANOID_SD_INIT
	if (err && (err != -ENOMEDIUM) && retries) {
		printk(KERN_INFO "%s: Re-scan card rc = %d (retries = %d)\n",
			mmc_hostname(host), err, retries);
		retries--;
		goto retry;
	}
#endif

	if (extend_wakelock)
		wake_lock_timeout(&host->wakelock, 5 * HZ);
	else
		wake_unlock(&host->wakelock);

	if (host->caps & MMC_CAP_NEEDS_POLL)
		mmc_schedule_delayed_work(&host->detect, HZ);
}
コード例 #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);
}
コード例 #11
0
static void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;

	if(fo_k){
		fo_k = 0;
		return;		
	}	 
	
	printk(" mmc_rescan... \n");
	mmc_bus_get(host);

	if (host->bus_ops == NULL) {
		/*
		 * Only we can add a new handler, so it's safe to
		 * release the lock here.
		 */
		if(pollux_gpio_getpin(SDI_CD_IO)) {
			printk("  mmc_rescan 1===> no card \n");
			mmc_bus_put(host);
			return;
		}
		mmc_bus_put(host);
		mmc_claim_host(host);
		mmc_power_up(host);
		if(pollux_gpio_getpin(SDI_CD_IO)) {
			printk("  mmc_rescan 2===> no card \n");
			mmc_power_off(host);
			mmc_release_host(host);
			return;
		}
		
		mmc_go_idle(host);
		mmc_send_if_cond(host, host->ocr_avail);

		err = mmc_send_app_op_cond(host, 0, &ocr);
		if (err == MMC_ERR_NONE) {
			if (mmc_attach_sd(host, ocr)){
				printk("mmc_attach_sd_error .... \n");
				mmc_power_off(host);
				fo_k = 1;
			}						
		} else {
			/*
			 * If we fail to detect any SD cards then try
			 * searching for MMC cards.
			 */
			if(pollux_gpio_getpin(SDI_CD_IO)) {
				printk("  mmc_rescan 4===> no card \n");
				mmc_power_off(host);
				mmc_release_host(host);
				return;
			}
			
			err = mmc_send_op_cond(host, 0, &ocr);
			if (err == MMC_ERR_NONE) {
				if (mmc_attach_mmc(host, ocr))
					mmc_power_off(host);
			} else {
				mmc_power_off(host);
				mmc_release_host(host);
			}
		}
	} else {
		if (host->bus_ops->detect && !host->bus_dead)
			host->bus_ops->detect(host);

		mmc_bus_put(host);
	}
}