History log of /linux-master/drivers/pci/pcie/pme.c
Revision Date Author Comments
# ec302b11 10-Oct-2023 Bjorn Helgaas <bhelgaas@google.com>

PCI/PME: Use FIELD_GET()

Use FIELD_GET() to remove dependences on the field position, i.e., the
shift value. No functional change intended.

Link: https://lore.kernel.org/r/20231010204436.1000644-8-helgaas@kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>


# aa66ea10 18-Nov-2021 Naveen Naidu <naveennaidu479@gmail.com>

PCI/PME: Use PCI_POSSIBLE_ERROR() to check config reads

When config pci_ops.read() can detect failed PCI transactions, the data
returned to the CPU is PCI_ERROR_RESPONSE (~0 or 0xffffffff).

Obviously a successful PCI config read may *also* return that data if a
config register happens to contain ~0, so it doesn't definitively indicate
an error unless we know the register cannot contain ~0.

Use PCI_POSSIBLE_ERROR() to check the response we get when we read data
from hardware. This unifies PCI error response checking and makes error
checks consistent and easier to find.

Compile tested only.

Link: https://lore.kernel.org/r/679ce049bccf10df3ca9ef4918ee2c3235afdaea.1637243717.git.naveennaidu479@gmail.com
Signed-off-by: Naveen Naidu <naveennaidu479@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 43395d9e 10-Mar-2021 Krzysztof Wilczyński <kw@linux.com>

PCI: Fix kernel-doc errors

Fix kernel-doc formatting errors, function names that don't match the doc,
and some missing parameter documentation. These are reported by:

make W=1 drivers/pci/

No functional change intended.

[bhelgaas: squashed into one patch since this only changes comments]
Link: https://lore.kernel.org/r/20210311001724.423356-1-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-2-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-3-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-4-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-5-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-6-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-7-kw@linux.com
Link: https://lore.kernel.org/r/20210311001724.423356-8-kw@linux.com
Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 9a2f604f 20-Nov-2020 Sean V Kelley <sean.v.kelley@intel.com>

PCI/PME: Add pcie_walk_rcec() to RCEC PME handling

Root Complex Event Collectors (RCEC) appear as peers of Root Ports and also
have the PME capability. As with AER, there is a need to be able to walk
the RCiEPs associated with their RCEC for purposes of acting upon them with
callbacks.

Add RCEC support through the use of pcie_walk_rcec() to the current PME
service driver and attach the PME service driver to the RCEC device.

Co-developed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Link: https://lore.kernel.org/r/20201121001036.8560-15-sean.v.kelley@intel.com
Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> # non-native/no RCEC
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Sean V Kelley <sean.v.kelley@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 5dda3ba6 16-May-2020 Jay Fang <f.fangjian@huawei.com>

PCI/PME: Fix kernel-doc of pcie_pme_resume() and pcie_pme_remove()

Fix kernel-doc of the "srv" parameter to pcie_pme_resume() and
pcie_pme_remove(). Building with W=1 produced these warnings:

drivers/pci/pcie/pme.c:414: warning: Function parameter or member 'srv' not described in 'pcie_pme_resume'
drivers/pci/pcie/pme.c:437: warning: Function parameter or member 'srv' not described in 'pcie_pme_remove'

Link: https://lore.kernel.org/r/1589612414-61682-1-git-send-email-f.fangjian@huawei.com
Signed-off-by: Jay Fang <f.fangjian@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 00ebf134 07-May-2019 Frederick Lawler <fred@fredlawl.com>

PCI/PME: Replace dev_printk(KERN_DEBUG) with dev_info()

Replace dev_printk(KERN_DEBUG) with dev_info() or dev_err() to be more
consistent with other logging.

These could be converted to dev_dbg(), but that depends on
CONFIG_DYNAMIC_DEBUG and DEBUG, and we want most of these messages to
*always* be in the dmesg log.

Also, use dev_fmt() to add the service name. Example output change:

- pcieport 0000:80:10.0: Signaling PME with IRQ ...
+ pcieport 0000:80:10.0: PME: Signaling with IRQ ...

