Пример #1
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 */
int mmc_suspend_host(struct mmc_host *host)
{
	int err = 0;

	if (mmc_bus_needs_resume(host))
		return 0;

	if (host->caps & MMC_CAP_DISABLE)
		cancel_delayed_work(&host->disable);

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {

		/*
		 * A long response time is not acceptable for device drivers
		 * when doing suspend. Prevent mmc_claim_host in the suspend
		 * sequence, to potentially wait "forever" by trying to
		 * pre-claim the host.
		 *
		 * Skip try claim host for SDIO cards, doing so fixes deadlock
		 * conditions. The function driver suspend may again call into
		 * SDIO driver within a different context for enabling power
		 * save mode in the card and hence wait in mmc_claim_host
		 * causing deadlock.
		 */
		if (!(host->card && mmc_card_sdio(host->card)))
			if (!mmc_try_claim_host(host))
				err = -EBUSY;

		if (!err) {
			if (host->bus_ops->suspend)
				err = host->bus_ops->suspend(host);
			if (!(host->card && mmc_card_sdio(host->card)))
				mmc_do_release_host(host);

			if (err == -ENOSYS || !host->bus_ops->resume) {
				/*
				 * We simply "remove" the card in this case.
				 * It will be redetected on resume.
				 */
				if (host->bus_ops->remove)
					host->bus_ops->remove(host);
				mmc_claim_host(host);
				mmc_detach_bus(host);
				mmc_power_off(host);
				mmc_release_host(host);
				host->pm_flags = 0;
				err = 0;
			}
		}
	}
	mmc_bus_put(host);

	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
		mmc_power_off(host);

	return err;
}
Пример #2
0
static ssize_t mmc_ops(struct file *file,
			const char __user * buffer, size_t count, loff_t * ppos)
{
	struct seq_file *s = (struct seq_file *)file->private_data;
	struct mmc_host *host = s->private;

	if (!strncmp(buffer, "d", 1)) {
		printk(KERN_INFO "Dump SDHCI registers.");
		host->ops->dump_regs(host);
	} else if (!strncmp(buffer, "t", 1)) {
		printk(KERN_INFO "Trigger one SDIO interrupt.\n");
		if (!host->card && !mmc_card_sdio(host->card)) {
			printk(KERN_INFO "\tNo SDIO card.");
		} else {
			host->ops->trigger_sdio_irq(host);
		}
	} else if (!strncmp(buffer, "r", 1)) {
		printk(KERN_INFO "Rescan the bus.\n");
		host->ops->rescan_bus(host);
	} else {
		printk(KERN_INFO "not supported\n");
		mmc_ops_usage(NULL, NULL);
	}

	return count;
}
Пример #3
0
/**
 *	mmc_set_data_timeout - set the timeout for a data command
 *	@data: data phase for command
 *	@card: the MMC card associated with the data transfer
 *
 *	Computes the data timeout parameters according to the
 *	correct algorithm given the card type.
 */
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
{
    unsigned int mult;

    /*
     * SDIO cards only define an upper 1 s limit on access.
     */
    if (mmc_card_sdio(card)) {
        data->timeout_ns = 1000000000;
        data->timeout_clks = 0;
        return;
    }

    /*
     * SD cards use a 100 multiplier rather than 10
     */
    mult = mmc_card_sd(card) ? 100 : 10;

    /*
     * Scale up the multiplier (and therefore the timeout) by
     * the r2w factor for writes.
     */
    if (data->flags & MMC_DATA_WRITE)
        mult <<= card->csd.r2w_factor;

    data->timeout_ns = card->csd.tacc_ns * mult;
    data->timeout_clks = card->csd.tacc_clks * mult;

    /*
     * SD cards also have an upper limit on the timeout.
     */
    if (mmc_card_sd(card)) {
        unsigned int timeout_us, limit_us;

        timeout_us = data->timeout_ns / 1000;
        timeout_us += data->timeout_clks * 1000 /
                      (card->host->ios.clock / 1000);

        if (data->flags & MMC_DATA_WRITE)
            /*
             * The limit is really 250 ms, but that is
             * insufficient for some crappy cards.
             */
#ifdef CONFIG_LGE_MMC_WORKAROUND
            limit_us = 500000;
#else
            limit_us = 300000;
#endif
        else
            limit_us = 100000;

        /*
         * SDHC cards always use these fixed values.
         */
        if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
            data->timeout_ns = limit_us * 1000;
            data->timeout_clks = 0;
        }
    }
