All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework
@ 2011-08-18 12:23 Mika Westerberg
  2011-08-18 12:23 ` [PATCH v2 1/3] mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release} Mika Westerberg
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Mika Westerberg @ 2011-08-18 12:23 UTC (permalink / raw)
  To: linux-mmc; +Cc: cjb, linus.walleij, linux-kernel, Mika Westerberg

Hi,

This is an updated series which should fix few races seen when aggressive
clock gating is active. The first patch actually just renames the gating
functions to make their use-cases a bit more clear.

Second and third patches fix the races itself.

Previous version of the series can be seen here
	http://article.gmane.org/gmane.linux.kernel.mmc/9611

Changes to previous version:
	* rename clock gating functions
	* use mmc_host_clk_hold() and mmc_host_clk_release() to protect the
	  ios updates
	* use non-reentrant workqueue instead of the default

Please review, thanks.

Mika Westerberg (3):
  mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release}
  mmc: prevent aggressive clock gating to race with ios updates
  mmc: use non-reentrant workqueue for clock gating

 drivers/mmc/core/core.c |   35 +++++++++++++++++++++++++++++++----
 drivers/mmc/core/host.c |   12 ++++++------
 drivers/mmc/core/host.h |    8 ++++----
 3 files changed, 41 insertions(+), 14 deletions(-)

-- 
1.7.5.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/3] mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release}
  2011-08-18 12:23 [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Mika Westerberg
@ 2011-08-18 12:23 ` Mika Westerberg
  2011-08-18 12:23 ` [PATCH v2 2/3] mmc: prevent aggressive clock gating to race with ios updates Mika Westerberg
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mika Westerberg @ 2011-08-18 12:23 UTC (permalink / raw)
  To: linux-mmc; +Cc: cjb, linus.walleij, linux-kernel, Mika Westerberg

As per suggestion by Linus Walleij:

	> If you think the names of the functions are confusing then
	> you may rename them, say like this:
	>
	> mmc_host_clk_ungate() -> mmc_host_clk_hold()
	> mmc_host_clk_gate() -> mmc_host_clk_release()
	>
	> Which would make the usecases more clear

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mmc/core/core.c |    4 ++--
 drivers/mmc/core/host.c |   10 +++++-----
 drivers/mmc/core/host.h |    8 ++++----
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 91a0a74..63ffc65 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -133,7 +133,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
 		if (mrq->done)
 			mrq->done(mrq);
 
-		mmc_host_clk_gate(host);
+		mmc_host_clk_release(host);
 	}
 }
 
@@ -192,7 +192,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 			mrq->stop->mrq = mrq;
 		}
 	}
-	mmc_host_clk_ungate(host);
+	mmc_host_clk_hold(host);
 	led_trigger_event(host->led, LED_FULL);
 	host->ops->request(host, mrq);
 }
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b29d3e8..96a26b2 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -119,14 +119,14 @@ static void mmc_host_clk_gate_work(struct work_struct *work)
 }
 
 /**
- *	mmc_host_clk_ungate - ungate hardware MCI clocks
+ *	mmc_host_clk_hold - ungate hardware MCI clocks
  *	@host: host to ungate.
  *
  *	Makes sure the host ios.clock is restored to a non-zero value
  *	past this call.	Increase clock reference count and ungate clock
  *	if we're the first user.
  */
-void mmc_host_clk_ungate(struct mmc_host *host)
+void mmc_host_clk_hold(struct mmc_host *host)
 {
 	unsigned long flags;
 
@@ -164,14 +164,14 @@ static bool mmc_host_may_gate_card(struct mmc_card *card)
 }
 
 /**
- *	mmc_host_clk_gate - gate off hardware MCI clocks
+ *	mmc_host_clk_release - gate off hardware MCI clocks
  *	@host: host to gate.
  *
  *	Calls the host driver with ios.clock set to zero as often as possible
  *	in order to gate off hardware MCI clocks. Decrease clock reference
  *	count and schedule disabling of clock.
  */
-void mmc_host_clk_gate(struct mmc_host *host)
+void mmc_host_clk_release(struct mmc_host *host)
 {
 	unsigned long flags;
 
@@ -231,7 +231,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host)
 	if (cancel_work_sync(&host->clk_gate_work))
 		mmc_host_clk_gate_delayed(host);
 	if (host->clk_gated)
-		mmc_host_clk_ungate(host);
+		mmc_host_clk_hold(host);
 	/* There should be only one user now */
 	WARN_ON(host->clk_requests > 1);
 }
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
index de199f9..fb8a5cd 100644
--- a/drivers/mmc/core/host.h
+++ b/drivers/mmc/core/host.h
@@ -16,16 +16,16 @@ int mmc_register_host_class(void);
 void mmc_unregister_host_class(void);
 
 #ifdef CONFIG_MMC_CLKGATE
-void mmc_host_clk_ungate(struct mmc_host *host);
-void mmc_host_clk_gate(struct mmc_host *host);
+void mmc_host_clk_hold(struct mmc_host *host);
+void mmc_host_clk_release(struct mmc_host *host);
 unsigned int mmc_host_clk_rate(struct mmc_host *host);
 
 #else
-static inline void mmc_host_clk_ungate(struct mmc_host *host)
+static inline void mmc_host_clk_hold(struct mmc_host *host)
 {
 }
 
-static inline void mmc_host_clk_gate(struct mmc_host *host)
+static inline void mmc_host_clk_release(struct mmc_host *host)
 {
 }
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/3] mmc: prevent aggressive clock gating to race with ios updates
  2011-08-18 12:23 [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Mika Westerberg
  2011-08-18 12:23 ` [PATCH v2 1/3] mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release} Mika Westerberg