Link: https://lore.kernel.org/lkml/20190509141456.223614-3-helgaas@kernel.org
Signed-off-by: Frederick Lawler <fred@fredlawl.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Keith Busch <keith.busch@intel.com>


# 7cf58b79 01-Mar-2019 Sven Van Asbroeck <thesven73@gmail.com>

PCI/PME: Fix possible use-after-free on remove

In remove(), ensure that the PME work cannot run after kfree() is called.
Otherwise, this could result in a use-after-free.

This issue was detected with the help of Coccinelle.

Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Sinan Kaya <okaya@kernel.org>
Cc: Frederick Lawler <fred@fredlawl.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 95c80bc6 28-Feb-2019 Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PCI/PME: Fix hotplug/sysfs remove deadlock in pcie_pme_remove()

Dongdong reported a deadlock triggered by a hotplug event during a sysfs
"remove" operation:

pciehp 0000:00:0c.0:pcie004: Slot(0-1): Link Up
# echo 1 > 0000:00:0c.0/remove

PME and hotplug share an MSI/MSI-X vector. The sysfs "remove" side is:

remove_store
pci_stop_and_remove_bus_device_locked
pci_lock_rescan_remove
pci_stop_and_remove_bus_device
...
pcie_pme_remove
pcie_pme_suspend
synchronize_irq # wait for hotplug IRQ handler
pci_unlock_rescan_remove

The hotplug side is:

pciehp_ist
pciehp_handle_presence_or_link_change
pciehp_configure_device
pci_lock_rescan_remove # wait for pci_unlock_rescan_remove()

INFO: task bash:10913 blocked for more than 120 seconds.

# ps -ax |grep D
PID TTY STAT TIME COMMAND
10913 ttyAMA0 Ds+ 0:00 -bash
14022 ? D 0:00 [irq/745-pciehp]

# cat /proc/14022/stack
__switch_to+0x94/0xd8
pci_lock_rescan_remove+0x20/0x28
pciehp_configure_device+0x30/0x140
pciehp_handle_presence_or_link_change+0x324/0x458
pciehp_ist+0x1dc/0x1e0

# cat /proc/10913/stack
__switch_to+0x94/0xd8
synchronize_irq+0x8c/0xc0
pcie_pme_suspend+0xa4/0x118
pcie_pme_remove+0x20/0x40
pcie_port_remove_service+0x3c/0x58
...
pcie_port_device_remove+0x2c/0x48
pcie_portdrv_remove+0x68/0x78
pci_device_remove+0x48/0x120
...
pci_stop_bus_device+0x84/0xc0
pci_stop_and_remove_bus_device_locked+0x24/0x40
remove_store+0xa4/0xb8
dev_attr_store+0x44/0x60
sysfs_kf_write+0x58/0x80

It is incorrect to call pcie_pme_suspend() from pcie_pme_remove() for two
reasons.

First, pcie_pme_suspend() calls synchronize_irq(), which will wait for the
native hotplug interrupt handler as well as for the PME one, because they
share one IRQ (as per the spec). That may deadlock if hotplug is signaled
while pcie_pme_remove() is running and the latter calls
pci_lock_rescan_remove() before the former.

