1. 25 4月, 2020 2 次提交
    • R
      PM: sleep: core: Rework the power.may_skip_resume handling · 0fe8a1be
      Rafael J. Wysocki 提交于
      Because the power.may_skip_resume device status bit is taken
      into account in combination with the DPM_FLAG_LEAVE_SUSPENDED
      driver flag, it can be set to 'true' for all devices in the
      "suspend" phase of a suspend-resume cycle, so do that.
      
      Then, neither the PM core nor the middle-layer (sybsystem) code
      handling it needs to set it to 'true' any more and it just has
      to be cleared if there is a reason to avoid skipping the "noirq"
      and "early" resume callbacks provided by the driver, so update
      the code in question accordingly.
      Suggested-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      0fe8a1be
    • R
      PM: sleep: core: Do not skip callbacks in the resume phase · 6e176bf8
      Rafael J. Wysocki 提交于
      The current code in device_resume_noirq() causes the entire early
      resume and resume phases of device suspend to be skipped for
      devices for which the noirq resume phase have been skipped (due
      to the LEAVE_SUSPENDED flag being set) on the premise that those
      devices should stay in runtime-suspend after system-wide resume.
      
      However, that may not be correct in two situations.  First, the
      middle layer (subsystem) noirq resume callback may be missing for
      a given device, but its early resume callback may be present and it
      may need to do something even if it decides to skip the driver
      callback.  Second, if the device's wakeup settings were adjusted
      in the suspend phase without resuming the device (that was in
      runtime suspend at that time), they most likely need to be
      adjusted again in the resume phase and so the driver callback
      in that phase needs to be run.
      
      For the above reason, modify the core to allow the middle layer
      ->resume_late callback to run even if its ->resume_noirq callback
      is missing (and the core has skipped the driver-level callback
      in that phase) and to allow all device callbacks to run in the
      resume phase.  Also make the core set the PM-runtime status of
      devices with SMART_SUSPEND set whose resume callbacks are not
      skipped to "active" in the "noirq" resume phase and update the
      affected subsystems (PCI and ACPI) accordingly.
      
      After this change, middle-layer (subsystem) callbacks will always
      be invoked in all phases of system suspend and resume and driver
      callbacks will always run in the prepare, suspend, resume, and
      complete phases for all devices.
      
      For devices with SMART_SUSPEND set, driver callbacks will be
      skipped in the late and noirq phases of system suspend if those
      devices remain in runtime suspend in __device_suspend_late().
      Driver callbacks will also be skipped for them during the
      noirq and early phases of the "thaw" transition related to
      hibernation in that case.
      
      Setting LEAVE_SUSPENDED means that the driver allows its callbacks
      to be skipped in the noirq and early phases of system resume, but
      some additional conditions need to be met for that to happen (among
      other things, the power.may_skip_resume flag needs to be set for the
      device during system suspend for the driver callbacks to be skipped
      during the subsequent resume transition).
      
      For all devices with SMART_SUSPEND set whose driver callbacks are
      invoked during system resume, the PM-runtime status will be set to
      "active" (by the core).
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Acked-by: NBjorn Helgaas <bhelgaas@google.com>
      6e176bf8
  2. 03 4月, 2020 6 次提交
  3. 31 3月, 2020 4 次提交
    • S
      PCI: pciehp: Fix MSI interrupt race · 8edf5332
      Stuart Hayes 提交于
      Without this commit, a PCIe hotplug port can stop generating interrupts on
      hotplug events, so device adds and removals will not be seen:
      
      The pciehp interrupt handler pciehp_isr() reads the Slot Status register
      and then writes back to it to clear the bits that caused the interrupt.  If
      a different interrupt event bit gets set between the read and the write,
      pciehp_isr() returns without having cleared all of the interrupt event
      bits.  If this happens when the MSI isn't masked (which by default it isn't
      in handle_edge_irq(), and which it will never be when MSI per-vector
      masking is not supported), we won't get any more hotplug interrupts from
      that device.
      
      That is expected behavior, according to the PCIe Base Spec r5.0, section
      6.7.3.4, "Software Notification of Hot-Plug Events".
      
      Because the Presence Detect Changed and Data Link Layer State Changed event
      bits can both get set at nearly the same time when a device is added or
      removed, this is more likely to happen than it might seem.  The issue was
      found (and can be reproduced rather easily) by connecting and disconnecting
      an NVMe storage device on at least one system model where the NVMe devices
      were being connected to an AMD PCIe port (PCI device 0x1022/0x1483).
      
      Fix the issue by modifying pciehp_isr() to loop back and re-read the Slot
      Status register immediately after writing to it, until it sees that all of
      the event status bits have been cleared.
      
      [lukas: drop loop count limitation, write "events" instead of "status",
      don't loop back in INTx and poll modes, tweak code comment & commit msg]
      Link: https://lore.kernel.org/r/78b4ced5072bfe6e369d20e8b47c279b8c7af12e.1582121613.git.lukas@wunner.deTested-by: NStuart Hayes <stuart.w.hayes@gmail.com>
      Signed-off-by: NStuart Hayes <stuart.w.hayes@gmail.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NJoerg Roedel <jroedel@suse.de>
      8edf5332
    • L
      PCI: pciehp: Fix indefinite wait on sysfs requests · 3e487d2e
      Lukas Wunner 提交于
      David Hoyer reports that powering pciehp slots up or down via sysfs may
      hang:  The call to wait_event() in pciehp_sysfs_enable_slot() and
      _disable_slot() does not return because ctrl->ist_running remains true.
      
      This flag, which was introduced by commit 157c1062 ("PCI: pciehp: Avoid
      returning prematurely from sysfs requests"), signifies that the IRQ thread
      pciehp_ist() is running.  It is set to true at the top of pciehp_ist() and
      reset to false at the end.  However there are two additional return
      statements in pciehp_ist() before which the commit neglected to reset the
      flag to false and wake up waiters for the flag.
      
      That omission opens up the following race when powering up the slot:
      
      * pciehp_ist() runs because a PCI_EXP_SLTSTA_PDC event was requested
        by pciehp_sysfs_enable_slot()
      
      * pciehp_ist() turns on slot power via the following call stack:
        pciehp_handle_presence_or_link_change() -> pciehp_enable_slot() ->
        __pciehp_enable_slot() -> board_added() -> pciehp_power_on_slot()
      
      * after slot power is turned on, the link comes up, resulting in a
        PCI_EXP_SLTSTA_DLLSC event
      
      * the IRQ handler pciehp_isr() stores the event in ctrl->pending_events
        and returns IRQ_WAKE_THREAD
      
      * the IRQ thread is already woken (it's bringing up the slot), but the
        genirq code remembers to re-run the IRQ thread after it has finished
        (such that it can deal with the new event) by setting IRQTF_RUNTHREAD
        via __handle_irq_event_percpu() -> __irq_wake_thread()
      
      * the IRQ thread removes PCI_EXP_SLTSTA_DLLSC from ctrl->pending_events
        via board_added() -> pciehp_check_link_status() in order to deal with
        presence and link flaps per commit 6c35a1ac ("PCI: pciehp:
        Tolerate initially unstable link")
      
      * after pciehp_ist() has successfully brought up the slot, it resets
        ctrl->ist_running to false and wakes up the sysfs requester
      
      * the genirq code re-runs pciehp_ist(), which sets ctrl->ist_running
        to true but then returns with IRQ_NONE because ctrl->pending_events
        is empty
      
      * pciehp_sysfs_enable_slot() is finally woken but notices that
        ctrl->ist_running is true, hence continues waiting
      
      The only way to get the hung task going again is to trigger a hotplug
      event which brings down the slot, e.g. by yanking out the card.
      
      The same race exists when powering down the slot because remove_board()
      likewise clears link or presence changes in ctrl->pending_events per commit
      3943af9d ("PCI: pciehp: Ignore Link State Changes after powering off a
      slot") and thereby may cause a re-run of pciehp_ist() which returns with
      IRQ_NONE without resetting ctrl->ist_running to false.
      
      Fix by adding a goto label before the teardown steps at the end of
      pciehp_ist() and jumping to that label from the two return statements which
      currently neglect to reset the ctrl->ist_running flag.
      
      Fixes: 157c1062 ("PCI: pciehp: Avoid returning prematurely from sysfs requests")
      Link: https://lore.kernel.org/r/cca1effa488065cb055120aa01b65719094bdcb5.1584530321.git.lukas@wunner.deReported-by: NDavid Hoyer <David.Hoyer@netapp.com>
      Signed-off-by: NLukas Wunner <lukas@wunner.de>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NKeith Busch <kbusch@kernel.org>
      Cc: stable@vger.kernel.org	# v4.19+
      3e487d2e
    • K
      PCI: endpoint: Fix clearing start entry in configfs · f58d5f53
      Kunihiko Hayashi 提交于
      After an endpoint is started through configfs, if 0 is written to the
      configfs entry 'start', the controller stops but the epc_group->start
      value remains 1.
      
      A subsequent unlinking of the function from the controller would trigger
      a spurious WARN_ON_ONCE() in pci_epc_epf_unlink() despite right
      behavior.
      
      Fix it by setting epc_group->start = 0 when a controller is stopped
      using configfs.
      
      Fixes: d7467991 ("PCI: endpoint: Introduce configfs entry for configuring EP functions")
      Signed-off-by: NKunihiko Hayashi <hayashi.kunihiko@socionext.com>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Acked-by: NKishon Vijay Abraham I <kishon@ti.com>
      Cc: Kishon Vijay Abraham I <kishon@ti.com>
      f58d5f53
    • V
      PCI: tegra: Add support for PCIe endpoint mode in Tegra194 · c57247f9
      Vidya Sagar 提交于
      Add support for the endpoint mode of Synopsys DesignWare core based
      dual mode PCIe controllers present in Tegra194 SoC.
      Signed-off-by: NVidya Sagar <vidyas@nvidia.com>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Acked-by: NThierry Reding <treding@nvidia.com>
      c57247f9
  4. 30 3月, 2020 3 次提交
    • K
      PCI: sysfs: Revert "rescan" file renames · bd641fd8
      Kelsey Skunberg 提交于
      We changed these sysfs filenames:
      
        .../pci_bus/<domain:bus>/rescan  ->  .../pci_bus/<domain:bus>/bus_rescan
        .../<domain:bus:dev.fn>/rescan   ->  .../<domain:bus:dev.fn>/dev_rescan
      
      and Ruslan reported [1] that this broke a userspace application.
      
      Revert these name changes so both files are named "rescan" again.
      
      Note that we have to use __ATTR() to assign custom C symbols, i.e.,
      "struct device_attribute <symbol>".
      
      [1] https://lore.kernel.org/r/CAB=otbSYozS-ZfxB0nCiNnxcbqxwrHOSYxJJtDKa63KzXbXgpw@mail.gmail.com
      
      [bhelgaas: commit log, use __ATTR() both places so we don't have to rename
      the attributes]
      Fixes: 8bdfa145 ("PCI: sysfs: Define device attributes with DEVICE_ATTR*()")
      Fixes: 4e2b7943 ("PCI: sysfs: Change DEVICE_ATTR() to DEVICE_ATTR_WO()")
      Link: https://lore.kernel.org/r/20200325151708.32612-1-skunberg.kelsey@gmail.comSigned-off-by: NKelsey Skunberg <kelsey.skunberg@gmail.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: stable@vger.kernel.org	# v5.4+
      bd641fd8
    • I
      PCI: Add support for root bus sizing · 2c8d5a2d
      Ivan Kokshaysky 提交于
      In certain cases we should be able to enumerate IO and MEM ranges of all
      PCI devices installed in the system, and then set respective host bridge
      apertures basing on calculated size and alignment.  Particularly when
      firmware is broken and fails to assign bridge windows properly, like on
      Alpha UP1500 platform.
      
      Actually, almost everything is already in place, and required changes are
      minimal:
      
      - add "size_windows" flag to struct pci_host_bridge: when set, it
        instructs __pci_bus_size_bridges() to continue with the root bus;
      - in the __pci_bus_size_bridges() path: add checks for bus->self,
        as it can legitimately be null for the root bus.
      
      Link: https://lore.kernel.org/r/20200314194355.GA12510@mail.rc.ruTested-by: NMatt Turner <mattst88@gmail.com>
      Signed-off-by: NIvan Kokshaysky <ink@jurassic.park.msu.ru>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      2c8d5a2d
    • M
      PCI: Use ioremap(), not phys_to_virt() for platform ROM · 72e0ef0e
      Mikel Rychliski 提交于
      On some EFI systems, the video BIOS is provided by the EFI firmware.  The
      boot stub code stores the physical address of the ROM image in pdev->rom.
      Currently we attempt to access this pointer using phys_to_virt(), which
      doesn't work with CONFIG_HIGHMEM.
      
      On these systems, attempting to load the radeon module on a x86_32 kernel
      can result in the following:
      
        BUG: unable to handle page fault for address: 3e8ed03c
        #PF: supervisor read access in kernel mode
        #PF: error_code(0x0000) - not-present page
        *pde = 00000000
        Oops: 0000 [#1] PREEMPT SMP
        CPU: 0 PID: 317 Comm: systemd-udevd Not tainted 5.6.0-rc3-next-20200228 #2
        Hardware name: Apple Computer, Inc. MacPro1,1/Mac-F4208DC8, BIOS     MP11.88Z.005C.B08.0707021221 07/02/07
        EIP: radeon_get_bios+0x5ed/0xe50 [radeon]
        Code: 00 00 84 c0 0f 85 12 fd ff ff c7 87 64 01 00 00 00 00 00 00 8b 47 08 8b 55 b0 e8 1e 83 e1 d6 85 c0 74 1a 8b 55 c0 85 d2 74 13 <80> 38 55 75 0e 80 78 01 aa 0f 84 a4 03 00 00 8d 74 26 00 68 dc 06
        EAX: 3e8ed03c EBX: 00000000 ECX: 3e8ed03c EDX: 00010000
        ESI: 00040000 EDI: eec04000 EBP: eef3fc60 ESP: eef3fbe0
        DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010206
        CR0: 80050033 CR2: 3e8ed03c CR3: 2ec77000 CR4: 000006d0
        Call Trace:
         r520_init+0x26/0x240 [radeon]
         radeon_device_init+0x533/0xa50 [radeon]
         radeon_driver_load_kms+0x80/0x220 [radeon]
         drm_dev_register+0xa7/0x180 [drm]
         radeon_pci_probe+0x10f/0x1a0 [radeon]
         pci_device_probe+0xd4/0x140
      
      Fix the issue by updating all drivers which can access a platform provided
      ROM. Instead of calling the helper function pci_platform_rom() which uses
      phys_to_virt(), call ioremap() directly on the pdev->rom.
      
      radeon_read_platform_bios() previously directly accessed an __iomem
      pointer. Avoid this by calling memcpy_fromio() instead of kmemdup().
      
      pci_platform_rom() now has no remaining callers, so remove it.
      
      Link: https://lore.kernel.org/r/20200319021623.5426-1-mikel@mikelr.comSigned-off-by: NMikel Rychliski <mikel@mikelr.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NAlex Deucher <alexander.deucher@amd.com>
      72e0ef0e
  5. 29 3月, 2020 13 次提交
  6. 27 3月, 2020 1 次提交
    • V
      PCI: dwc: pci-dra7xx: Fix MSI IRQ handling · 9a5595ab
      Vignesh Raghavendra 提交于
      Due to an issue with PCIe wrapper logic built for the DWC PCIe IP on
      dra7xx, the driver needs to ensure that there are no pending MSI IRQ
      vector set (i.e PCIE_MSI_INTR0_STATUS reads 0 at least once) before
      exiting IRQ handler otherwise the dra7xx PCIe wrapper will not register
      new MSI IRQs even though PCIE_MSI_INTR0_STATUS reports IRQs are pending.
      
      Therefore it's no longer possible to use default IRQ handler provided by
      DWC library.
      
      Add an irqchip implementation inside pci-dra7xx.c and install new MSI
      IRQ handler to handle the above errata.
      
      This fixes a bug, where PCIe wifi cards with 4 DMA queues like Intel
      8260 used to throw following error and stall during ping/iperf3 tests.
      
      [   97.776310] iwlwifi 0000:01:00.0: Queue 9 stuck for 2500 ms.
      Tested-by: NKishon Vijay Abraham I <kishon@ti.com>
      Signed-off-by: NVignesh Raghavendra <vigneshr@ti.com>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Acked-by: NKishon Vijay Abraham I <kishon@ti.com>
      9a5595ab
  7. 25 3月, 2020 4 次提交
  8. 21 3月, 2020 2 次提交
  9. 20 3月, 2020 1 次提交
  10. 19 3月, 2020 3 次提交
  11. 18 3月, 2020 1 次提交