Пример #4
0
static void sprd_sdio_card_remove(struct mmc_card *card) {
    struct mmc_host *host = card->host;
    if (mmc_card_sdio(card)) {
        if(host->caps & MMC_CAP_POWER_OFF_CARD) {
            pm_suspend_ignore_children(mmc_classdev(host), true);  
            pm_runtime_idle(mmc_classdev(host)); 
        }
    }
}
Пример #5
0
static void sprd_sdio_card_remove(struct mmc_card *card) {
    struct mmc_host *host = card->host;
    if (mmc_card_sdio(card)) {
        if(host->caps & MMC_CAP_POWER_OFF_CARD) {
            pm_suspend_ignore_children(mmc_classdev(host), true);  // avoid mmc_attach_sdio->pm_runtime_set_active returning with error -16
            pm_runtime_idle(mmc_classdev(host)); // make platform devices runtime suspendable
        }
    }
}
Пример #6
0
static void  sdhci_host_wakeup_clear(struct sdhci_host *host)
{
       if( (host->mmc->card )&& mmc_card_sdio(host->mmc->card) ){
		disable_irq_wake(sdio_wakeup_irq);
		free_irq(sdio_wakeup_irq, host);
		gpio_free(HOST_WAKEUP_GPIO);
		sdhci_set_gpio_to_data1(host);
        }
	return;
}
Пример #7
0
static int sprd_sdio_card_probe(struct mmc_card *card) {
    struct mmc_host *host = card->host;
    if (mmc_card_sdio(card)) {
        if(host->caps & MMC_CAP_POWER_OFF_CARD) {
            pm_runtime_no_callbacks(&card->dev); 
            pm_suspend_ignore_children(mmc_classdev(host), false); 
            return 0;
        }
    }
    return -EINVAL;
}
Пример #8
0
static int sprd_sdio_card_probe(struct mmc_card *card) {
    struct mmc_host *host = card->host;
    if (mmc_card_sdio(card)) {
        if(host->caps & MMC_CAP_POWER_OFF_CARD) {
            pm_runtime_no_callbacks(&card->dev); // avoid default sdio bus runtime calling
            pm_suspend_ignore_children(mmc_classdev(host), false); // paired with remove function
        }
        return 0;
    }
    return -EINVAL;
}
Пример #9
0
/**
 *	mmc_set_data_timeout - set the timeout for a data command
 *	@data: data phase for command
 *	@card: the MMC card associated with the data transfer
 *	@write: flag to differentiate reads from writes
 *
 *	Computes the data timeout parameters according to the
 *	correct algorithm given the card type.
 */
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
			  int write)
{
	unsigned int mult;

	/*
	 * SDIO cards only define an upper 1 s limit on access.
	 */
	if (mmc_card_sdio(card)) {
		data->timeout_ns = 1000000000;
		data->timeout_clks = 0;
		return;
	}

	/*
	 * SD cards use a 100 multiplier rather than 10
	 */
	mult = mmc_card_sd(card) ? 100 : 10;

	/*
	 * Scale up the multiplier (and therefore the timeout) by
	 * the r2w factor for writes.
	 */
	if (write)
		mult <<= card->csd.r2w_factor;

	data->timeout_ns = card->csd.tacc_ns * mult;
	data->timeout_clks = card->csd.tacc_clks * mult;

	/*
	 * SD cards also have an upper limit on the timeout.
	 */
	if (mmc_card_sd(card)) {
		unsigned int timeout_us, limit_us;

		timeout_us = data->timeout_ns / 1000;
		timeout_us += data->timeout_clks * 1000 /
			(card->host->ios.clock / 1000);

		if (write)
			limit_us = 250000;
		else
			limit_us = 100000;

		/*
		 * SDHC cards always use these fixed values.
		 */
		if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
			data->timeout_ns = limit_us * 1000;
			data->timeout_clks = 0;
		}
	}
}
Пример #10
0
/**
 *	mmc_resume_host - resume a previously suspended host
 *	@host: mmc host
 */
int mmc_resume_host(struct mmc_host *host)
{
#if 0 // kimhyuns remove to recognize card
	// for issue fix for ecim G0100145817
	if(host->bus_dead )
#else
	if((host->bus_dead) && (host->index!=0))
#endif	
	{
		printk("No Suspend resume in case of bus-dead if init failed -- %s \r\n",__FUNCTION__);
		return 0;
	}

	mmc_bus_get(host);
	 if (host->bus_ops && !host->bus_dead) {
		if ( host->card && mmc_card_sdio(host->card)){    //ijihyun.jung -Sec VinsQ
			printk("mmc%d:mmc_resume_host: skip mmc_power_up()\n", host->index);
		} else {
			mmc_power_up(host);
	         }
		mmc_select_voltage(host, host->ocr);//cyj_dc23 -kernel 협의
		BUG_ON(!host->bus_ops->resume);
		host->bus_ops->resume(host);
	} 
	  mmc_bus_put(host); 
	
	 /* 
	  * We add a slight delay here so that resume can progress 
	 * in parallel.
	  */ 
	if ( host->card && mmc_card_sdio(host->card)) {	//ijihyun.jung -Sec VinsQ
	 	printk("mmc%d:mmc_resume_host: skip mmc_detect_change()\n", host->index);
	 }
	 else{
	 	printk("mmc%d:mmc_resume_host: excute mmc_detect_change()\n", host->index);
 		mmc_detect_change(host, 1);  
	 }
	
	return 0;
} 
/**
 *	mmc_resume_host - resume a previously suspended host
 *	@host: mmc host
 */