@ 2011-08-18 12:23 ` Mika Westerberg
  2011-08-18 12:23 ` [PATCH v2 3/3] mmc: use non-reentrant workqueue for clock gating Mika Westerberg
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Mika Westerberg @ 2011-08-18 12:23 UTC (permalink / raw)
  To: linux-mmc; +Cc: cjb, linus.walleij, linux-kernel, Mika Westerberg

We have seen at least two different races when clock gating kicks in in a
middle of ios structure update.

First one happens when ios->clock is changed outside of aggressive clock
gating framework, for example via mmc_set_clock(). The race might happen
when we run following code:

mmc_set_ios():
	...
	if (ios->clock > 0)
		mmc_set_ungated(host);

Now if gating kicks in right after the condition check we end up setting
host->clk_gated to false even though we have just gated the clock. Next
time a request is started we try to ungate and restore the clock in
mmc_host_clk_hold(). However since we have host->clk_gated set to false the
original clock is not restored.

This eventually will cause the host controller to hang since its clock is
disabled while we are trying to issue a request. For example on Intel
Medfield platform we see:

[   13.818610] mmc2: Timeout waiting for hardware interrupt.
[   13.818698] sdhci: =========== REGISTER DUMP (mmc2)===========
[   13.818753] sdhci: Sys addr: 0x00000000 | Version:  0x00008901
[   13.818804] sdhci: Blk size: 0x00000000 | Blk cnt:  0x00000000
[   13.818853] sdhci: Argument: 0x00000000 | Trn mode: 0x00000000
[   13.818903] sdhci: Present:  0x1fff0000 | Host ctl: 0x00000001
[   13.818951] sdhci: Power:    0x0000000d | Blk gap:  0x00000000
[   13.819000] sdhci: Wake-up:  0x00000000 | Clock:    0x00000000
[   13.819049] sdhci: Timeout:  0x00000000 | Int stat: 0x00000000
[   13.819098] sdhci: Int enab: 0x00ff00c3 | Sig enab: 0x00ff00c3
[   13.819147] sdhci: AC12 err: 0x00000000 | Slot int: 0x00000000
[   13.819196] sdhci: Caps:     0x6bee32b2 | Caps_1:   0x00000000
[   13.819245] sdhci: Cmd:      0x00000000 | Max curr: 0x00000000
[   13.819292] sdhci: Host ctl2: 0x00000000
[   13.819331] sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0x00000000
[   13.819377] sdhci: ===========================================
[   13.919605] mmc2: Reset 0x2 never completed.

and it never recovers.

Second race might happen while running mmc_power_off():

