1. 11 12月, 2011 4 次提交
  2. 01 11月, 2011 2 次提交
  3. 27 10月, 2011 30 次提交
  4. 01 9月, 2011 4 次提交
    • S
      mmc: sd: UHS-I bus speed should be set last in UHS initialization · 93c712f9
      Subhash Jadavani 提交于
      mmc_sd_init_uhs_card function sets the driver type, current limit
      and bus speed mode on card as well as on host controller side.
      
      Currently bus speed mode is set by sending CMD6 to card and
      immediately setting the timing mode in host controller. But
      then before initiating tuning sequence, it also tries to set
      current limit by sending CMD6 to card which results in data
      timeout errors in controller if bus speed mode is SDR50/SDR104 mode.
      
      So basically bus speed mode should be set only after current limit
      is set in the card and immediately after setting the bus speed mode,
      tuning sequence should be initiated.
      Signed-off-by: NSubhash Jadavani <subhashj@codeaurora.org>
      Reviewed-by: NArindam Nath <arindam.nath@amd.com>
      Signed-off-by: NChris Ball <cjb@laptop.org>
      93c712f9
    • M
      mmc: core: use non-reentrant workqueue for clock gating · 50a50f92
      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: NMika Westerberg <mika.westerberg@linux.intel.com>
      Reviewed-by: NLinus Walleij <linus.walleij@linaro.org>
      Tested-by: NChris Ball <cjb@laptop.org>
      Cc: <stable@kernel.org>
      Signed-off-by: NChris Ball <cjb@laptop.org>
      50a50f92
    • M
      mmc: core: prevent aggressive clock gating racing with ios updates · 778e277c
      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: NMika Westerberg <mika.westerberg@linux.intel.com>
      Reviewed-by: NLinus Walleij <linus.walleij@linaro.org>
      Tested-by: NChris Ball <cjb@laptop.org>
      Cc: <stable@kernel.org>
      Signed-off-by: NChris Ball <cjb@laptop.org>
      778e277c
    • M
      mmc: rename mmc_host_clk_{ungate|gate} to mmc_host_clk_{hold|release} · 08c14071
      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
      
      (This is CC'd to stable@ because the next two patches, which fix
      observable races, depend on it.)
      Signed-off-by: NMika Westerberg <mika.westerberg@linux.intel.com>
      Reviewed-by: NLinus Walleij <linus.walleij@linaro.org>
      Cc: <stable@kernel.org>
      Signed-off-by: NChris Ball <cjb@laptop.org>
      08c14071