int mmc_resume_host(struct mmc_host *host)
{
	int err = 0;

	mmc_bus_get(host);
	if (mmc_bus_manual_resume(host)) {
		host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
		mmc_bus_put(host);
		return 0;
	}

	if (host->bus_ops && !host->bus_dead) {
		if (!mmc_card_keep_power(host)) {
			mmc_power_up(host);
			mmc_select_voltage(host, host->ocr);
			/*
			 * Tell runtime PM core we just powered up the card,
			 * since it still believes the card is powered off.
			 * Note that currently runtime PM is only enabled
			 * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
			 */
			if (mmc_card_sdio(host->card) &&
				(host->caps & MMC_CAP_POWER_OFF_CARD)) {
				pm_runtime_disable(&host->card->dev);
				pm_runtime_set_active(&host->card->dev);
				pm_runtime_enable(&host->card->dev);
			}
		}
		BUG_ON(!host->bus_ops->resume);
		err = host->bus_ops->resume(host);
		if (err) {
			printk(KERN_WARNING "%s: error %d during resume "
					    "(card was removed?)\n",
					    mmc_hostname(host), err);
			err = 0;
		}
	}

	/* clear flag */
	host->pm_flags &= ~MMC_PM_KEEP_POWER;
	
	mmc_bus_put(host);

	return err;
}
Пример #12
0
static void  sdhci_host_wakeup_set( struct sdhci_host *host )
{
	unsigned int val;
	int ret;


	if( (host->mmc->card )&& mmc_card_sdio(host->mmc->card) ){
		sdhci_set_data1_to_gpio(host);
		gpio_request(HOST_WAKEUP_GPIO, "host_wakeup_irq");
		sdio_wakeup_irq = gpio_to_irq(HOST_WAKEUP_GPIO);
		gpio_direction_input(HOST_WAKEUP_GPIO);
		ret = request_threaded_irq(sdio_wakeup_irq, sdhci_wakeup_irq_handler, NULL,
			IRQF_TRIGGER_LOW | IRQF_ONESHOT, "host_wakeup_irq", host);
		if(ret){
			printk(KERN_ERR "%s, request threaded irq error:%d\n",
				mmc_hostname(host->mmc), ret);
			return;
		}
		enable_irq_wake(sdio_wakeup_irq);
	}
	return;
}
Пример #13
0
/**
 *	mmc_suspend_host - suspend a host
 *	@host: mmc host
 *	@state: suspend mode (PM_SUSPEND_xxx)
 */
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
#if 0 // kimhyuns remove to recognize card
	// for issue fix for ecim G0100145817
	if(host->bus_dead )
#else
	if((host->bus_dead) && (host->index!=0))
#endif
	{
		printk("No Suspend resume in case of bus-dead if init failed (%s) \r\n",__FUNCTION__);
		return 0;
	}
	printk("Soni calling mmc_flush_scheduled_work (%s)",__FUNCTION__);

	mmc_flush_scheduled_work();

	mmc_bus_get(host);
	if (host->bus_ops && !host->bus_dead) {
		if (host->bus_ops->suspend)
			host->bus_ops->suspend(host);
		if (!host->bus_ops->resume) {
			if (host->bus_ops->remove)
				 host->bus_ops->remove(host);
	
			 mmc_claim_host(host);
			 mmc_detach_bus(host);
                         mmc_release_host(host);
		 }
	}
	 mmc_bus_put(host);

	if (host->card && mmc_card_sdio(host->card)) {  //ijihyun.jung -Sec VinsQ
		printk("mmc%d:mmc_suspend_host: skip mmc_power_off()\n", host->index);
	} else {
		mmc_power_off(host);
	}
				 
	return 0;
}
Пример #14
0
/* Return value = 0 when resume is done
 * Return value = 1 when suspend is done
 */