static void mmc_power_off(struct mmc_host *host)
{
	host->ios.clock = 0;
	host->ios.vdd = 0;

[ clock gating kicks in here ]

	/*
	 * Reset ocr mask to be the highest possible voltage supported for
	 * this mmc host. This value will be used at next power up.
	 */
	host->ocr = 1 << (fls(host->ocr_avail) - 1);

	if (!mmc_host_is_spi(host)) {
		host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
		host->ios.chip_select = MMC_CS_DONTCARE;
	}
	host->ios.power_mode = MMC_POWER_OFF;
	host->ios.bus_width = MMC_BUS_WIDTH_1;
	host->ios.timing = MMC_TIMING_LEGACY;
	mmc_set_ios(host);
}

If the clock gating worker kicks in while we are only partially updated the
ios structure the host controller gets incomplete ios and might not work as
supposed. Again on Intel Medfield platform we get:

[    4.185349] kernel BUG at drivers/mmc/host/sdhci.c:1155!
[    4.185422] invalid opcode: 0000 [#1] PREEMPT SMP
[    4.185509] Modules linked in:
[    4.185565]
[    4.185608] Pid: 4, comm: kworker/0:0 Not tainted 3.0.0+ #240 Intel Corporation Medfield/iCDKA
[    4.185742] EIP: 0060:[<c136364e>] EFLAGS: 00010083 CPU: 0
[    4.185827] EIP is at sdhci_set_power+0x3e/0xd0
[    4.185891] EAX: f5ff98e0 EBX: f5ff98e0 ECX: 00000000 EDX: 00000001
[    4.185970] ESI: f5ff977c EDI: f5ff9904 EBP: f644fe98 ESP: f644fe94
[    4.186049]  DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
[    4.186125] Process kworker/0:0 (pid: 4, ti=f644e000 task=f644c0e0 task.ti=f644e000)
[    4.186219] Stack:
[    4.186257]  f5ff98e0 f644feb0 c1365173 00000282 f5ff9460 f5ff96e0 f5ff96e0 f644feec
[    4.186418]  c1355bd8 f644c0e0 c1499c3d f5ff96e0 f644fed4 00000006 f5ff96e0 00000286
[    4.186579]  f644fedc c107922b f644feec 00000286 f5ff9460 f5ff9700 f644ff10 c135839e
[    4.186739] Call Trace:
[    4.186802]  [<c1365173>] sdhci_set_ios+0x1c3/0x340
[    4.186883]  [<c1355bd8>] mmc_gate_clock+0x68/0x120
[    4.186963]  [<c1499c3d>] ? _raw_spin_unlock_irqrestore+0x4d/0x60
[    4.187052]  [<c107922b>] ? trace_hardirqs_on+0xb/0x10
[    4.187134]  [<c135839e>] mmc_host_clk_gate_delayed+0xbe/0x130
[    4.187219]  [<c105ec09>] ? process_one_work+0xf9/0x5b0
[    4.187300]  [<c135841d>] mmc_host_clk_gate_work+0xd/0x10
[    4.187379]  [<c105ec82>] process_one_work+0x172/0x5b0
[    4.187457]  [<c105ec09>] ? process_one_work+0xf9/0x5b0
[    4.187538]  [<c1358410>] ? mmc_host_clk_gate_delayed+0x130/0x130
[    4.187625]  [<c105f3c8>] worker_thread+0x118/0x330
[    4.187700]  [<c1496cee>] ? preempt_schedule+0x2e/0x50
[    4.187779]  [<c105f2b0>] ? rescuer_thread+0x1f0/0x1f0
[    4.187857]  [<c1062cf4>] kthread+0x74/0x80
[    4.187931]  [<c1062c80>] ? __init_kthread_worker+0x60/0x60
[    4.188015]  [<c149acfa>] kernel_thread_helper+0x6/0xd
[    4.188079] Code: 81 fa 00 00 04 00 0f 84 a7 00 00 00 7f 21 81 fa 80 00 00 00 0f 84 92 00 00 00 81 fa 00 00 0
[    4.188780] EIP: [<c136364e>] sdhci_set_power+0x3e/0xd0 SS:ESP 0068:f644fe94
[    4.188898] ---[ end trace a7b23eecc71777e4 ]---

This BUG() comes from the fact that ios.power_mode was still in previous
value (MMC_POWER_ON) and ios.vdd was set to zero.

We prevent these by inhibiting the clock gating while we update the ios
structure.

Both problems can be reproduced by simply running the device in a reboot
loop.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mmc/core/core.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 63ffc65..b27b940 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -728,15 +728,17 @@ static inline void mmc_set_ios(struct mmc_host *host)
  */
 void mmc_set_chip_select(struct mmc_host *host, int mode)
 {
+	mmc_host_clk_hold(host);
 	host->ios.chip_select = mode;
 	mmc_set_ios(host);
+	mmc_host_clk_release(host);
 }
 
 /*
  * Sets the host clock to the highest possible frequency that
  * is below "hz".
  */
-void mmc_set_clock(struct mmc_host *host, unsigned int hz)
+static void __mmc_set_clock(struct mmc_host *host, unsigned int hz)
 {
 	WARN_ON(hz < host->f_min);
 
@@ -747,6 +749,13 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz)
 	mmc_set_ios(host);
 }
 
