Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/pci/pci.c
Show First 20 Lines • Show All 4,461 Lines • ▼ Show 20 Lines | if (device_is_attached(child) && | ||||
PCIB_POWER_FOR_SLEEP(pcib, child, &dstate) == 0) | PCIB_POWER_FOR_SLEEP(pcib, child, &dstate) == 0) | ||||
pci_set_powerstate(child, dstate); | pci_set_powerstate(child, dstate); | ||||
} | } | ||||
int | int | ||||
pci_suspend_child(device_t dev, device_t child) | pci_suspend_child(device_t dev, device_t child) | ||||
{ | { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
struct resource_list_entry *rle; | |||||
int error; | int error; | ||||
dinfo = device_get_ivars(child); | dinfo = device_get_ivars(child); | ||||
/* | /* | ||||
* Save the PCI configuration space for the child and set the | * Save the PCI configuration space for the child and set the | ||||
* device in the appropriate power state for this sleep state. | * device in the appropriate power state for this sleep state. | ||||
*/ | */ | ||||
pci_cfg_save(child, dinfo, 0); | pci_cfg_save(child, dinfo, 0); | ||||
/* Suspend devices before potentially powering them down. */ | /* Suspend devices before potentially powering them down. */ | ||||
error = bus_generic_suspend_child(dev, child); | error = bus_generic_suspend_child(dev, child); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
if (pci_do_power_suspend) | if (pci_do_power_suspend) { | ||||
/* | |||||
* Make sure this device's interrupt handler is not invoked | |||||
* in the case the device uses a shared interrupt that can | |||||
* be raised by some other device. | |||||
* This is applicable only to regular (legacy) PCI interrupts | |||||
* as MSI/MSI-X interrupts are never shared. | |||||
*/ | |||||
rle = resource_list_find(&dinfo->resources, | |||||
SYS_RES_IRQ, 0); | |||||
if (rle != NULL && rle->res != NULL) | |||||
(void)bus_suspend_intr(child, rle->res); | |||||
pci_set_power_child(dev, child, PCI_POWERSTATE_D3); | pci_set_power_child(dev, child, PCI_POWERSTATE_D3); | ||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pci_resume_child(device_t dev, device_t child) | pci_resume_child(device_t dev, device_t child) | ||||
{ | { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
struct resource_list_entry *rle; | |||||
if (pci_do_power_resume) | if (pci_do_power_resume) | ||||
pci_set_power_child(dev, child, PCI_POWERSTATE_D0); | pci_set_power_child(dev, child, PCI_POWERSTATE_D0); | ||||
dinfo = device_get_ivars(child); | dinfo = device_get_ivars(child); | ||||
pci_cfg_restore(child, dinfo); | pci_cfg_restore(child, dinfo); | ||||
if (!device_is_attached(child)) | if (!device_is_attached(child)) | ||||
pci_cfg_save(child, dinfo, 1); | pci_cfg_save(child, dinfo, 1); | ||||
bus_generic_resume_child(dev, child); | bus_generic_resume_child(dev, child); | ||||
/* | |||||
* Allow interrupts only after fully resuming the driver and hardware. | |||||
*/ | |||||
if (pci_do_power_suspend) { | |||||
/* See pci_suspend_child for details. */ | |||||
rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 0); | |||||
if (rle != NULL && rle->res != NULL) | |||||
(void)bus_resume_intr(child, rle->res); | |||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
pci_resume(device_t dev) | pci_resume(device_t dev) | ||||
{ | { | ||||
device_t child, *devlist; | device_t child, *devlist; | ||||
▲ Show 20 Lines • Show All 1,990 Lines • Show Last 20 Lines |