int mmc_auto_suspend(struct mmc_host *host, int suspend)
{
	int	status = -1;
	unsigned long next_timeout, timeout;
	unsigned long j = jiffies;

	if (host->card && mmc_card_sdio(host->card))
		return -1;

	mutex_lock(&host->auto_suspend_mutex);
	if (suspend) {
		if (host->auto_suspend_state)
			goto out;

		timeout = host->last_busy + host->idle_timeout;
		if (time_after_eq(j, timeout)) {
			host->auto_suspend_state = 1;
			host->ops->auto_suspend(host, 1); /* suspend host */
			status = 1;
			goto out;
		}
	} else {
		host->last_busy = j;
		if (host->auto_suspend_state) {
			host->ops->auto_suspend(host, 0); /* resume host */
			host->auto_suspend_state = 0;
			status = 0;
		}
	}

	if (host->idle_timeout >= 0) {
		next_timeout = host->idle_timeout - (j - host->last_busy);
		mmc_schedule_autosuspend(host, next_timeout);
	}
out:
	mutex_unlock(&host->auto_suspend_mutex);
	return status;
}
Пример #15
0
inline static int sslsd_card_type(struct mmc_card *card)
/**<
this is a safe card type check as during initialization, there is no card
@param[in]	card	card
@return		SSLSD_CARD_XXX bitmap flag
*/
{
	int	flag;

	if (!card)
	{
		return 0;
	}
	flag = 0;
	if (mmc_card_sdio(card))
	{
		flag = SSLSD_CARD_SDIO;
	}
	if (mmc_card_blockaddr(card))
	{
		flag |= SSLSD_CARD_BLKADR;
	}
	return flag;
}
/*
 * Register a new MMC card with the driver model.
 */
