From: Tony Lindgren <tony@atomide.com>
To: Andreas Fenkart <afenkart@gmail.com>
Cc: Chris Ball <cjb@laptop.org>,
Grant Likely <grant.likely@secretlab.ca>,
Felipe Balbi <balbi@ti.com>, Balaji T K <balajitk@ti.com>,
zonque@gmail.com, galak@codeaurora.org,
linux-doc@vger.kernel.org, linux-mmc@vger.kernel.org,
linux-omap@vger.kernel.org
Subject: Re: [PATCH v6 2/3] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x.
Date: Fri, 20 Dec 2013 17:01:16 -0800 [thread overview]
Message-ID: <20131221010115.GJ26054@atomide.com> (raw)
In-Reply-To: <1387193091-23218-3-git-send-email-afenkart@gmail.com>
* Andreas Fenkart <afenkart@gmail.com> [131216 03:29]:
> --- a/drivers/mmc/host/omap_hsmmc.c
> +++ b/drivers/mmc/host/omap_hsmmc.c
> @@ -2098,8 +2186,28 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
> if (pdev->dev.of_node) {
> mmc->caps |= MMC_CAP_SDIO_IRQ;
> if (pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) {
> - /* no wakeup from deeper power states, use polling */
> - mmc->caps &= ~MMC_CAP_SDIO_IRQ;
> + /* use GPIO to wakeup from deeper power states */
> + if (!host->idle || !host->gpio_sdio_irq) {
> + dev_warn(mmc_dev(host->mmc),
> + "Disable SDIO IRQ workaround, GPIO IRQ or pinctrl idle state missing, falling back to polling\n");
> + mmc->caps &= ~MMC_CAP_SDIO_IRQ;
> + } else {
> + host->flags |= HSMMC_SWAKEUP_QUIRK;
> +
> + }
> + }
> +
> + if (host->flags & HSMMC_SWAKEUP_QUIRK) {
> + /* prevent auto-enabling of IRQ */
> + irq_set_status_flags(host->gpio_sdio_irq, IRQ_NOAUTOEN);
> + ret = request_irq(host->gpio_sdio_irq, omap_hsmmc_cirq,
> + IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> + mmc_hostname(mmc), host);
> + if (ret) {
> + dev_err(mmc_dev(host->mmc),
> + "Unable to grab GPIO SDIO IRQ\n");
> + goto err_irq_sdio;
> + }
> }
> }
>
FYI This part needs to be changed a bit for the omaps that have a working
wake-up interrupt. I tried on 3730 with the following patch, but so far it
gets stuck in an infinite SDIO interrupt loop. I'll try to take a look at
it more but may not get to it very soon with the holidays coming up. Also
changed the naming to use wakeirq to make it a bit shorter and generic.
Regards,
Tony
8< ---------------------------------------
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -48,7 +48,7 @@
0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
- 0x12e (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
>;
@@ -81,6 +81,7 @@
};
&mmc2 {
+ interrupts-extended = <&intc 86 &omap3_pmx_core 0x12e>;
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins>;
};
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -395,7 +395,7 @@
mmc2: mmc@480b4000 {
compatible = "ti,omap3-hsmmc";
reg = <0x480b4000 0x200>;
- interrupts = <86>;
+ interrupts-extended = <&intc 86>;
ti,hwmods = "mmc2";
dmas = <&sdma 47>, <&sdma 48>;
dma-names = "tx", "rx";
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 78e7b80..7da1532 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -182,7 +182,7 @@ struct omap_hsmmc_host {
u32 sysctl;
u32 capa;
int irq;
- int gpio_sdio_irq;
+ int wakeirq;
int use_dma, dma_ch;
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
@@ -211,7 +211,7 @@ static irqreturn_t omap_hsmmc_cirq(int irq, void *dev_id)
spin_lock_irqsave(&host->irq_lock, flags);
if (host->flags & HSMMC_CIRQ_GPIO_ENABLED) {
- disable_irq_nosync(host->gpio_sdio_irq);
+ disable_irq_nosync(host->wakeirq);
host->flags &= ~HSMMC_CIRQ_GPIO_ENABLED;
}
spin_unlock_irqrestore(&host->irq_lock, flags);
@@ -1159,7 +1159,8 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
omap_hsmmc_do_irq(host, status);
if (status & CIRQ_EN)
- mmc_signal_sdio_irq(host->mmc);
+ if (host->mmc->sdio_irq_thread)
+ mmc_signal_sdio_irq(host->mmc);
/* Flush posted write */
status = OMAP_HSMMC_READ(host->base, STAT);
@@ -1976,7 +1977,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host->use_dma = 1;
host->dma_ch = -1;
host->irq = irq;
- host->gpio_sdio_irq = irq2;
+ host->wakeirq = irq2;
host->slot_id = 0;
host->mapbase = res->start + pdata->reg_offset;
host->base = ioremap(host->mapbase, SZ_4K);
@@ -2153,20 +2154,19 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
mmc->caps |= MMC_CAP_SDIO_IRQ;
if (pdata->controller_flags & OMAP_HSMMC_SWAKEUP_MISSING) {
/* use GPIO to wakeup from deeper power states */
- if (!host->idle || !host->gpio_sdio_irq) {
+ if (!host->idle || !host->wakeirq) {
dev_warn(mmc_dev(host->mmc),
"Disable SDIO IRQ workaround, GPIO IRQ or pinctrl idle state missing, falling back to polling\n");
mmc->caps &= ~MMC_CAP_SDIO_IRQ;
- } else {
- host->flags |= HSMMC_SWAKEUP_QUIRK;
-
}
}
- if (host->flags & HSMMC_SWAKEUP_QUIRK) {
+ if (host->wakeirq) {
+ host->flags |= HSMMC_SWAKEUP_QUIRK;
+
/* prevent auto-enabling of IRQ */
- irq_set_status_flags(host->gpio_sdio_irq, IRQ_NOAUTOEN);
- ret = request_irq(host->gpio_sdio_irq, omap_hsmmc_cirq,
+ irq_set_status_flags(host->wakeirq, IRQ_NOAUTOEN);
+ ret = request_irq(host->wakeirq, omap_hsmmc_cirq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
mmc_hostname(mmc), host);
if (ret) {
@@ -2201,8 +2201,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
err_slot_name:
mmc_remove_host(mmc);
- if (host->gpio_sdio_irq)
- free_irq(host->gpio_sdio_irq, host);
+ if (host->wakeirq)
+ free_irq(host->wakeirq, host);
err_irq_sdio:
devm_pinctrl_put(host->pinctrl);
err_pinctrl_state:
@@ -2252,8 +2252,8 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
if (host->pdata->cleanup)
host->pdata->cleanup(&pdev->dev);
free_irq(host->irq, host);
- if ((host->gpio_sdio_irq))
- free_irq(host->gpio_sdio_irq, host);
+ if ((host->wakeirq))
+ free_irq(host->wakeirq, host);
if (mmc_slot(host).card_detect_irq)
free_irq(mmc_slot(host).card_detect_irq, host);
if (host->tx_chan)
@@ -2317,7 +2317,7 @@ static int omap_hsmmc_suspend(struct device *dev)
}
if (host->flags & HSMMC_SWAKEUP_QUIRK)
- disable_irq(host->gpio_sdio_irq);
+ disable_irq(host->wakeirq);
if (host->dbclk)
clk_disable_unprepare(host->dbclk);
@@ -2345,7 +2345,7 @@ static int omap_hsmmc_resume(struct device *dev)
omap_hsmmc_protect_card(host);
if (host->flags & HSMMC_SWAKEUP_QUIRK)
- enable_irq(host->gpio_sdio_irq);
+ enable_irq(host->wakeirq);
pm_runtime_mark_last_busy(host->dev);
pm_runtime_put_autosuspend(host->dev);
@@ -2374,13 +2374,16 @@ static int omap_hsmmc_runtime_suspend(struct device *dev)
OMAP_HSMMC_WRITE(host->base, IE, 0);
OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
- ret = pinctrl_select_state(host->pinctrl, host->idle);
- if (ret < 0)
- dev_warn(mmc_dev(host->mmc), "Unable to select idle pinmux\n");
+ if (host->idle) {
+ ret = pinctrl_select_state(host->pinctrl, host->idle);
+ if (ret < 0)
+ dev_warn(mmc_dev(host->mmc),
+ "Unable to select idle pinmux\n");
+ }
spin_lock_irqsave(&host->irq_lock, flags);
if (host->flags & HSMMC_SDIO_IRQ_ENABLED) {
- enable_irq(host->gpio_sdio_irq);
+ enable_irq(host->wakeirq);
host->flags |= HSMMC_CIRQ_GPIO_ENABLED;
}
spin_unlock_irqrestore(&host->irq_lock, flags);
@@ -2403,14 +2406,17 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
spin_lock_irqsave(&host->irq_lock, flags);
if (host->flags & HSMMC_CIRQ_GPIO_ENABLED) {
- disable_irq_nosync(host->gpio_sdio_irq);
+ disable_irq_nosync(host->wakeirq);
host->flags &= ~HSMMC_CIRQ_GPIO_ENABLED;
}
spin_unlock_irqrestore(&host->irq_lock, flags);
- ret = pinctrl_select_state(host->pinctrl, host->active);
- if (ret < 0)
- dev_warn(mmc_dev(host->mmc), "Unable to select active pinmux\n");
+ if (host->active) {
+ ret = pinctrl_select_state(host->pinctrl, host->active);
+ if (ret < 0)
+ dev_warn(mmc_dev(host->mmc),
+ "Unable to select active pinmux\n");
+ }
OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR);
OMAP_HSMMC_WRITE(host->base, ISE, CIRQ_EN);
next prev parent reply other threads:[~2013-12-21 1:01 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-16 11:24 [PATCH v6 0/3] mmc: omap_hsmmc: Enable SDIO IRQ Andreas Fenkart
2013-12-16 11:24 ` [PATCH v6 1/3] " Andreas Fenkart
2013-12-21 0:53 ` Tony Lindgren
2013-12-16 11:24 ` [PATCH v6 2/3] mmc: omap_hsmmc: Pin remux workaround to support SDIO interrupt on AM335x Andreas Fenkart
2013-12-21 1:01 ` Tony Lindgren [this message]
2013-12-16 11:24 ` [PATCH v6 3/3] mmc: omap_hsmmc: Extend debugfs for SDIO IRQ, GPIO and pinmux Andreas Fenkart
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=20131221010115.GJ26054@atomide.com \
--to=tony@atomide.com \
--cc=afenkart@gmail.com \
--cc=balajitk@ti.com \
--cc=balbi@ti.com \
--cc=cjb@laptop.org \
--cc=galak@codeaurora.org \
--cc=grant.likely@secretlab.ca \
--cc=linux-doc@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=zonque@gmail.com \
/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.