+void mmc_set_clock(struct mmc_host *host, unsigned int hz)
+{
+	mmc_host_clk_hold(host);
+	__mmc_set_clock(host, hz);
+	mmc_host_clk_release(host);
+}
+
 #ifdef CONFIG_MMC_CLKGATE
 /*
  * This gates the clock by setting it to 0 Hz.
@@ -779,7 +788,7 @@ void mmc_ungate_clock(struct mmc_host *host)
 	if (host->clk_old) {
 		BUG_ON(host->ios.clock);
 		/* This call will also set host->clk_gated to false */
-		mmc_set_clock(host, host->clk_old);
+		__mmc_set_clock(host, host->clk_old);
 	}
 }
 
@@ -807,8 +816,10 @@ void mmc_set_ungated(struct mmc_host *host)
  */
 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
 {
+	mmc_host_clk_hold(host);
 	host->ios.bus_mode = mode;
 	mmc_set_ios(host);
+	mmc_host_clk_release(host);
 }
 
 /*
@@ -816,8 +827,10 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode)
  */
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
 {
+	mmc_host_clk_hold(host);
 	host->ios.bus_width = width;
 	mmc_set_ios(host);
+	mmc_host_clk_release(host);
 }
 
 /**
@@ -1015,8 +1028,10 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
 
 		ocr &= 3 << bit;
 
+		mmc_host_clk_hold(host);
 		host->ios.vdd = bit;
 		mmc_set_ios(host);
+		mmc_host_clk_release(host);
 	} else {
 		pr_warning("%s: host doesn't support card's voltages\n",
 				mmc_hostname(host));
@@ -1063,8 +1078,10 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11
  */
 void mmc_set_timing(struct mmc_host *host, unsigned int timing)
 {
+	mmc_host_clk_hold(host);
 	host->ios.timing = timing;
 	mmc_set_ios(host);
+	mmc_host_clk_release(host);
 }
 
 /*
@@ -1072,8 +1089,10 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
  */
 void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
 {
+	mmc_host_clk_hold(host);
 	host->ios.drv_type = drv_type;
 	mmc_set_ios(host);
+	mmc_host_clk_release(host);
 }
 
 /*
@@ -1091,6 +1110,8 @@ static void mmc_power_up(struct mmc_host *host)
 {
 	int bit;
 
+	mmc_host_clk_hold(host);
+
 	/* If ocr is set, we use it */
 	if (host->ocr)
 		bit = ffs(host->ocr) - 1;
@@ -1126,10 +1147,14 @@ static void mmc_power_up(struct mmc_host *host)
 	 * time required to reach a stable voltage.
 	 */
 	mmc_delay(10);