int mmc_add_card(struct mmc_card *card)
{
	int ret;
	const char *type;
	const char *uhs_bus_speed_mode = "";
	static const char *const uhs_speeds[] = {
		[UHS_SDR12_BUS_SPEED] = "SDR12 ",
		[UHS_SDR25_BUS_SPEED] = "SDR25 ",
		[UHS_SDR50_BUS_SPEED] = "SDR50 ",
		[UHS_SDR104_BUS_SPEED] = "SDR104 ",
		[UHS_DDR50_BUS_SPEED] = "DDR50 ",
	};


	dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca);

	switch (card->type) {
	case MMC_TYPE_MMC:
		type = "MMC";
		break;
	case MMC_TYPE_SD:
		type = "SD";
		if (mmc_card_blockaddr(card)) {
			if (mmc_card_ext_capacity(card))
				type = "SDXC";
			else
				type = "SDHC";
		}
		break;
	case MMC_TYPE_SDIO:
		type = "SDIO";
		break;
	case MMC_TYPE_SD_COMBO:
		type = "SD-combo";
		if (mmc_card_blockaddr(card))
			type = "SDHC-combo";
		break;
	default:
		type = "?";
		break;
	}

	if (mmc_sd_card_uhs(card) &&
		(card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
		uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];

	if (mmc_host_is_spi(card->host)) {
		pr_info("%s: new %s%s%s card on SPI\n",
			mmc_hostname(card->host),
			mmc_card_highspeed(card) ? "high speed " : "",
			mmc_card_ddr_mode(card) ? "DDR " : "",
			type);
	} else {
		EMMCSD_LOG_INFO("%s: new %s%s%s%s%s%s card at address %04x\n",
			mmc_hostname(card->host),
			mmc_card_uhs(card) ? "ultra high speed " :
			(mmc_card_highspeed(card) ? "high speed " : ""),
			(mmc_card_hs400(card) ? "HS400 " : ""),
			(mmc_card_hs200(card) ? "HS200 " : ""),
			mmc_card_ddr_mode(card) ? "DDR " : "",
			uhs_bus_speed_mode, type, card->rca);
	}

#ifdef CONFIG_DEBUG_FS
	mmc_add_card_debugfs(card);
#endif
	mmc_init_context_info(card->host);

	ret = pm_runtime_set_active(&card->dev);
	if (ret)
		pr_err("%s: %s: failed setting runtime active: ret: %d\n",
		       mmc_hostname(card->host), __func__, ret);
	else if (!mmc_card_sdio(card) && mmc_use_core_runtime_pm(card->host))
		pm_runtime_enable(&card->dev);

	if (mmc_card_sdio(card)) {
		ret = device_init_wakeup(&card->dev, true);
		if (ret)
			pr_err("%s: %s: failed to init wakeup: %d\n",
			       mmc_hostname(card->host), __func__, ret);
	}
	ret = device_add(&card->dev);
	if (ret)
		return ret;

	device_enable_async_suspend(&card->dev);
	if (mmc_use_core_runtime_pm(card->host) && !mmc_card_sdio(card)) {
		card->rpm_attrib.show = show_rpm_delay;
		card->rpm_attrib.store = store_rpm_delay;
		sysfs_attr_init(&card->rpm_attrib.attr);
		card->rpm_attrib.attr.name = "runtime_pm_timeout";
		card->rpm_attrib.attr.mode = S_IRUGO | S_IWUSR;

		ret = device_create_file(&card->dev, &card->rpm_attrib);
		if (ret)
			pr_err("%s: %s: creating runtime pm sysfs entry: failed: %d\n",
			       mmc_hostname(card->host), __func__, ret);
		/* Default timeout is 10 seconds */
		card->idle_timeout = RUNTIME_SUSPEND_DELAY_MS;
	}

	mmc_card_set_present(card);

	return 0;
}
Пример #17
0
Файл: mmci.c Проект: Lyude/linux
static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
{
	struct variant_data *variant = host->variant;
	unsigned int datactrl, timeout, irqmask;
	unsigned long long clks;
	void __iomem *base;
	int blksz_bits;

	dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
		data->blksz, data->blocks, data->flags);

	host->data = data;
	host->size = data->blksz * data->blocks;
	data->bytes_xfered = 0;

	clks = (unsigned long long)data->timeout_ns * host->cclk;
	do_div(clks, NSEC_PER_SEC);

	timeout = data->timeout_clks + (unsigned int)clks;

	base = host->base;
	writel(timeout, base + MMCIDATATIMER);
	writel(host->size, base + MMCIDATALENGTH);

	blksz_bits = ffs(data->blksz) - 1;
	BUG_ON(1 << blksz_bits != data->blksz);

	if (variant->blksz_datactrl16)
		datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
	else if (variant->blksz_datactrl4)
		datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
	else
		datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;

	if (data->flags & MMC_DATA_READ)
		datactrl |= MCI_DPSM_DIRECTION;

	if (host->mmc->card && mmc_card_sdio(host->mmc->card)) {
		u32 clk;

		datactrl |= variant->datactrl_mask_sdio;

		/*
		 * The ST Micro variant for SDIO small write transfers
		 * needs to have clock H/W flow control disabled,
		 * otherwise the transfer will not start. The threshold
		 * depends on the rate of MCLK.
		 */
		if (variant->st_sdio && data->flags & MMC_DATA_WRITE &&
		    (host->size < 8 ||
		     (host->size <= 8 && host->mclk > 50000000)))
			clk = host->clk_reg & ~variant->clkreg_enable;
		else
			clk = host->clk_reg | variant->clkreg_enable;

		mmci_write_clkreg(host, clk);
	}

	if (host->mmc->ios.timing == MMC_TIMING_UHS_DDR50 ||
	    host->mmc->ios.timing == MMC_TIMING_MMC_DDR52)
		datactrl |= variant->datactrl_mask_ddrmode;

	/*
	 * Attempt to use DMA operation mode, if this
	 * should fail, fall back to PIO mode
	 */
	if (!mmci_dma_start_data(host, datactrl))
		return;

	/* IRQ mode, map the SG list for CPU reading/writing */
	mmci_init_sg(host, data);

	if (data->flags & MMC_DATA_READ) {
		irqmask = MCI_RXFIFOHALFFULLMASK;

		/*
		 * If we have less than the fifo 'half-full' threshold to
		 * transfer, trigger a PIO interrupt as soon as any data
		 * is available.
		 */
		if (host->size < variant->fifohalfsize)
			irqmask |= MCI_RXDATAAVLBLMASK;
	} else {
		/*
		 * We don't actually need to include "FIFO empty" here
		 * since its implicit in "FIFO half empty".
		 */
		irqmask = MCI_TXFIFOHALFEMPTYMASK;
	}

	mmci_write_datactrlreg(host, datactrl);
	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
	mmci_set_mask1(host, irqmask);
}
Пример #18
0
/**
 * mmc_init_queue - initialise a queue structure.
 * @mq: mmc queue
 * @card: mmc card to attach this queue
 * @lock: queue lock
 *
 * Initialise a MMC card request queue.
 */
int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
{
	struct mmc_host *host = card->host;
	u64 limit = BLK_BOUNCE_HIGH;
	int ret;

	if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
		limit = *mmc_dev(host)->dma_mask;

	mq->card = card;
	mq->queue = blk_init_queue(mmc_request, lock);
	if (!mq->queue)
		return -ENOMEM;

	mq->queue->queuedata = mq;
	mq->req = NULL;

	blk_queue_prep_rq(mq->queue, mmc_prep_request);
	blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL);
	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);

