From: Chris Ball <cjb@laptop.org>
To: Hein_Tibosch <hein_tibosch@yahoo.es>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Pierre Ossman <pierre@ossman.eu>,
Ben Nizette <bn@niasdigital.com>,
Sascha Hauer <s.hauer@pengutronix.de>,
Adrian Hunter <adrian.hunter@nokia.com>,
linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org,
Matt Fleming <matt@console-pimps.org>
Subject: Re: [PATCH v4] mmc: Make ID freq configurable
Date: Fri, 3 Sep 2010 02:47:57 +0100 [thread overview]
Message-ID: <20100903014757.GA23012@void.printf.net> (raw)
In-Reply-To: <4C80187D.9000304@yahoo.es>
Hi Hein, thanks for resending this,
On Fri, Sep 03, 2010 at 05:34:53AM +0800, Hein_Tibosch wrote:
> In the latest releases of the mmc driver, the freq during initialization
> is set to a fixed 400 Khz. This was reportedly too fast for several
> users. As there doesn't seem to be an ideal frequency which-works-for-all,
> Pierre suggested to let the driver try several frequencies.
>
> This patch implements that idea. It will try mmc-initialization using
> several frequencies from an array 400, 300, 200 and 100.
> I submitted it earlier but it's now adapted to and tested with kernel
> 2.6.36-rc3.
>
> In case SDIO is broken, it'll still try to detect SDMEM, also at different
> freqs.
>
> Signed-off-by: Hein Tibosch <hein_tibosch@yahoo.es>
Reviewed-and-Tested-by: Chris Ball <cjb@laptop.org>
I tested by modifying mmc_send_app_op_cond() to return timeouts for
various frequencies, and verified that the code correctly progresses
through the freqs[] table until reaching host->f_min, and can bring
up the card successfully on any of those retries.
In an earlier mail, you said:
> Here it tries 3 frequencies, which takes 290 ms:
> In a meanwhile it is doing other things, so not much time is wasted.
I decided to check this. If my emulated failing of bringing up a card
at a given frequency is correct, 14ms per frequency attempt is spent in
mdelay() rather than msleep(). I don't think this is a problem, though,
because you only take that hit if you have a card inserted that we're
unable to bring up at the default frequency -- the only alternative
would be to give up on the card.
If a host has no card inserted then we still try to detect a card on
all frequencies, but all of the paths in that case are msleep() rather
than mdelay(), so that's okay.
Two minor checkpatch fixes below:
> ---
> diff -Nurp a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> --- a/drivers/mmc/core/core.c 2010-08-29 23:36:04.000000000 +0800
> +++ b/drivers/mmc/core/core.c 2010-09-03 04:28:52.000000000 +0800
> @@ -907,12 +907,7 @@ static void mmc_power_up(struct mmc_host
> */
> mmc_delay(10);
>
> - if (host->f_min > 400000) {
> - pr_warning("%s: Minimum clock frequency too high for "
> - "identification mode\n", mmc_hostname(host));
> - host->ios.clock = host->f_min;
> - } else
> - host->ios.clock = 400000;
> + host->ios.clock = host->f_init;
>
> host->ios.power_mode = MMC_POWER_ON;
> mmc_set_ios(host);
> @@ -1404,6 +1399,8 @@ void mmc_rescan(struct work_struct *work
> u32 ocr;
> int err;
> unsigned long flags;
> + int i;
> + unsigned freqs[] = { 400000, 300000, 200000, 100000 };
>
> spin_lock_irqsave(&host->lock, flags);
>
> @@ -1443,55 +1440,64 @@ void mmc_rescan(struct work_struct *work
> if (host->ops->get_cd && host->ops->get_cd(host) == 0)
> goto out;
>
> - mmc_claim_host(host);
> + for (i = 0; i < ARRAY_SIZE(freqs); i++) {
> + mmc_claim_host(host);
>
> - mmc_power_up(host);
> - sdio_reset(host);
> - mmc_go_idle(host);
> + if (freqs[i] >= host->f_min)
> + host->f_init = freqs[i];
> + else if (i && freqs[i-1] <= host->f_min)
> + goto out;
> + else
> + host->f_init = host->f_min;
>
> - mmc_send_if_cond(host, host->ocr_avail);
> + printk ("mmc_rescan: trying %u Hz\n", host->f_init);
Need a loglevel here, and an mmc_hostname. Something like:
pr_info("%s: %s: trying to init card at %u Hz\n",
mmc_hostname(host), __func__, host->f_init);
> + mmc_power_up(host);
> + sdio_reset(host);
> + mmc_go_idle(host);
>
> - /*
> - * 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;
> + 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 */
This breaks 80-chars, so:
/*
* 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;
> }
> - 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;
> - }
> + /*
> + * ...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);
> -
> + mmc_release_host(host);
> + mmc_power_off(host);
> + }
> out:
> if (host->caps & MMC_CAP_NEEDS_POLL)
> mmc_schedule_delayed_work(&host->detect, HZ);
> diff -Nurp a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> --- a/include/linux/mmc/host.h 2010-08-29 23:36:04.000000000 +0800
> +++ b/include/linux/mmc/host.h 2010-09-03 00:52:48.000000000 +0800
> @@ -123,6 +123,7 @@ struct mmc_host {
> const struct mmc_host_ops *ops;
> unsigned int f_min;
> unsigned int f_max;
> + unsigned int f_init;
> u32 ocr_avail;
> struct notifier_block pm_notify;
>
> ---
--
Chris Ball <cjb@laptop.org> <http://printf.net/>
One Laptop Per Child
next prev parent reply other threads:[~2010-09-03 1:48 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-02 21:34 [PATCH v4] mmc: Make ID freq configurable Hein_Tibosch
2010-09-03 1:47 ` Chris Ball [this message]
2010-09-03 23:25 ` Andrew Morton
2010-09-05 20:14 ` Matt Fleming
2010-09-05 20:43 ` Chris Ball
2010-09-05 21:22 ` Matt Fleming
2010-09-06 1:37 ` [PATCH v5] " Hein_Tibosch
2010-12-02 11:16 ` [PATCH v4] " Sahitya Tummala
2010-12-02 21:21 ` Hein_Tibosch
2010-12-02 22:38 ` Michal Miroslaw
2010-12-03 5:05 ` stummala
2010-12-03 6:56 ` Michal Miroslaw
2010-12-17 1:09 ` Chris Ball
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100903014757.GA23012@void.printf.net \
--to=cjb@laptop.org \
--cc=adrian.hunter@nokia.com \
--cc=akpm@linux-foundation.org \
--cc=bn@niasdigital.com \
--cc=hein_tibosch@yahoo.es \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=matt@console-pimps.org \
--cc=pierre@ossman.eu \
--cc=s.hauer@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.