1. 08 May, 2012 1 commit
    • Janusz Krzysztofik's avatar
      mtd: ams-delta: fix request_mem_region() failure · b027274d
      Janusz Krzysztofik authored
      A call to request_mem_region() has been introduced in the omap-gpio
      driver recently (commit 96751fcb,
      "gpio/omap: Use devm_ API and add request_mem_region"). This change
      prevented the Amstrad Delta NAND driver, which was doing the same in
      order to take control over OMAP MPU I/O lines that the NAND device hangs
      off, from loading successfully.
      
      The I/O lines and corresponding registers used by the NAND driver are a
      subset of those used for the GPIO function. Then, to avoid run time
      collisions, all MPUIO GPIO lines should be marked as requested while
      initializing the NAND driver, and vice versa, a single MPUIO GPIO line
      already requested before the NAND driver initialization is attempted
      should prevent the NAND device from being started successfully.
      
      There is another driver, omap-keypad, which also manipulates MPUIO
      registers, but has never been calling request_mem_region() on startup,
      so it's not affected by the change in the gpio-omap and works correctly.
      It uses the depreciated omap_read/write functions for accessing MPUIO
      registers. Unlike the NAND driver, these I/O lines and registers are
      separate from those used by the GPIO driver. However, both register sets
      are non-contiguous and overlapping, so it would be impractical to
      request the two sets separately, one from the gpio-omap, the other form
      the omap-keypad driver.
      
      In order to solve all these issues correctly, a solution first suggested
      by Artem Bityutskiy, then closer specified by Tony Lindgren while they
      commented the initial version of this fix, should be implemented. The
      gpio-omap driver should export a few functions which would allow the
      other two drivers to access MPUIO registers in a safe manner instead of
      trying to manage them in parallel to the GPIO driver.  However, such a
      big change, affecting 3 drivers all together, is not suitable for the rc
      cycle, and should be prepared for the merge window.  Then, an
      alternative solution is proposed as a regression fix.
      
      For the ams-delta NAND driver to initialize correctly in coexistence
      with the changed GPIO driver, drop the request_mem_region() call from
      the former, especially as this call is going to be removed while the
      long-term solution is implemented.
      
      Tested on Amstrad Delta.
      Signed-off-by: default avatarJanusz Krzysztofik <jkrzyszt@tis.icnet.pl>
      Acked-by: default avatarTony Lindgren <tony@atomide.com>
      Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
      Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
      b027274d
  2. 07 May, 2012 2 commits
    • Josh Cartwright's avatar
      jffs2: Fix lock acquisition order bug in gc path · 226bb7df
      Josh Cartwright authored
      The locking policy is such that the erase_complete_block spinlock is
      nested within the alloc_sem mutex.  This fixes a case in which the
      acquisition order was erroneously reversed.  This issue was caught by
      the following lockdep splat:
      
         =======================================================
         [ INFO: possible circular locking dependency detected ]
         3.0.5 #1
         -------------------------------------------------------
         jffs2_gcd_mtd6/299 is trying to acquire lock:
          (&c->alloc_sem){+.+.+.}, at: [<c01f7714>] jffs2_garbage_collect_pass+0x314/0x890
      
         but task is already holding lock:
          (&(&c->erase_completion_lock)->rlock){+.+...}, at: [<c01f7708>] jffs2_garbage_collect_pass+0x308/0x890
      
         which lock already depends on the new lock.
      
         the existing dependency chain (in reverse order) is:
      
         -> #1 (&(&c->erase_completion_lock)->rlock){+.+...}:
                [<c008bec4>] validate_chain+0xe6c/0x10bc
                [<c008c660>] __lock_acquire+0x54c/0xba4
                [<c008d240>] lock_acquire+0xa4/0x114
                [<c046780c>] _raw_spin_lock+0x3c/0x4c
                [<c01f744c>] jffs2_garbage_collect_pass+0x4c/0x890
                [<c01f937c>] jffs2_garbage_collect_thread+0x1b4/0x1cc
                [<c0071a68>] kthread+0x98/0xa0
                [<c000f264>] kernel_thread_exit+0x0/0x8
      
         -> #0 (&c->alloc_sem){+.+.+.}:
                [<c008ad2c>] print_circular_bug+0x70/0x2c4
                [<c008c08c>] validate_chain+0x1034/0x10bc
                [<c008c660>] __lock_acquire+0x54c/0xba4
                [<c008d240>] lock_acquire+0xa4/0x114
                [<c0466628>] mutex_lock_nested+0x74/0x33c
                [<c01f7714>] jffs2_garbage_collect_pass+0x314/0x890
                [<c01f937c>] jffs2_garbage_collect_thread+0x1b4/0x1cc
                [<c0071a68>] kthread+0x98/0xa0
                [<c000f264>] kernel_thread_exit+0x0/0x8
      
         other info that might help us debug this:
      
          Possible unsafe locking scenario:
      
                CPU0                    CPU1
                ----                    ----
           lock(&(&c->erase_completion_lock)->rlock);
                                        lock(&c->alloc_sem);
                                        lock(&(&c->erase_completion_lock)->rlock);
           lock(&c->alloc_sem);
      
          *** DEADLOCK ***
      
         1 lock held by jffs2_gcd_mtd6/299:
          #0:  (&(&c->erase_completion_lock)->rlock){+.+...}, at: [<c01f7708>] jffs2_garbage_collect_pass+0x308/0x890
      
         stack backtrace:
         [<c00155dc>] (unwind_backtrace+0x0/0x100) from [<c0463dc0>] (dump_stack+0x20/0x24)
         [<c0463dc0>] (dump_stack+0x20/0x24) from [<c008ae84>] (print_circular_bug+0x1c8/0x2c4)
         [<c008ae84>] (print_circular_bug+0x1c8/0x2c4) from [<c008c08c>] (validate_chain+0x1034/0x10bc)
         [<c008c08c>] (validate_chain+0x1034/0x10bc) from [<c008c660>] (__lock_acquire+0x54c/0xba4)
         [<c008c660>] (__lock_acquire+0x54c/0xba4) from [<c008d240>] (lock_acquire+0xa4/0x114)
         [<c008d240>] (lock_acquire+0xa4/0x114) from [<c0466628>] (mutex_lock_nested+0x74/0x33c)
         [<c0466628>] (mutex_lock_nested+0x74/0x33c) from [<c01f7714>] (jffs2_garbage_collect_pass+0x314/0x890)
         [<c01f7714>] (jffs2_garbage_collect_pass+0x314/0x890) from [<c01f937c>] (jffs2_garbage_collect_thread+0x1b4/0x1cc)
         [<c01f937c>] (jffs2_garbage_collect_thread+0x1b4/0x1cc) from [<c0071a68>] (kthread+0x98/0xa0)
         [<c0071a68>] (kthread+0x98/0xa0) from [<c000f264>] (kernel_thread_exit+0x0/0x8)
      
      This was introduce in '81cfc9f1 jffs2: Fix serious write stall due to erase'.
      
      Cc: stable@kernel.org [2.6.37+]
      Signed-off-by: default avatarJosh Cartwright <joshc@linux.com>
      Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
      Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
      226bb7df
    • Will Newton's avatar
      mtd: fix oops in dataflash driver · 7a84477c
      Will Newton authored
      I'm seeing an oops in mtd_dataflash.c with Linux 3.3. What appears to
      be happening is that otp_select_filemode calls mtd_read_fact_prot_reg
      with -1 for offset and length and a NULL buffer to test if OTP
      operations are supported. This finds its way down to otp_read in
      mtd_dataflash.c and causes an oops when memcpying the returned data
      into the NULL buf.
      
      None of the checks in otp_read catches the negative length and offset.
      Changing the length of the dummy read to 0 prevents the oops.
      
      Cc: stable@kernel.org [3.3+]
      Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
      Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
      7a84477c
  3. 21 Apr, 2012 23 commits
  4. 20 Apr, 2012 14 commits