#ifdef CONFIG_MMC_BLOCK_BOUNCE
	if (host->max_hw_segs == 1) {
		unsigned int bouncesz;

		bouncesz = MMC_QUEUE_BOUNCESZ;

		if (bouncesz > host->max_req_size)
			bouncesz = host->max_req_size;
		if (bouncesz > host->max_seg_size)
			bouncesz = host->max_seg_size;
		if (bouncesz > (host->max_blk_count * 512))
			bouncesz = host->max_blk_count * 512;

		if (bouncesz > 512) {
			mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
			if (!mq->bounce_buf) {
				printk(KERN_WARNING "%s: unable to "
					"allocate bounce buffer\n",
					mmc_card_name(card));
			}
		}

		if (mq->bounce_buf) {
			blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY);
			blk_queue_max_sectors(mq->queue, bouncesz / 512);
			blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
			blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
			blk_queue_max_segment_size(mq->queue, bouncesz);

			mq->sg = kmalloc(sizeof(struct scatterlist),
				GFP_KERNEL);
			if (!mq->sg) {
				ret = -ENOMEM;
				goto cleanup_queue;
			}
			sg_init_table(mq->sg, 1);

			mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
				bouncesz / 512, GFP_KERNEL);
			if (!mq->bounce_sg) {
				ret = -ENOMEM;
				goto cleanup_queue;
			}
			sg_init_table(mq->bounce_sg, bouncesz / 512);
		}
	}
#endif

	if (!mq->bounce_buf) {
		blk_queue_bounce_limit(mq->queue, limit);
		blk_queue_max_sectors(mq->queue,
			min(host->max_blk_count, host->max_req_size / 512));
		blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
		blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
		blk_queue_max_segment_size(mq->queue, host->max_seg_size);

		mq->sg = kmalloc(sizeof(struct scatterlist) *
			host->max_phys_segs, GFP_KERNEL);
		if (!mq->sg) {
			ret = -ENOMEM;
			goto cleanup_queue;
		}
		sg_init_table(mq->sg, host->max_phys_segs);
	}

	init_MUTEX(&mq->thread_sem);

	if (is_svlte_type_mmc_card(card))
		mq->thread = kthread_run(mmc_queue_thread, mq, "svlte-qd");
	else if (mmc_card_sd(card))
		mq->thread = kthread_run(mmc_queue_thread, mq, "sd-qd");
	else if (mmc_card_mmc(card))
		mq->thread = kthread_run(mmc_queue_thread, mq, "emmc-qd");
	else if (mmc_card_sdio(card))
		mq->thread = kthread_run(mmc_queue_thread, mq, "sdio-qd");
	else
		mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd");

	if (IS_ERR(mq->thread)) {
		ret = PTR_ERR(mq->thread);
		goto free_bounce_sg;
	}

	return 0;
 free_bounce_sg:
 	if (mq->bounce_sg)
 		kfree(mq->bounce_sg);
 	mq->bounce_sg = NULL;
 cleanup_queue:
 	if (mq->sg)
		kfree(mq->sg);
	mq->sg = NULL;
	if (mq->bounce_buf)
		kfree(mq->bounce_buf);
	mq->bounce_buf = NULL;
	blk_cleanup_queue(mq->queue);
	return ret;
}
Пример #19
0
/*
 * This hook just adds a quirk for all sdio devices
 */
