1. 19 1月, 2018 4 次提交
  2. 30 10月, 2017 1 次提交
  3. 30 8月, 2017 1 次提交
  4. 25 4月, 2017 1 次提交
  5. 13 2月, 2017 1 次提交
    • L
      mmc: core/mmci: restore pre/post_req behaviour · e13934bd
      Linus Walleij 提交于
      commit 64b12a68
      "mmc: core: fix prepared requests while doing bkops"
      is fixing a bug in the wrong way. A bug in the MMCI
      device driver is fixed by amending the MMC core.
      
      Thinking about it: what the pre- and post-callbacks
      are doing is to essentially map and unmap SG lists
      for DMA transfers. Why would we not be able to do that
      just because a BKOPS command is sent inbetween?
      Having to unprepare/prepare the next asynchronous
      request for DMA seems wrong.
      
      Looking the backtrace in that commit we can see what
      the real problem actually is:
      
      mmci_data_irq() is calling mmci_dma_unmap() twice
      which is goung to call arm_dma_unmap_sg() twice
      and v7_dma_inv_range() twice for the same sglist
      and that will crash.
      
      This happens because a request is prepared, then
      a BKOPS is sent. The IRQ completing the BKOPS command
      goes through mmci_data_irq() and thinks that a DMA
      operation has just been completed because
      dma_inprogress() reports true. It then proceeds to
      unmap the sglist.
      
      But that was wrong! dma_inprogress() should NOT be
      true because no DMA was actually in progress! We had
      just prepared the sglist, and the DMA channel
      dma_current has been configured, but NOT started!
      
      Because of this, the sglist is already unmapped when
      we get our actual data completion IRQ, and we are
      unmapping the sglist once more, and we get this crash.
      
      Therefore, we need to revert this solution pushing
      the problem to the core and causing problems, and
      instead augment the implementation such that
      dma_inprogress() only reports true if some DMA has
      actually been started.
      
      After this we can keep the request prepared during the
      BKOPS and we need not unprepare/reprepare it.
      
      Fixes: 64b12a68 ("mmc: core: fix prepared requests while doing bkops")
      Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Tested-by: NSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      e13934bd
  6. 08 2月, 2017 1 次提交
    • J
      mmc: mmci: avoid clearing ST Micro busy end interrupt mistakenly · 5cad24d8
      Jean-Nicolas Graux 提交于
      This fixes a race condition that may occur whenever ST micro busy end
      interrupt is raised just after being unmasked but before leaving mmci
      interrupt context.
      
      A dead-lock has been found if connecting mmci ST Micro variant whose amba
      id is 0x10480180 to some new eMMC that supports internal caches.  Whenever
      mmci driver enables cache control by programming eMMC's EXT_CSD register,
      block driver may request to flush the eMMC internal caches causing mmci
      driver to send a MMC_SWITCH command to the card with FLUSH_CACHE operation.
      And because busy end interrupt may be mistakenly cleared while not yet
      processed, this mmc request may never complete.  As a result, mmcqd task
      may be stuck forever.
      
      Here is an instance caught by lockup detector which shows that mmcqd task
      was hung while waiting for mmc_flush_cache command to complete:
      
      ..
      [  240.251595] INFO: task mmcqd/1:52 blocked for more than 120 seconds.
      [  240.257973]       Not tainted 4.1.13-00510-g9d91424 #2
      [  240.263109] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
      [  240.270955] mmcqd/1         D c047504c     0    52      2 0x00000000
      [  240.277359] [<c047504c>] (__schedule) from [<c04754a0>] (schedule+0x40/0x98)
      [  240.284418] [<c04754a0>] (schedule) from [<c0477d40>] (schedule_timeout+0x148/0x188)
      [  240.292191] [<c0477d40>] (schedule_timeout) from [<c0476040>] (wait_for_common+0xa4/0x170)
      [  240.300491] [<c0476040>] (wait_for_common) from [<c02efc1c>] (mmc_wait_for_req_done+0x4c/0x13c)
      [  240.309224] [<c02efc1c>] (mmc_wait_for_req_done) from [<c02efd90>] (mmc_wait_for_cmd+0x64/0x84)
      [  240.317953] [<c02efd90>] (mmc_wait_for_cmd) from [<c02f5b14>] (__mmc_switch+0xa4/0x2a8)
      [  240.325964] [<c02f5b14>] (__mmc_switch) from [<c02f5d40>] (mmc_switch+0x28/0x30)
      [  240.333389] [<c02f5d40>] (mmc_switch) from [<c02f0984>] (mmc_flush_cache+0x54/0x80)
      [  240.341073] [<c02f0984>] (mmc_flush_cache) from [<c02ff0c4>] (mmc_blk_issue_rq+0x114/0x4e8)
      [  240.349459] [<c02ff0c4>] (mmc_blk_issue_rq) from [<c03008d4>] (mmc_queue_thread+0xc0/0x180)
      [  240.357844] [<c03008d4>] (mmc_queue_thread) from [<c003cf90>] (kthread+0xdc/0xf4)
      [  240.365339] [<c003cf90>] (kthread) from [<c0010068>] (ret_from_fork+0x14/0x2c)
      ..
      ..
      [  240.664311] INFO: task partprobe:564 blocked for more than 120 seconds.
      [  240.670943]       Not tainted 4.1.13-00510-g9d91424 #2
      [  240.676078] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
      [  240.683922] partprobe       D c047504c     0   564    486 0x00000000
      [  240.690318] [<c047504c>] (__schedule) from [<c04754a0>] (schedule+0x40/0x98)
      [  240.697396] [<c04754a0>] (schedule) from [<c0477d40>] (schedule_timeout+0x148/0x188)
      [  240.705149] [<c0477d40>] (schedule_timeout) from [<c0476040>] (wait_for_common+0xa4/0x170)
      [  240.713446] [<c0476040>] (wait_for_common) from [<c01f3300>] (submit_bio_wait+0x58/0x64)
      [  240.721571] [<c01f3300>] (submit_bio_wait) from [<c01fbbd8>] (blkdev_issue_flush+0x60/0x88)
      [  240.729957] [<c01fbbd8>] (blkdev_issue_flush) from [<c010ff84>] (blkdev_fsync+0x34/0x44)
      [  240.738083] [<c010ff84>] (blkdev_fsync) from [<c0109594>] (do_fsync+0x3c/0x64)
      [  240.745319] [<c0109594>] (do_fsync) from [<c000ffc0>] (ret_fast_syscall+0x0/0x3c)
      ..
      
      Here is the detailed sequence showing when this issue may happen:
      
      1) At probe time, mmci device is initialized and card busy detection based
      on DAT[0] monitoring is enabled.
      
      2) Later during run time, since card reported to support internal caches, a
      MMCI_SWITCH command is sent to eMMC device with FLUSH_CACHE operation. On
      receiving this command, eMMC may enter busy state (for a relatively short
      time in the case of the dead-lock).
      
      3) Then mmci interrupt is raised and mmci_irq() is called:
      
      MMCISTATUS register is read and is equal to 0x01000440. So the following
      status bits are set:
      - MCI_CMDRESPEND (= 6)
      - MCI_DATABLOCKEND (= 10)
      - MCI_ST_CARDBUSY (= 24)
      
      Since MMCIMASK0 register is 0x3FF, status variable is set to 0x00000040 and
      BIT MCI_CMDRESPEND is cleared by writing MMCICLEAR register.
      
      Then mmci_cmd_irq() is called. Considering the following conditions:
      - host->busy_status is 0,
      - this is a "busy response",
      - reading again MMCISTATUS register gives 0x1000400,
      MMCIMASK0 is updated to unmask MCI_ST_BUSYEND bit.
      
      Thus, MMCIMASK0 is set to 0x010003FF and host->busy_status is set to wait
      for busy end completion.
      
      Back again in status loop of mmci_irq(), we quickly go through
      mmci_data_irq() as there are no data in that case.  And we finally go
      through following test at the end of while(status) loop:
      
      /*
       * Don't poll for busy completion in irq context.
       */
      if (host->variant->busy_detect && host->busy_status)
      	status &= ~host->variant->busy_detect_flag;
      
      Because status variable is not yet null (is equal to 0x40), we do not leave
      interrupt context yet but we loop again into while(status) loop. So we run
      across following steps:
      
      a) MMCISTATUS register is read again and this time is equal to 0x01000400.
      So that following bits are set:
      - MCI_DATABLOCKEND (= 10)
      - MCI_ST_CARDBUSY (= 24)
      
      Since MMCIMASK0 register is equal to 0x010003FF:
      
      b) status variable is set to 0x01000000.
      c) MCI_ST_CARDBUSY bit is cleared by writing MMCICLEAR register.
      
      Then, mmci_cmd_irq() is called one more time. Since host->busy_status is
      set and that MCI_ST_CARDBUSY is set in status variable, we just return from
      this function.
      
      Back again in mmci_irq(), status variable is set to 0 and we finally leave
      the while(status) loop. As a result we leave interrupt context, waiting for
      busy end interrupt event.
      
      Now, consider that busy end completion is raised IN BETWEEN steps 3.a) and
      3.c). In such a case, we may mistakenly clear busy end interrupt at step
      3.c) while it has not yet been processed. This will result in mmc command
      to wait forever for a busy end completion that will never happen.
      
      To fix the problem, this patch implements the following changes:
      
      Considering that the mmci seems to be triggering the IRQ on both edges
      while monitoring DAT0 for busy completion and that same status bit is used
      to monitor start and end of busy detection, special care must be taken to
      make sure that both start and end interrupts are always cleared one after
      the other.
      
      1) Clearing of card busy bit is moved in mmc_cmd_irq() function where
      unmasking of busy end bit is effectively handled.
      2) Just before unmasking busy end event, busy start event is cleared by
      writing card busy bit in MMCICLEAR register.
      3) Finally, once we are no more busy with a command, busy end event is
      cleared writing again card busy bit in MMCICLEAR register.
      
      This patch has been tested with the ST Accordo5 machine, not yet supported
      upstream but relies on the mmci driver.
      Signed-off-by: NSarang Mairal <sarang.mairal@garmin.com>
      Signed-off-by: NJean-Nicolas Graux <jean-nicolas.graux@st.com>
      Reviewed-by: NLinus Walleij <linus.walleij@linaro.org>
      Tested-by: NUlf Hansson <ulf.hansson@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      5cad24d8
  7. 29 11月, 2016 3 次提交
    • L
      mmc: delete is_first_req parameter from pre-request callback · d3c6aac3
      Linus Walleij 提交于
      The void (*pre_req) callback in the struct mmc_host_ops vtable
      is passing an argument "is_first_req" indicating whether this is
      the first request or not.
      
      None of the in-kernel users use this parameter: instead, since
      they all just do variants of dma_map* they use the DMA cookie
      to indicate whether a pre* callback has already been done for
      a request when they decide how to handle it.
      
      Delete the parameter from the callback and all users, as it is
      just pointless cruft.
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Acked-by: NJaehoon Chung <jh80.chung@samsung.com>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      d3c6aac3
    • L
      mmc: mmci: refactor ST Micro busy detection · 49adc0ca
      Linus Walleij 提交于
      The ST Micro-specific busy detection was made after the assumption
      that only this variant supports busy detection. So when doing busy
      detection, the host immediately tries to use some ST-specific
      register bits.
      
      Since the qualcomm variant also supports some busy detection
      schemes, encapsulate the variant flags better in the variant struct
      and prepare to add more variants by just providing some bitmasks
      to the logic.
      
      Put the entire busy detection logic within an if()-clause in the
      mmci_cmd_irq() function so the code is only executed when busy
      detection is enabled, and so that it is kept in (almost) one
      place, and add comments describing what is going on so the
      code can be understood.
      
      Tested on the Ux500 by introducing some prints in the busy
      detection path and noticing how the IRQ is enabled, used and
      disabled successfully.
      
      Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      49adc0ca
    • L
      mmc: mmci: clean up header defines · 5db3eee7
      Linus Walleij 提交于
      There was some confusion in the CPSM (Command Path State Machine)
      and DPSM (Data Path State Machine) regarding the naming of the
      registers, clarify the meaning of this acronym so the naming is
      understandable, and consistently use BIT() to define these fields.
      
      Consequently name the register bit defines MCI_[C|D]PSM_* and
      adjust the driver as well.
      
      Include new definitions for a few bits found in a patch from
      Srinivas Kandagatla.
      
      Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      5db3eee7
  8. 02 5月, 2016 1 次提交
  9. 17 3月, 2016 1 次提交
  10. 14 1月, 2016 2 次提交
  11. 25 3月, 2015 1 次提交
  12. 28 1月, 2015 1 次提交
  13. 19 1月, 2015 1 次提交
  14. 04 12月, 2014 1 次提交
  15. 10 11月, 2014 1 次提交
    • S
      mmc: mmci: fix mmci_post_request · b5c16a60
      Srinivas Kandagatla 提交于
      If the post request is cancelling the channel and descriptor and which are
      equal to host->dma_current and host->dma_desc_current respectively, then it
      makes sense to reset these pointers to NULL, so that the driver does not
      reference it.
      
      Also the host_cookie can be reset to 0 in cases of error, so that the
      core could reissue the same mmc_request.
      
      This patch was tested with 'mmc: core: fix prepared requests while doing
      bkops' to fix the below issue.
      
      mmci-pl18x 12400000.sdcc: error during DMA transfer!
      Unable to handle kernel paging request at virtual address 40000000
      pgd = c0204000
      [40000000] *pgd=00000000
      Internal error: Oops: 805 [#1] SMP ARM
      Modules linked in: ipv6 ath6kl_sdio ath6kl_core
      CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W      3.17.0-rc7-linaro-multi-v7 #1
      task: c0c9d7e0 ti: c0c92000 task.ti: c0c92000
      PC is at v7_dma_inv_range+0x34/0x4c
      LR is at __dma_page_dev_to_cpu+0x80/0x100
      pc : [<c021efc0>]    lr : [<c021af18>]    psr: 400f0193
      sp : c0c93e20  ip : c0c9a478  fp : c08ea538
      r10: c0c9f548  r9 : 00000002  r8 : e97d9000
      r7 : 00000200  r6 : c0c9d504  r5 : c0db0880  r4 : 00000000
      r3 : 0000003f  r2 : 00000040  r1 : 40000200  r0 : 40000000
      Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
      Control: 10c5787d  Table: a9ef406a  DAC: 00000015
      Process swapper/0 (pid: 0, stack limit = 0xc0c92250)
      Stack: (0xc0c93e20 to 0xc0c94000)
      3e20: c021f058 e9a17178 e9a171bc e99dfd6c 00000001 00000001 e995de10 00000002
      3e40: 00000000 c021b574 00000000 c04bc4a4 00000000 e9b49ac0 c0ce6e6c e99dfda4
      3e60: 00000088 e9810780 c0d8291c c072ea58 00000000 c072d3fc 00000000 c072f534
      3e80: 00000000 e9b49ac0 00000100 c0c9a444 00000088 c072f6b4 c072f5d4 e9d40080
      3ea0: e98107dc 00000000 00000000 c0280a60 00000000 7d55bf61 e9810780 e98107dc
      3ec0: 00000000 f0002000 c0d460e8 c0d460e8 c0c92000 c0280b60 e9810780 c0ce7190
      3ee0: 00000000 c028369c c02835f4 00000088 00000088 c0280278 c0c8ec70 c020f080
      3f00: f000200c c0c9a958 c0c93f28 c02088e4 c04bd630 c04bd5bc 200f0013 ffffffff
      3f20: c0c93f5c c0212800 00000001 a987c000 c0c93f3c c04bd574 00000000 0000015b
      3f40: ea7a0e40 00000000 c0d460e8 c0d460e8 c0c92000 c08ea538 29b12000 c0c93f70
      3f60: c04bd630 c04bd5bc 200f0013 ffffffff c04bd574 c071bd24 7d50c9b4 c0719a44
      3f80: 7d50c9b4 0000015b c0c9a498 c0c92028 c0c9a498 c0c9a4fc ea7a0e40 c0c8ee38
      3fa0: c0d460e8 c0276198 00000000 c0d8291a 00000000 c0c9a400 00000000 c0be0bc4
      3fc0: ffffffff ffffffff c0be05f8 00000000 00000000 c0c533d8 c0d82ed4 c0c9a47c
      3fe0: c0c533d4 c0c9e870 8020406a 511f06f0 00000000 80208074 00000000 00000000
      [<c021efc0>] (v7_dma_inv_range) from [<c021af18>] (__dma_page_dev_to_cpu+0x80/0x100)
      [<c021af18>] (__dma_page_dev_to_cpu) from [<c021b574>] (arm_dma_unmap_sg+0x5c/0x84)
      [<c021b574>] (arm_dma_unmap_sg) from [<c072ea58>] (mmci_dma_unmap.isra.16+0x60/0x74)
      [<c072ea58>] (mmci_dma_unmap.isra.16) from [<c072f534>] (mmci_data_irq+0x1fc/0x29c)
      [<c072f534>] (mmci_data_irq) from [<c072f6b4>] (mmci_irq+0xe0/0x114)
      [<c072f6b4>] (mmci_irq) from [<c0280a60>] (handle_irq_event_percpu+0x78/0x134)
      [<c0280a60>] (handle_irq_event_percpu) from [<c0280b60>] (handle_irq_event+0x44/0x64)
      [<c0280b60>] (handle_irq_event) from [<c028369c>] (handle_fasteoi_irq+0xa8/0x1a8)
      [<c028369c>] (handle_fasteoi_irq) from [<c0280278>] (generic_handle_irq+0x2c/0x3c)
      [<c0280278>] (generic_handle_irq) from [<c020f080>] (handle_IRQ+0x40/0x90)
      [<c020f080>] (handle_IRQ) from [<c02088e4>] (gic_handle_irq+0x38/0x68)
      [<c02088e4>] (gic_handle_irq) from [<c0212800>] (__irq_svc+0x40/0x54)
      Exception stack(0xc0c93f28 to 0xc0c93f70)
      3f20:                   00000001 a987c000 c0c93f3c c04bd574 00000000 0000015b
      3f40: ea7a0e40 00000000 c0d460e8 c0d460e8 c0c92000 c08ea538 29b12000 c0c93f70
      3f60: c04bd630 c04bd5bc 200f0013 ffffffff
      [<c0212800>] (__irq_svc) from [<c04bd5bc>] (msm_cpu_pm_enter_sleep+0x48/0x4c)
      [<c04bd5bc>] (msm_cpu_pm_enter_sleep) from [<c071bd24>] (qcom_lpm_enter_spc+0x20/0x2c)
      [<c071bd24>] (qcom_lpm_enter_spc) from [<c0719a44>] (cpuidle_enter_state+0x44/0xf0)
      [<c0719a44>] (cpuidle_enter_state) from [<c0276198>] (cpu_startup_entry+0x1f4/0x238)
      [<c0276198>] (cpu_startup_entry) from [<c0be0bc4>] (start_kernel+0x384/0x390)
      Code: 1e070f3e e1110003 e1c11003 1e071f3e (ee070f36)
      ---[ end trace cf6cb3f6432c9834 ]---
      Kernel panic - not syncing: Fatal exception in interrupt
      Signed-off-by: NSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      b5c16a60
  16. 02 10月, 2014 1 次提交
  17. 10 9月, 2014 2 次提交
  18. 09 9月, 2014 2 次提交
  19. 11 8月, 2014 3 次提交
  20. 09 7月, 2014 11 次提交