Second, if pcie_pme_suspend() figures out that wakeup needs to be enabled
for the port, it will return without disabling the interrupt as expected by
pcie_pme_remove() which was overlooked by commit c7b5a4e6e8fb ("PCI / PM:
Fix native PME handling during system suspend/resume").

To fix that, rework pcie_pme_remove() to disable the PME interrupt, clear
its status and prevent the PME worker function from re-enabling it before
calling free_irq() on it, which should be sufficient.

Fixes: c7b5a4e6e8fb ("PCI / PM: Fix native PME handling during system suspend/resume")
Link: https://lore.kernel.org/linux-pci/c7697e7c-e1af-13e4-8491-0a3996e6ab5d@huawei.com
Reported-by: Dongdong Liu <liudongdong3@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[bhelgaas: add URL and deadlock details from Dongdong]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# c528f7bd 31-Jan-2019 Mika Westerberg <mika.westerberg@linux.intel.com>

Revert "PCI/PME: Implement runtime PM callbacks"

This reverts commit 0e157e52860441cb26051f131dd0b5ae3187a07b.

Heiner reported that the commit in question prevents his network adapter
from triggering PME and waking up when network cable is plugged.

The commit tried to prevent root port waking up from D3cold immediately but
looks like disabing root port PME interrupt is not the right way to fix
that issue so revert it now. The patch following proposes an alternative
solution to that issue.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=202103
Fixes: 0e157e528604 ("PCI/PME: Implement runtime PM callbacks")
Reported-by: Heiner Kallweit <hkallweit1@gmail.com>
Tested-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
CC: stable@vger.kernel.org # v4.20+


# 0e157e52 27-Sep-2018 Mika Westerberg <mika.westerberg@linux.intel.com>

PCI/PME: Implement runtime PM callbacks

Basically we need to do the same steps than what we do when system sleep is
entered and disable PME interrupt when the root port is runtime suspended.
This prevents spurious wakeups immediately when the port is transitioned
into D3cold.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# c29de841 20-Sep-2018 Keith Busch <kbusch@kernel.org>

PCI: portdrv: Initialize service drivers directly

The PCI port driver saves the PCI state after initializing the device with
the applicable service devices. This was, however, before the service
drivers were even registered because PCI probe happens before the
device_initcall initialized those service drivers. The config space state
that the services set up were not being saved. The end result would cause
PCI devices to not react to events that the drivers think they did if the
PCI state ever needed to be restored.

Fix this by changing the service drivers from using the init calls to
having the portdrv driver calling the services directly. This will get the
state saved as desired, while making the relationship between the port
driver and the services under it more explicit in the code.

Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Sinan Kaya <okaya@kernel.org>


# ef794260 09-Mar-2018 Bjorn Helgaas <bhelgaas@google.com>

PCI/portdrv: Merge pcieport_if.h into portdrv.h

pcieport_if.h contained the interfaces to register port service driver,
e.g., pcie_port_service_register(). portdrv.h contained internal data
structures of the port driver.

I don't think it's worth keeping those files separate, since both headers
and their users are all inside the PCI core.

Merge pcieport_if.h directly in drivers/pci/pcie/portdrv.h and update the
users to include that instead.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>


# c37e627f 13-Feb-2018 Frederick Lawler <fred@fredlawl.com>

PCI/portdrv: Move pcieport_if.h to drivers/pci/pcie/

Move pcieport_if.h from include/linux to drivers/pci/pcie/pcieport_if.h
because the interfaces there are only used by the PCI core.

Replace all uses of #include<linux/pcieport_if.h> with relative paths to
the new file location, e.g., #include "../pcieport_if.h"

Signed-off-by: Frederick Lawler <fred@fredlawl.com>
Signed-off-by: Bjorn Helgaas <helgaas@kernel.org>


# 8cfab3cf 25-Jan-2018 Bjorn Helgaas <bhelgaas@google.com>

PCI: Add SPDX GPL-2.0 to replace GPL v2 boilerplate

Add SPDX GPL-2.0 to all PCI files that specified the GPL version 2 license.

Remove the boilerplate GPL version 2 language, relying on the assertion in
b24413180f56 ("License cleanup: add SPDX GPL-2.0 license identifier to
files with no license") that the SPDX identifier may be used instead of the
full boilerplate text.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


# 7506dc79 17-Jan-2018 Frederick Lawler <fred@fredlawl.com>

PCI: Add wrappers for dev_printk()

Add PCI-specific dev_printk() wrappers and use them to simplify the code
slightly. No functional change intended.

Signed-off-by: Frederick Lawler <fred@fredlawl.com>
[bhelgaas: squash into one patch]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 3ad3f8ce 27-Sep-2017 Qiang <zhengqiang10@huawei.com>

PCI/PME: Handle invalid data when reading Root Status

PCIe PME and native hotplug share the same interrupt number, so hotplug
interrupts are also processed by PME. In some cases, e.g., a Link Down
interrupt, a device may be present but unreachable, so when we try to
read its Root Status register, the read fails and we get all ones data
(0xffffffff).

Previously, we interpreted that data as PCI_EXP_RTSTA_PME being set, i.e.,
"some device has asserted PME," so we scheduled pcie_pme_work_fn(). This
caused an infinite loop because pcie_pme_work_fn() tried to handle PME
requests until PCI_EXP_RTSTA_PME is cleared, but with the link down,
PCI_EXP_RTSTA_PME can't be cleared.

Check for the invalid 0xffffffff data everywhere we read the Root Status
register.

1469d17dd341 ("PCI: pciehp: Handle invalid data when reading from
non-existent devices") added similar checks in the hotplug driver.

Signed-off-by: Qiang Zheng <zhengqiang10@huawei.com>
[bhelgaas: changelog, also check in pcie_pme_work_fn(), use "~0" to follow
other similar checks]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# c7b5a4e6 05-Jul-2017 Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PCI / PM: Fix native PME handling during system suspend/resume

Commit 76cde7e49590 (PCI / PM: Make PCIe PME interrupts wake up from
suspend-to-idle) went too far with preventing pcie_pme_work_fn() from
clearing the root port's PME Status and re-enabling the PME interrupt
which should be done for PMEs to work correctly after system resume.

The failing scenario is as follows:

1. pcie_pme_suspend() finds that the PME IRQ should be designated
for system wakeup, so it calls enable_irq_wake() and then sets
data->suspend_level to PME_SUSPEND_WAKEUP.

2. PME interrupt happens at this point.

3. pcie_pme_irq() runs, disables the PME interrupt and queues up
the execution of pcie_pme_work_fn().

4. pcie_pme_work_fn() runs before pcie_pme_resume() and breaks out
of the loop right away, because data->suspend_level is not
PME_SUSPEND_NONE, and it doesn't re-enable the PME interrupt
for the same reason.

5. pcie_pme_resume() runs and simply calls disable_irq_wake()
without re-enabling the PME interrupt (because data->suspend_level
is not PME_SUSPEND_NONE), so the PME interrupt remains disabled
and the PME Status remains set.

To fix this notice that there is no reason why pcie_pme_work_fn()
should behave in a special way during system resume if the PME
interrupt is not disabled by pcie_pme_suspend() and partially revert
commit 76cde7e49590 and restore the previous (and correct) behavior
of pcie_pme_work_fn().

Fixes: 76cde7e49590 (PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle)
Reported-and-tested-by: Naresh Solanki <naresh.solanki@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>


# de3ef1eb 23-Jun-2017 Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PM / core: Drop run_wake flag from struct dev_pm_info

The run_wake flag in struct dev_pm_info is used to indicate whether
or not the device is capable of generating remote wakeup signals at
run time (or in the system working state), but the distinction
between runtime remote wakeup and system wakeup signaling has always
been rather artificial. The only practical reason for it to exist
at the core level was that ACPI and PCI treated those two cases
differently, but that's not the case any more after recent changes.

For this reason, get rid of the run_wake flag and, when applicable,
use device_set_wakeup_capable() and device_can_wakeup() instead of
device_set_run_wake() and device_run_wake(), respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>


# 8370c2dc 23-Jun-2017 Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PCI / PM: Drop pme_interrupt flag from struct pci_dev

The pme_interrupt flag in struct pci_dev is set when PMEs generated
by the device are going to be signaled via root port PME interrupts.

Ironically enough, that information is only used by the code setting
up device wakeup through ACPI which returns as soon as it sees the
pme_interrupt flag set while setting up "remote runtime wakeup".
That is questionable, however, because in theory there may be PCIe
devices using out-of-band PME signaling under root ports handled
by the native PME code or devices requiring wakeup power setup to be
carried out by AML. For such devices, ACPI wakeup should be invoked
regardless of whether or not native PME signaling is used in general.

For this reason, drop the pme_interrupt flag and rework the code
using it which then allows the ACPI-based device wakeup handling
in PCI to be consolidated to use one code path for both "runtime
remote wakeup" and system wakeup (from sleep states).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>


# afe3e4d1 14-Feb-2017 Yinghai Lu <yinghai@kernel.org>

PCI/PME: Restore pcie_pme_driver.remove

In addition to making PME non-modular, d7def2040077 ("PCI/PME: Make
explicitly non-modular") removed the pcie_pme_driver .remove() method,
pcie_pme_remove().

pcie_pme_remove() freed the PME IRQ that was requested in pci_pme_probe().
The fact that we don't free the IRQ after d7def2040077 causes the following
crash when removing a PCIe port device via /sys:

------------[ cut here ]------------
kernel BUG at drivers/pci/msi.c:370!
invalid opcode: 0000 [#1] SMP
Modules linked in:
CPU: 1 PID: 14509 Comm: sh Tainted: G W 4.8.0-rc1-yh-00012-gd29438d
RIP: 0010:[<ffffffff9758bbf5>] free_msi_irqs+0x65/0x190
...
Call Trace:
[<ffffffff9758cda4>] pci_disable_msi+0x34/0x40
[<ffffffff97583817>] cleanup_service_irqs+0x27/0x30
[<ffffffff97583e9a>] pcie_port_device_remove+0x2a/0x40
[<ffffffff97584250>] pcie_portdrv_remove+0x40/0x50
[<ffffffff97576d7b>] pci_device_remove+0x4b/0xc0
[<ffffffff9785ebe6>] __device_release_driver+0xb6/0x150
[<ffffffff9785eca5>] device_release_driver+0x25/0x40
[<ffffffff975702e4>] pci_stop_bus_device+0x74/0xa0
[<ffffffff975704ea>] pci_stop_and_remove_bus_device_locked+0x1a/0x30
[<ffffffff97578810>] remove_store+0x50/0x70
[<ffffffff9785a378>] dev_attr_store+0x18/0x30
[<ffffffff97260b64>] sysfs_kf_write+0x44/0x60
[<ffffffff9725feae>] kernfs_fop_write+0x10e/0x190
[<ffffffff971e13f8>] __vfs_write+0x28/0x110
[<ffffffff970b0fa4>] ? percpu_down_read+0x44/0x80
[<ffffffff971e53a7>] ? __sb_start_write+0xa7/0xe0
[<ffffffff971e53a7>] ? __sb_start_write+0xa7/0xe0
[<ffffffff971e1f04>] vfs_write+0xc4/0x180
[<ffffffff971e3089>] SyS_write+0x49/0xa0
[<ffffffff97001a46>] do_syscall_64+0xa6/0x1b0
[<ffffffff9819201e>] entry_SYSCALL64_slow_path+0x25/0x25
...
RIP [<ffffffff9758bbf5>] free_msi_irqs+0x65/0x190
RSP <ffff89ad3085bc48>
---[ end trace f4505e1dac5b95d3 ]---
Segmentation fault

Restore pcie_pme_remove().

[bhelgaas: changelog]
Fixes: d7def2040077 ("PCI/PME: Make explicitly non-modular")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
CC: stable@vger.kernel.org # v4.9+


# a902d81a 21-Nov-2016 Bjorn Helgaas <bhelgaas@google.com>

PCI/PME: Log PME IRQ when claiming Root Port

We already log a "Signaling PME" whenever the PME service driver claims a
Root Port. In fact, we also log the same message for every device in the
hierarchy below the Root Port.

Log the "Signaling PME" once (only for the Root Port, since we can
trivially find out which devices are below the Root Port), and include the
IRQ number in the message to help connect the dots with /proc/interrupts.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 0a1e1b26 21-Nov-2016 Bjorn Helgaas <bhelgaas@google.com>

PCI/PME: Drop unused support for PMEs from Root Complex Event Collectors

Since we register pcie_pme_driver only for PCI_EXP_TYPE_ROOT_PORT, the PME
driver never claims Root Complex Event Collectors.

Remove unused code related to Root Complex Event Collectors.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# d7def204 24-Aug-2016 Paul Gortmaker <paul.gortmaker@windriver.com>

PCI/PME: Make explicitly non-modular

This code is not being built as a module by anyone:

config PCIE_PME
def_bool y
depends on PCIEPORTBUS && PM

Remove traces of modularity so that when reading the driver there is no
doubt it is builtin-only.

Also delete the .remove function, since that doesn't seem to have a
sensible use case. With "normal" endpoint drivers, we have in the past set
the suppress_bind_attrs bit to make it clear that the use of ".remove" in a
builtin driver was deleted, but here for PCI, it seems overkill to jump
through the pcie_port_service_driver and into the struct device_driver in
order to finally try and do something similar with the bind setting.

Note that for non-modular code, module_init() translates to
device_initcall().

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 41ccebae 05-Feb-2016 Bjorn Helgaas <bhelgaas@google.com>

PCI/PME: Restructure pcie_pme_suspend() to prevent compiler warning

Previously we had this:

if (wakeup)
ret = enable_irq_wake(...);
if (!wakeup || ret)
...

"ret" is only evaluated when "wakeup" is true, and it is always initialized
in that case, but gcc isn't smart enough to figure that out and warns:

drivers/pci/pcie/pme.c:414:14: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]

Restructure the code slightly to make it easier for gcc (and maybe for
humans as well).

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com


# 4e48fe41 05-Feb-2016 Bjorn Helgaas <bhelgaas@google.com>

PCI/PME: Remove redundant port lookup

We've already looked up srv->port a few lines earlier, and there's no need
to do it again. Remove the redundant lookup.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com


# 5dfd7f9f 22-Oct-2014 Lucas Stach <l.stach@pengutronix.de>

PCI / PM: handle failure to enable wakeup on PCIe PME

If the irqchip handling the PCIe PME interrupt is not able
to enable interrupt wakeup we should properly reflect this
in the PME suspend status.

This fixes a kernel warning on resume, where it would try
to disable the irq wakeup that failed to be activated while
suspending, for example:

WARNING: CPU: 0 PID: 609 at kernel/irq/manage.c:536 irq_set_irq_wake+0xc0/0xf8()
Unbalanced IRQ 384 wake disable

Fixes: 76cde7e49590 (PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle)
Reported-and-tested-by: Richard Zhu <richard.zhu@freescale.com>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 76cde7e4 01-Sep-2014 Rafael J. Wysocki <rafael.j.wysocki@intel.com>

PCI / PM: Make PCIe PME interrupts wake up from suspend-to-idle

To make PCIe PME interrupts wake up the system from suspend to idle,
make the PME driver use enable_irq_wake() on the IRQ during system
suspend (if there are any wakeup devices below the given PCIe port)
without disabling PME interrupts. This way, an interrupt will still
trigger if a wakeup event happens and the system will be woken up (or
system suspend in progress will be aborted) by means of the new
mechanics introduced previously.

This change allows Wake-on-LAN to be used for wakeup from
suspend-to-idle on my MSI Wind tesbed netbook.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 227f0647 18-Apr-2014 Ryan Desfosses <ryan@desfo.org>

PCI: Merge multi-line quoted strings

Merge quoted strings that are broken across lines into a single entity.
The compiler merges them anyway, but checkpatch complains about it, and
merging them makes it easier to grep for strings.

No functional change.

[bhelgaas: changelog, do the same for everything under drivers/pci]
Signed-off-by: Ryan Desfosses <ryan@desfo.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# f7625980 14-Nov-2013 Bjorn Helgaas <bhelgaas@google.com>

PCI: Fix whitespace, capitalization, and spelling errors

Fix whitespace, capitalization, and spelling errors. No functional change.
I know "busses" is not an error, but "buses" was more common, so I used it
consistently.

Signed-off-by: Marta Rybczynska <rybczynska@gmail.com> (pci_reset_bridge_secondary_bus())
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# bd0c5024 08-Jun-2013 Yijing Wang <wangyijing@huawei.com>

PCI: Fix comment typo for pcie_pme_remove()

Fix trivial comment typo for pcie_pme_remove().

Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 05795726 11-Apr-2013 Bjorn Helgaas <bhelgaas@google.com>

PCI: Remove unnecessary dependencies between PME and ACPI

PCIe PME doesn't depend on ACPI, so remove the #includes and
Kconfig dependency.

Based-on-patch-by: Andrew Murray <Andrew.Murray@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>


# 263e54b9 24-Jul-2012 Jiang Liu <jiang.liu@huawei.com>

PCI/PME: Use PCI Express Capability accessors

Use PCI Express Capability access functions to simplify PCIe PME.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 62f87c0e 24-Jul-2012 Yijing Wang <wangyijing@huawei.com>

PCI: Introduce pci_pcie_type(dev) to replace pci_dev->pcie_type

Introduce an inline function pci_pcie_type(dev) to extract PCIe
device type from pci_dev->pcie_flags_reg field, and prepare for
removing pci_dev->pcie_type.

Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>


# 379021d5 03-Oct-2011 Rafael J. Wysocki <rjw@rjwysocki.net>

PCI / PM: Extend PME polling to all PCI devices

The land of PCI power management is a land of sorrow and ugliness,
especially in the area of signaling events by devices. There are
devices that set their PME Status bits, but don't really bother
to send a PME message or assert PME#. There are hardware vendors
who don't connect PME# lines to the system core logic (they know
who they are). There are PCI Express Root Ports that don't bother
to trigger interrupts when they receive PME messages from the devices
below. There are ACPI BIOSes that forget to provide _PRW methods for
devices capable of signaling wakeup. Finally, there are BIOSes that
do provide _PRW methods for such devices, but then don't bother to
call Notify() for those devices from the corresponding _Lxx/_Exx
GPE-handling methods. In all of these cases the kernel doesn't have
a chance to receive a proper notification that it should wake up a
device, so devices stay in low-power states forever. Worse yet, in
some cases they continuously send PME Messages that are silently
ignored, because the kernel simply doesn't know that it should clear
the device's PME Status bit.

This problem was first observed for "parallel" (non-Express) PCI
devices on add-on cards and Matthew Garrett addressed it by adding
code that polls PME Status bits of such devices, if they are enabled
to signal PME, to the kernel. Recently, however, it has turned out
that PCI Express devices are also affected by this issue and that it
is not limited to add-on devices, so it seems necessary to extend
the PME polling to all PCI devices, including PCI Express and planar
ones. Still, it would be wasteful to poll the PME Status bits of
devices that are known to receive proper PME notifications, so make
the kernel (1) poll the PME Status bits of all PCI and PCIe devices
enabled to signal PME and (2) disable the PME Status polling for
devices for which correct PME notifications are received.

Tested-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>


# 0f953bf6 29-Dec-2010 Rafael J. Wysocki <rjw@rjwysocki.net>

PCI/PM: Report wakeup events before resuming devices

Make wakeup events be reported by the PCI subsystem before attempting to
resume devices or queuing up runtime resume requests for them, because
wakeup events should be reported as soon as they have been detected.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>


# fe31e697 19-Dec-2010 Rafael J. Wysocki <rjw@rjwysocki.net>

PCI/PCIe: Clear Root PME Status bits early during system resume

I noticed that PCI Express PMEs don't work on my Toshiba Portege R500
after the system has been woken up from a sleep state by a PME
(through Wake-on-LAN). After some investigation it turned out that
the BIOS didn't clear the Root PME Status bit in the root port that
received the wakeup PME and since the Requester ID was also set in
the port's Root Status register, any subsequent PMEs didn't trigger
interrupts.

This problem can be avoided by clearing the Root PME Status bits in
all PCI Express root ports during early resume. For this purpose,
add an early resume routine to the PCIe port driver and make this
driver be always registered, even if pci_ports_disable is set (in
which case the driver's only function is to provide the early
resume callback).

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>


# 271fb719 20-Aug-2010 Rafael J. Wysocki <rjw@rjwysocki.net>

PCI: PCIe: Move PCIe PME code to the pcie directory

The PCIe PME code only consists of one file, so it doesn't need to
occupy its own directory. Move it to drivers/pci/pcie/pme.c and
remove the contents of drivers/pci/pcie/pme .

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>