static void add_quirk_for_sdio_devices(struct mmc_card *card, int data)
{
	if (mmc_card_sdio(card))
		card->quirks |= data;
}
Пример #20
0
/**
 *	
 * added this from linux 3.10 to get better performance for 64 gb sd cards cheers Jukkaman
 * mmc_set_data_timeout - set the timeout for a data command
 *	@data: data phase for command
 *	@card: the MMC card associated with the data transfer
 *
 *	Computes the data timeout parameters according to the
 *	correct algorithm given the card type.
 */
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
{
	unsigned int mult;

	/*
	 * SDIO cards only define an upper 1 s limit on access.
	 */
	if (mmc_card_sdio(card)) {
		data->timeout_ns = 1000000000;
		data->timeout_clks = 0;
		return;
	}

	/*
	 * SD cards use a 100 multiplier rather than 10
	 */
	mult = mmc_card_sd(card) ? 100 : 10;

	/*
	 * Scale up the multiplier (and therefore the timeout) by
	 * the r2w factor for writes.
	 */
	if (data->flags & MMC_DATA_WRITE)
		mult <<= card->csd.r2w_factor;

	data->timeout_ns = card->csd.tacc_ns * mult;
	data->timeout_clks = card->csd.tacc_clks * mult;

	/*
	 * SD cards also have an upper limit on the timeout.
	 */
	if (mmc_card_sd(card)) {
		unsigned int timeout_us, limit_us;

		timeout_us = data->timeout_ns / 1000;
		if (mmc_host_clk_rate(card->host))
			timeout_us += data->timeout_clks * 1000 /
				(mmc_host_clk_rate(card->host) / 1000);

		if (data->flags & MMC_DATA_WRITE)
			/*
			 * The MMC spec "It is strongly recommended
			 * for hosts to implement more than 500ms
			 * timeout value even if the card indicates
			 * the 250ms maximum busy length."  Even the
			 * previous value of 300ms is known to be
			 * insufficient for some cards.
			 */
			limit_us = 3000000;
		else
			limit_us = 100000;

		/*
		 * SDHC cards always use these fixed values.
		 */
		if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
			data->timeout_ns = limit_us * 1000;
			data->timeout_clks = 0;
		}
	}

	/*
	 * Some cards require longer data read timeout than indicated in CSD.
	 * Address this by setting the read timeout to a "reasonably high"
	 * value. For the cards tested, 300ms has proven enough. If necessary,
	 * this value can be increased if other problematic cards require this.
	 */
	if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) {
		data->timeout_ns = 300000000;
		data->timeout_clks = 0;
	}

	/*
	 * Some cards need very high timeouts if driven in SPI mode.
	 * The worst observed timeout was 900ms after writing a
	 * continuous stream of data until the internal logic
	 * overflowed.
	 */
	if (mmc_host_is_spi(card->host)) {
		if (data->flags & MMC_DATA_WRITE) {
			if (data->timeout_ns < 1000000000)
				data->timeout_ns = 1000000000;	/* 1s */
		} else {
			if (data->timeout_ns < 100000000)
				data->timeout_ns =  100000000;	/* 100ms */
		}
	}
}
Пример #21
0
/**
 *	mmc_set_data_timeout - set the timeout for a data command
 *	@data: data phase for command
 *	@card: the MMC card associated with the data transfer
 *
 *	Computes the data timeout parameters according to the
 *	correct algorithm given the card type.
 */
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
{
	unsigned int mult;

	/*
	 * SDIO cards only define an upper 1 s limit on access.
	 */
	if (mmc_card_sdio(card)) {
		data->timeout_ns = 1000000000;
		data->timeout_clks = 0;
		return;
	}

	/*
	 * SD cards use a 100 multiplier rather than 10
	 */
	mult = mmc_card_sd(card) ? 100 : 10;

	/*
	 * Scale up the multiplier (and therefore the timeout) by
	 * the r2w factor for writes.
	 */
	if (data->flags & MMC_DATA_WRITE)
		mult <<= card->csd.r2w_factor;

	data->timeout_ns = card->csd.tacc_ns * mult;
	data->timeout_clks = card->csd.tacc_clks * mult;

	/*
	 * SD cards also have an upper limit on the timeout.
	 */
	if (mmc_card_sd(card)) {
		unsigned int timeout_us, limit_us;

		timeout_us = data->timeout_ns / 1000;
		timeout_us += data->timeout_clks * 1000 /
			(card->host->ios.clock / 1000);

		if (data->flags & MMC_DATA_WRITE)
			/*
			 * The limit is really 250 ms, but that is
			 * insufficient for some crappy cards.
			 */
			limit_us = 300000;
		else
			limit_us = 100000;

		/*
		 * SDHC cards always use these fixed values.
		 */
		if (timeout_us > limit_us || mmc_card_blockaddr(card)) {
			data->timeout_ns = limit_us * 1000;
			data->timeout_clks = 0;
		}
	}
	/*
	 * Some cards need very high timeouts if driven in SPI mode.
	 * The worst observed timeout was 900ms after writing a
	 * continuous stream of data until the internal logic
	 * overflowed.
	 */
	if (mmc_host_is_spi(card->host)) {
		if (data->flags & MMC_DATA_WRITE) {
			if (data->timeout_ns < 1000000000)
				data->timeout_ns = 1000000000;	/* 1s */
		} else {
			if (data->timeout_ns < 100000000)
				data->timeout_ns =  100000000;	/* 100ms */
		}
	}
}
Пример #22
0
/*
 * Register a new MMC card with the driver model.
 */