+
+	mmc_host_clk_release(host);
 }
 
 static void mmc_power_off(struct mmc_host *host)
 {
+	mmc_host_clk_hold(host);
+
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
@@ -1147,6 +1172,8 @@ static void mmc_power_off(struct mmc_host *host)
 	host->ios.bus_width = MMC_BUS_WIDTH_1;
 	host->ios.timing = MMC_TIMING_LEGACY;
 	mmc_set_ios(host);
+
+	mmc_host_clk_release(host);
 }
 
 /*
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/3] mmc: use non-reentrant workqueue for clock gating
  2011-08-18 12:23 [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Mika Westerberg
  2011-08-18 12:23 ` [PATCH v2 1/3] mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release} Mika Westerberg
  2011-08-18 12:23 ` [PATCH v2 2/3] mmc: prevent aggressive clock gating to race with ios updates Mika Westerberg
@ 2011-08-18 12:23 ` Mika Westerberg
  2011-08-19  9:58 ` [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Linus Walleij
  2011-08-19 17:13 ` Chris Ball
  4 siblings, 0 replies; 6+ messages in thread
From: Mika Westerberg @ 2011-08-18 12:23 UTC (permalink / raw)
  To: linux-mmc; +Cc: cjb, linus.walleij, linux-kernel, Mika Westerberg

The default multithread workqueue can cause the same work to be executed
concurrently on a different CPUs. This isn't really suitable for clock
gating as it might already gated the clock and gating it twice results both
host->clk_old and host->ios.clock to be set to 0.

To prevent this from happening we use system_nrt_wq instead.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/mmc/core/host.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 96a26b2..793d0a0 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -179,7 +179,7 @@ void mmc_host_clk_release(struct mmc_host *host)
 	host->clk_requests--;
 	if (mmc_host_may_gate_card(host->card) &&
 	    !host->clk_requests)
-		schedule_work(&host->clk_gate_work);
+		queue_work(system_nrt_wq, &host->clk_gate_work);
 	spin_unlock_irqrestore(&host->clk_lock, flags);
 }
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework
  2011-08-18 12:23 [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Mika Westerberg
                   ` (2 preceding siblings ...)
  2011-08-18 12:23 ` [PATCH v2 3/3] mmc: use non-reentrant workqueue for clock gating Mika Westerberg
@ 2011-08-19  9:58 ` Linus Walleij
  2011-08-19 17:13 ` Chris Ball
  4 siblings, 0 replies; 6+ messages in thread
From: Linus Walleij @ 2011-08-19  9:58 UTC (permalink / raw)
  To: Mika Westerberg; +Cc: linux-mmc, cjb, linux-kernel

On Thu, Aug 18, 2011 at 2:23 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> This is an updated series which should fix few races seen when aggressive
> clock gating is active. The first patch actually just renames the gating
> functions to make their use-cases a bit more clear.

Wow excellent work Mika, this is exactly how we should fix this.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Chris: you get to decide whether we push this for the -rc or -next,
since it fixes a regression for Mika I suggest this should go into -rc.

Thanks a *lot* Mika!
Linus Walleij

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework
  2011-08-18 12:23 [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Mika Westerberg
                   ` (3 preceding siblings ...)
  2011-08-19  9:58 ` [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Linus Walleij
@ 2011-08-19 17:13 ` Chris Ball
  4 siblings, 0 replies; 6+ messages in thread
From: Chris Ball @ 2011-08-19 17:13 UTC (permalink / raw)
  To: Mika Westerberg; +Cc: linux-mmc, linus.walleij, linux-kernel

Hi Mika,

On Thu, Aug 18 2011, Mika Westerberg wrote:
> Hi,
>
> This is an updated series which should fix few races seen when aggressive
> clock gating is active. The first patch actually just renames the gating
> functions to make their use-cases a bit more clear.

Thanks very much!  Pushed to mmc-next for 3.1-rc.

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-08-19 17:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-18 12:23 [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Mika Westerberg
2011-08-18 12:23 ` [PATCH v2 1/3] mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release} Mika Westerberg
2011-08-18 12:23 ` [PATCH v2 2/3] mmc: prevent aggressive clock gating to race with ios updates Mika Westerberg
2011-08-18 12:23 ` [PATCH v2 3/3] mmc: use non-reentrant workqueue for clock gating Mika Westerberg
2011-08-19  9:58 ` [PATCH v2 0/3] mmc: fixes for aggressive clock gating framework Linus Walleij
2011-08-19 17:13 ` Chris Ball

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.