From patchwork Wed Oct 21 21:15:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ladislav.Michl@seznam.cz X-Patchwork-Id: 55158 X-Patchwork-Delegate: tony@atomide.com Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9LJFRr9007193 for ; Wed, 21 Oct 2009 19:15:27 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754663AbZJUTPW (ORCPT ); Wed, 21 Oct 2009 15:15:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754220AbZJUTPW (ORCPT ); Wed, 21 Oct 2009 15:15:22 -0400 Received: from smtp.seznam.cz ([77.75.72.43]:40134 "EHLO smtp.seznam.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754172AbZJUTPV (ORCPT ); Wed, 21 Oct 2009 15:15:21 -0400 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=seznam.cz; h=Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To:User-Agent:X-Smtpd:X-Seznam-User:X-QM-Mark; b=NBAST0qqGu4wkzt8NJsWYIU+f8LYJSnSv5SVKW7d20Pg8U4JZd6w3adPJNcbKMPpu B56VbFf8LtroWRV/kNReiMkuLRqKSCzJ+WNXDPIiJliBxscDGa4E4AUXH5JeFHF3/+I uQTOLPU9mADItpOxNjBs5WJgOtdg3IPOlZDYV3s= Received: from debian (34.24.broadband3.iol.cz [85.70.24.34]) by email-relay2.go.seznam.cz (Seznam SMTPD 1.1.7@13984) with ESMTP; Wed, 21 Oct 2009 21:15:11 +0200 (CEST) Received: by debian (sSMTP sendmail emulation); Wed, 21 Oct 2009 23:15:07 +0200 Date: Wed, 21 Oct 2009 23:15:07 +0200 From: Ladislav.Michl@seznam.cz To: Tony Lindgren Cc: linux-omap@vger.kernel.org, juha.yrjola@nokia.com Subject: Re: mmci-omap regressions Message-ID: <20091021211506.GA6498@localhost.localdomain> Reply-To: Ladislav Michl References: <20090112091721.GA11921@michl.2n.cz> <20090112104242.GA9373@atomide.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20090112104242.GA9373@atomide.com> User-Agent: Mutt/1.5.18 (2008-05-17) X-Smtpd: 1.1.7@13984 X-Seznam-User: ladislav.michl@seznam.cz X-QM-Mark: email-qm3<251154691> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 5d773b8..0bcd6b0 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -123,15 +123,16 @@ struct mmc_omap_host { struct mmc_data * data; struct mmc_host * mmc; struct device * dev; - unsigned char id; /* 16xx chips have 2 MMC blocks */ struct clk * iclk; struct clk * fclk; struct resource *mem_res; void __iomem *virt_base; unsigned int phys_base; int irq; + unsigned char id; /* 16xx chips have 2 MMC blocks */ unsigned char bus_mode; unsigned char hw_bus_mode; + unsigned char power_mode; struct work_struct cmd_abort_work; unsigned abort:1; @@ -1233,7 +1234,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) struct mmc_omap_slot *slot = mmc_priv(mmc); struct mmc_omap_host *host = slot->host; int i, dsor; - int clk_enabled; + int clk_enabled, init_stream; mmc_omap_select_slot(slot, 0); @@ -1243,20 +1244,27 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) slot->vdd = ios->vdd; clk_enabled = 0; + init_stream = 0; switch (ios->power_mode) { case MMC_POWER_OFF: + printk("MMC_POWER_OFF\n"); mmc_omap_set_power(slot, 0, ios->vdd); break; case MMC_POWER_UP: + printk("MMC_POWER_UP\n"); /* Cannot touch dsor yet, just power up MMC */ mmc_omap_set_power(slot, 1, ios->vdd); + host->power_mode = ios->power_mode; goto exit; case MMC_POWER_ON: + printk("MMC_POWER_ON\n"); mmc_omap_fclk_enable(host, 1); clk_enabled = 1; - dsor |= 1 << 11; + if (host->power_mode != MMC_POWER_ON) + init_stream = 1; break; } + host->power_mode = ios->power_mode; if (slot->bus_mode != ios->bus_mode) { if (slot->pdata->set_bus_mode != NULL) @@ -1269,12 +1277,15 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * goes somehow out of sync, and the POW bit is not being set, * which results in the while loop below getting stuck. * Writing to the CON register twice seems to do the trick. */ + if (ios->power_mode == MMC_POWER_ON) + dsor |= 1 << 11; + printk("MMC dsor: %x\n", dsor); for (i = 0; i < 2; i++) OMAP_MMC_WRITE(host, CON, dsor); slot->saved_con = dsor; - if (ios->power_mode == MMC_POWER_ON) { + if (init_stream) { /* worst case at 400kHz, 80 cycles makes 200 microsecs */ - int usecs = 250; + int usecs = 512; /* Send clock cycles, poll completion */ OMAP_MMC_WRITE(host, IE, 0); @@ -1285,8 +1296,8 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) usecs--; } OMAP_MMC_WRITE(host, STAT, 1); + printk("time elapsed: %dus\n", 512 - usecs); } - exit: mmc_omap_release_slot(slot, clk_enabled); } @@ -1445,6 +1456,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); host->id = pdev->id; + host->power_mode = -1; host->mem_res = res; host->irq = irq; @@ -1459,8 +1471,10 @@ static int __init mmc_omap_probe(struct platform_device *pdev) goto err_ioremap; host->iclk = clk_get(&pdev->dev, "ick"); - if (IS_ERR(host->iclk)) + if (IS_ERR(host->iclk)) { + ret = PTR_ERR(host->iclk); goto err_free_mmc_host; + } clk_enable(host->iclk); host->fclk = clk_get(&pdev->dev, "fck"); @@ -1500,10 +1514,8 @@ err_free_irq: err_free_fclk: clk_put(host->fclk); err_free_iclk: - if (host->iclk != NULL) { - clk_disable(host->iclk); - clk_put(host->iclk); - } + clk_disable(host->iclk); + clk_put(host->iclk); err_free_mmc_host: iounmap(host->virt_base); err_ioremap: @@ -1529,6 +1541,7 @@ static int mmc_omap_remove(struct platform_device *pdev) host->pdata->cleanup(&pdev->dev); mmc_omap_fclk_enable(host, 0); + free_irq(host->irq, host); clk_put(host->fclk); clk_disable(host->iclk); clk_put(host->iclk);