int mmc_add_card(struct mmc_card *card)
{
	int ret;
	const char *type;
	const char *uhs_bus_speed_mode = "";
	static const char *const uhs_speeds[] = {
		[UHS_SDR12_BUS_SPEED] = "SDR12 ",
		[UHS_SDR25_BUS_SPEED] = "SDR25 ",
		[UHS_SDR50_BUS_SPEED] = "SDR50 ",
		[UHS_SDR104_BUS_SPEED] = "SDR104 ",
		[UHS_DDR50_BUS_SPEED] = "DDR50 ",
	};


	dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca);

	switch (card->type) {
	case MMC_TYPE_MMC:
		type = "MMC";
		break;
	case MMC_TYPE_SD:
		type = "SD";
		if (mmc_card_blockaddr(card)) {
			if (mmc_card_ext_capacity(card))
				type = "SDXC";
			else
				type = "SDHC";
		}
		break;
	case MMC_TYPE_SDIO:
		type = "SDIO";
		break;
	case MMC_TYPE_SD_COMBO:
		type = "SD-combo";
		if (mmc_card_blockaddr(card))
			type = "SDHC-combo";
		break;
	default:
		type = "?";
		break;
	}

	if (mmc_sd_card_uhs(card) &&
		(card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
		uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];

	if (mmc_host_is_spi(card->host)) {
		pr_info("%s: new %s%s%s card on SPI\n",
			mmc_hostname(card->host),
			mmc_card_highspeed(card) ? "high speed " : "",
			mmc_card_ddr_mode(card) ? "DDR " : "",
			type);
	} else {
		pr_info("%s: new %s%s%s%s%s%s card at address %04x\n",
			mmc_hostname(card->host),
			mmc_card_uhs(card) ? "ultra high speed " :
			(mmc_card_highspeed(card) ? "high speed " : ""),
			(mmc_card_hs400(card) ? "HS400 " : ""),
			(mmc_card_hs200(card) ? "HS200 " : ""),
			mmc_card_ddr_mode(card) ? "DDR " : "",
			uhs_bus_speed_mode, type, card->rca);
	}

#ifdef CONFIG_MACH_LGE
	/* LGE_CHANGE
	 * Adding Print for more information.
	 * 2014-09-01, [email protected]
	 */
	printk(KERN_INFO "[LGE][MMC][%-18s( )] mmc_hostname:%s, type:%s\n", __func__, mmc_hostname(card->host), type);
#endif

#ifdef CONFIG_DEBUG_FS
	mmc_add_card_debugfs(card);
#endif
	mmc_init_context_info(card->host);

	ret = pm_runtime_set_active(&card->dev);
	if (ret)
		pr_err("%s: %s: failed setting runtime active: ret: %d\n",
		       mmc_hostname(card->host), __func__, ret);
	else if (!mmc_card_sdio(card) && mmc_use_core_runtime_pm(card->host))
		pm_runtime_enable(&card->dev);

	if (mmc_card_sdio(card)) {
		ret = device_init_wakeup(&card->dev, true);
		if (ret)
			pr_err("%s: %s: failed to init wakeup: %d\n",
			       mmc_hostname(card->host), __func__, ret);
	}
	ret = device_add(&card->dev);
#ifdef CONFIG_MACH_LGE
	/* LGE_CHANGE
	 * Adding Print for more information.
	 * 2014-09-01, [email protected]
	 */
	if (ret) {
		printk(KERN_INFO "[LGE][MMC][%-18s( )] device_add & uevent posting fail!, ret:%d \n", __func__, ret);
		return ret;
	} else {
		printk(KERN_INFO "[LGE][MMC][%-18s( )] device_add & uevent posting complete!\n", __func__);
	}
#else
	if (ret)
		return ret;
#endif

	device_enable_async_suspend(&card->dev);
#if defined(CONFIG_BCMDHD) || defined (CONFIG_BCMDHD_MODULE)
	if (!strcmp(mmc_hostname(card->host), "mmc2")){
	    device_disable_async_suspend(&card->dev);
	    pr_err("%s: %s: device_disable_async_suspend\n", mmc_hostname(card->host),__func__);
	}
#endif
	if (mmc_use_core_runtime_pm(card->host) && !mmc_card_sdio(card)) {
		card->rpm_attrib.show = show_rpm_delay;
		card->rpm_attrib.store = store_rpm_delay;
		sysfs_attr_init(&card->rpm_attrib.attr);
		card->rpm_attrib.attr.name = "runtime_pm_timeout";
		card->rpm_attrib.attr.mode = S_IRUGO | S_IWUSR;

		ret = device_create_file(&card->dev, &card->rpm_attrib);
		if (ret)
			pr_err("%s: %s: creating runtime pm sysfs entry: failed: %d\n",
			       mmc_hostname(card->host), __func__, ret);
		/* Default timeout is 10 seconds */
		card->idle_timeout = RUNTIME_SUSPEND_DELAY_MS;
	}

	mmc_card_set_present(card);

	return 0;
}