1. 27 May, 2020 8 commits
    • H. Nikolaus Schaller's avatar
      w1: omap-hdq: fix interrupt handling which did show spurious timeouts · 13db4c40
      H. Nikolaus Schaller authored
      Since
      
      commit 27d13da8 ("w1: omap-hdq: Simplify driver with PM runtime autosuspend")
      
      was applied,
      
      I did see timeouts and wrong values when reading a bq27000 connected
      to hdq of the omap3. This occurred mainly after boot but remained and
      only sometimes settled down after several reads.
      
      root@letux:~# time cat /sys/class/power_supply/bq27000-battery/uevent
      POWER_SUPPLY_NAME=bq27000-battery
      POWER_SUPPLY_STATUS=Discharging
      POWER_SUPPLY_PRESENT=1
      POWER_SUPPLY_VOLTAGE_NOW=0
      POWER_SUPPLY_CURRENT_NOW=0
      POWER_SUPPLY_CAPACITY=0
      POWER_SUPPLY_CAPACITY_LEVEL=Normal
      POWER_SUPPLY_TEMP=-2731
      POWER_SUPPLY_TIME_TO_EMPTY_NOW=0
      POWER_SUPPLY_TIME_TO_EMPTY_AVG=0
      POWER_SUPPLY_TIME_TO_FULL_NOW=0
      POWER_SUPPLY_TECHNOLOGY=Li-ion
      POWER_SUPPLY_CHARGE_FULL=0
      POWER_SUPPLY_CHARGE_NOW=0
      POWER_SUPPLY_CHARGE_FULL_DESIGN=0
      POWER_SUPPLY_CYCLE_COUNT=0
      POWER_SUPPLY_ENERGY_NOW=0
      POWER_SUPPLY_POWER_AVG=0
      POWER_SUPPLY_HEALTH=Good
      POWER_SUPPLY_MANUFACTURER=Texas Instruments
      
      real    0m15.761s
      user    0m0.001s
      sys     0m0.025s
      root@letux:~#
      
      Sometimes the effect did disappear after accessing
      the device multiple times, speed went up and results
      became correct.
      
      All this indicates that some interrupts from the hdq
      controller are lost by the driver.
      
      Enabling debugging revealed that there were spurious tx
      and rx timeouts, i.e. the driver does not always recognise
      interrupts. The main problem is that rx and tx interrupts
      share a single variable which was sometimes reset to
      0 wiping out other interrupts. And it was overwritten
      by a second interrupt, independent of whether the
      previous interrupt was already processed or not.
      
      This patch improves interrupt handling to avoid such
      races and loss of interrupt flags.
      
      The ideas are:
      * only the hdq_isr() sets bits in hdq_status
      * it does not reset any bits
      * it does wake_up() if any interrupt is pending
      * bits are only reset by the read/write/break functions
        if they were waited for
      * this makes sure that no interrupts can be lost
      * rx/tx/timeout bits are completely decoupled from each
        other (and not reset all after waiting for any of them)
      * which bits to reset is now specified by a new parameter
        to hdq_reset_irqstatus()
      * hdq_reset_irqstatus() also returns the state before
        resetting so that we can encapsulate the spinlock
      * this should now handle the case that the write and read
        are both already finished quickly before the hdq_write_byte()
        ends.
      * Or that two interrupts occur in succession before
        they are processed by the driver.
        Old code may have reset all status bits making the next
        hdq_read_byte() timeout.
      * the spinlock now always protects changing of bits in function
        hdq_reset_irqstatus() which could become a read-write-modify
        problem if the interrupt handler tries to read-modify-write
        exactly at the same moment
      * we add mutex protection also for hdq_write_byte() just to
        be safe to not to disturb a hdq_read_byte() triggered by
        some other thread/process.
      
      This patch was tested on a GTA04 and results in no
      boot problems any more. And first read after boot is now ok:
      
      root@letux:~# time cat /sys/class/power_supply/bq27000-battery/uevent
      POWER_SUPPLY_NAME=bq27000-battery
      POWER_SUPPLY_STATUS=Discharging
      POWER_SUPPLY_PRESENT=1
      POWER_SUPPLY_VOLTAGE_NOW=3970000
      POWER_SUPPLY_CURRENT_NOW=354144
      POWER_SUPPLY_CAPACITY=82
      POWER_SUPPLY_CAPACITY_LEVEL=Normal
      POWER_SUPPLY_TEMP=266
      POWER_SUPPLY_TIME_TO_EMPTY_NOW=7680
      POWER_SUPPLY_TIME_TO_EMPTY_AVG=7380
      POWER_SUPPLY_TECHNOLOGY=Li-ion
      POWER_SUPPLY_CHARGE_FULL=934856
      POWER_SUPPLY_CHARGE_NOW=763976
      POWER_SUPPLY_CHARGE_FULL_DESIGN=1233792
      POWER_SUPPLY_CYCLE_COUNT=82
      POWER_SUPPLY_ENERGY_NOW=2852840
      POWER_SUPPLY_POWER_AVG=1392840
      POWER_SUPPLY_HEALTH=Good
      POWER_SUPPLY_MANUFACTURER=Texas Instruments
      
      real    0m0.233s
      user    0m0.000s
      sys     0m0.025s
      root@letux:~#
      
      It was also tested with dev_dbg enabled and more
      printk that all activities behave correctly, especially
      hdq_write_byte(), hdq_read_byte(), omap_hdq_break().
      
      Not tested is omap_w1_triplet().
      
      Fixes: 27d13da8 ("w1: omap-hdq: Simplify driver with PM runtime autosuspend")
      Cc: stable@vger.kernel.org # v5.6+
      Signed-off-by: default avatarH. Nikolaus Schaller <hns@goldelico.com>
      Link: https://lore.kernel.org/r/68fc8623ae741878beef049273696d2377526165.1590255176.git.hns@goldelico.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      13db4c40
    • H. Nikolaus Schaller's avatar
      w1: omap-hdq: fix return value to be -1 if there is a timeout · 2d410063
      H. Nikolaus Schaller authored
      omap_w1_read_byte() should return -1 (or 0xff) in case of
      error (e.g. missing battery).
      
      The code accidentially overwrites the variable ret and not val,
      which is returned. So it will return the initial value 0 instead
      of -1.
      
      Fixes: 27d13da8 ("w1: omap-hdq: Simplify driver with PM runtime autosuspend")
      Cc: stable@vger.kernel.org # v5.6+
      Acked-by: default avatarTony Lindgren <tony@atomide.com>
      Signed-off-by: default avatarH. Nikolaus Schaller <hns@goldelico.com>
      Link: https://lore.kernel.org/r/b2c2192b461fbb9b8e9bea4ad514a49557a7210b.1590255176.git.hns@goldelico.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2d410063
    • H. Nikolaus Schaller's avatar
      w1: omap-hdq: cleanup to add missing newline for some dev_dbg · 5e02f3b3
      H. Nikolaus Schaller authored
      Otherwise it will corrupt the console log during debugging.
      
      Fixes: 7b5362a6 ("w1: omap_hdq: Fix some error/debug handling.")
      Cc: stable@vger.kernel.org
      Acked-by: default avatarTony Lindgren <tony@atomide.com>
      Signed-off-by: default avatarH. Nikolaus Schaller <hns@goldelico.com>
      Link: https://lore.kernel.org/r/cd0d55749a091214106575f6e1d363c6db56622f.1590255176.git.hns@goldelico.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      5e02f3b3
    • Dan Williams's avatar
      /dev/mem: Revoke mappings when a driver claims the region · 3234ac66
      Dan Williams authored
      Close the hole of holding a mapping over kernel driver takeover event of
      a given address range.
      
      Commit 90a545e9 ("restrict /dev/mem to idle io memory ranges")
      introduced CONFIG_IO_STRICT_DEVMEM with the goal of protecting the
      kernel against scenarios where a /dev/mem user tramples memory that a
      kernel driver owns. However, this protection only prevents *new* read(),
      write() and mmap() requests. Established mappings prior to the driver
      calling request_mem_region() are left alone.
      
      Especially with persistent memory, and the core kernel metadata that is
      stored there, there are plentiful scenarios for a /dev/mem user to
      violate the expectations of the driver and cause amplified damage.
      
      Teach request_mem_region() to find and shoot down active /dev/mem
      mappings that it believes it has successfully claimed for the exclusive
      use of the driver. Effectively a driver call to request_mem_region()
      becomes a hole-punch on the /dev/mem device.
      
      The typical usage of unmap_mapping_range() is part of
      truncate_pagecache() to punch a hole in a file, but in this case the
      implementation is only doing the "first half" of a hole punch. Namely it
      is just evacuating current established mappings of the "hole", and it
      relies on the fact that /dev/mem establishes mappings in terms of
      absolute physical address offsets. Once existing mmap users are
      invalidated they can attempt to re-establish the mapping, or attempt to
      continue issuing read(2) / write(2) to the invalidated extent, but they
      will then be subject to the CONFIG_IO_STRICT_DEVMEM checking that can
      block those subsequent accesses.
      
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: Kees Cook <keescook@chromium.org>
      Cc: Matthew Wilcox <willy@infradead.org>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Fixes: 90a545e9 ("restrict /dev/mem to idle io memory ranges")
      Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/159009507306.847224.8502634072429766747.stgit@dwillia2-desk3.amr.corp.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3234ac66
    • John Hubbard's avatar
      misc: xilinx-sdfec: convert get_user_pages() --> pin_user_pages() · 03358b0f
      John Hubbard authored
      This code was using get_user_pages*(), in approximately a "Case 1"
      scenario (Direct IO), using the categorization from [1]. That means
      that it's time to convert the get_user_pages*() + put_page() calls to
      pin_user_pages*() + unpin_user_pages() calls.
      
      There is some helpful background in [2]: basically, this is a small
      part of fixing a long-standing disconnect between pinning pages, and
      file systems' use of those pages.
      
      [1] Documentation/core-api/pin_user_pages.rst
      
      [2] "Explicit pinning of user-space pages":
          https://lwn.net/Articles/807108/
      
      Cc: Derek Kiernan <derek.kiernan@xilinx.com>
      Cc: Dragan Cvetic <dragan.cvetic@xilinx.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Michal Simek <michal.simek@xilinx.com>
      Cc: linux-arm-kernel@lists.infradead.org
      Signed-off-by: default avatarJohn Hubbard <jhubbard@nvidia.com>
      Link: https://lore.kernel.org/r/20200527012628.1100649-4-jhubbard@nvidia.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      03358b0f
    • John Hubbard's avatar
      misc: xilinx-sdfec: cleanup return value in xsdfec_table_write() · d25594d7
      John Hubbard authored
      Return 0 for success, rather than the value of an incrementing
      "reg" index. The reg value was never actually used, so this
      simplifies the caller slightly.
      
      Cc: Derek Kiernan <derek.kiernan@xilinx.com>
      Cc: Dragan Cvetic <dragan.cvetic@xilinx.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Michal Simek <michal.simek@xilinx.com>
      Cc: linux-arm-kernel@lists.infradead.org
      Signed-off-by: default avatarJohn Hubbard <jhubbard@nvidia.com>
      Link: https://lore.kernel.org/r/20200527012628.1100649-3-jhubbard@nvidia.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d25594d7
    • John Hubbard's avatar
      misc: xilinx-sdfec: improve get_user_pages_fast() error handling · 57343d51
      John Hubbard authored
      This fixes the case of get_user_pages_fast() returning a -errno.
      The result needs to be stored in a signed integer. And for safe
      signed/unsigned comparisons, it's best to keep everything signed.
      And get_user_pages_fast() also expects a signed value for number
      of pages to pin.
      
      Therefore, change most relevant variables, from u32 to int. Leave
      "n" unsigned, for convenience in checking for overflow. And provide
      a WARN_ON_ONCE() and early return, if overflow occurs.
      
      Also, as long as we're tidying up: rename the page array from page,
      to pages, in order to match the conventions used in most other call
      sites.
      
      Fixes: 20ec628e ("misc: xilinx_sdfec: Add ability to configure LDPC")
      Cc: Derek Kiernan <derek.kiernan@xilinx.com>
      Cc: Dragan Cvetic <dragan.cvetic@xilinx.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Michal Simek <michal.simek@xilinx.com>
      Cc: linux-arm-kernel@lists.infradead.org
      Signed-off-by: default avatarJohn Hubbard <jhubbard@nvidia.com>
      Link: https://lore.kernel.org/r/20200527012628.1100649-2-jhubbard@nvidia.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      57343d51
    • Srinivas Kandagatla's avatar
      nvmem: qfprom: remove incorrect write support · 8d9eb0d6
      Srinivas Kandagatla authored
      qfprom has different address spaces for read and write. Reads are
      always done from corrected address space, where as writes are done
      on raw address space.
      Writing to corrected address space is invalid and ignored, so it
      does not make sense to have this support in the driver which only
      supports corrected address space regions at the moment.
      
      Fixes: 4ab11996 ("nvmem: qfprom: Add Qualcomm QFPROM support.")
      Signed-off-by: default avatarSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
      Reviewed-by: default avatarDouglas Anderson <dianders@chromium.org>
      Cc: stable <stable@vger.kernel.org>
      Link: https://lore.kernel.org/r/20200522113341.7728-1-srinivas.kandagatla@linaro.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8d9eb0d6
  2. 25 May, 2020 7 commits
  3. 22 May, 2020 22 commits
  4. 21 May, 2020 2 commits
  5. 20 May, 2020 1 commit