PCI: add set_powerstate and get_powerstate hooks
Change-Id: I8e32b5fccba3461cdb1b0c6e81b15705b2be1c57 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2447 Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
@@ -36,6 +36,8 @@ typedef struct pci_device_module_info {
|
|||||||
void (*get_pci_info)(pci_device *device, struct pci_info *info);
|
void (*get_pci_info)(pci_device *device, struct pci_info *info);
|
||||||
status_t (*find_pci_extended_capability)(pci_device *device, uint16 capID,
|
status_t (*find_pci_extended_capability)(pci_device *device, uint16 capID,
|
||||||
uint16 *offset);
|
uint16 *offset);
|
||||||
|
uint8 (*get_powerstate)(pci_device *device);
|
||||||
|
void (*set_powerstate)(pci_device *device, uint8 state);
|
||||||
} pci_device_module_info;
|
} pci_device_module_info;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1801,3 +1801,34 @@ PCI::UpdateInterruptLine(uint8 domain, uint8 bus, uint8 _device, uint8 function,
|
|||||||
|
|
||||||
return WriteConfig(device, PCI_interrupt_line, 1, newInterruptLineValue);
|
return WriteConfig(device, PCI_interrupt_line, 1, newInterruptLineValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8
|
||||||
|
PCI::GetPowerstate(PCIDev *device)
|
||||||
|
{
|
||||||
|
uint8 capabilityOffset;
|
||||||
|
status_t res = FindCapability(device, PCI_cap_id_pm, &capabilityOffset);
|
||||||
|
if (res == B_OK) {
|
||||||
|
uint32 state = ReadConfig(device, capabilityOffset + PCI_pm_status, 2);
|
||||||
|
return (state & PCI_pm_mask);
|
||||||
|
}
|
||||||
|
return PCI_pm_state_d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PCI::SetPowerstate(PCIDev *device, uint8 newState)
|
||||||
|
{
|
||||||
|
uint8 capabilityOffset;
|
||||||
|
status_t res = FindCapability(device, PCI_cap_id_pm, &capabilityOffset);
|
||||||
|
if (res == B_OK) {
|
||||||
|
uint32 state = ReadConfig(device, capabilityOffset + PCI_pm_status, 2);
|
||||||
|
if ((state & PCI_pm_mask) != newState) {
|
||||||
|
WriteConfig(device, capabilityOffset + PCI_pm_status, 2,
|
||||||
|
(state & ~PCI_pm_mask) | newState);
|
||||||
|
if ((state & PCI_pm_mask) == PCI_pm_state_d3)
|
||||||
|
snooze(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,9 @@ public:
|
|||||||
|
|
||||||
void ClearDeviceStatus(PCIBus *bus, bool dumpStatus);
|
void ClearDeviceStatus(PCIBus *bus, bool dumpStatus);
|
||||||
|
|
||||||
|
uint8 GetPowerstate(PCIDev *device);
|
||||||
|
void SetPowerstate(PCIDev *device, uint8 state);
|
||||||
|
|
||||||
void RefreshDeviceInfo();
|
void RefreshDeviceInfo();
|
||||||
|
|
||||||
status_t UpdateInterruptLine(uint8 domain, uint8 bus,
|
status_t UpdateInterruptLine(uint8 domain, uint8 bus,
|
||||||
|
|||||||
@@ -102,6 +102,20 @@ pci_device_find_extended_capability(pci_device* device, uint16 capID,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8
|
||||||
|
pci_device_get_powerstate(pci_device *device)
|
||||||
|
{
|
||||||
|
return gPCI->GetPowerstate(device->device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
pci_device_set_powerstate(pci_device *device, uint8 state)
|
||||||
|
{
|
||||||
|
return gPCI->SetPowerstate(device->device, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pci_device_get_pci_info(pci_device* device, struct pci_info* info)
|
pci_device_get_pci_info(pci_device* device, struct pci_info* info)
|
||||||
{
|
{
|
||||||
@@ -196,5 +210,7 @@ pci_device_module_info gPCIDeviceModule = {
|
|||||||
pci_device_write_pci_config,
|
pci_device_write_pci_config,
|
||||||
pci_device_find_capability,
|
pci_device_find_capability,
|
||||||
pci_device_get_pci_info,
|
pci_device_get_pci_info,
|
||||||
pci_device_find_extended_capability
|
pci_device_find_extended_capability,
|
||||||
|
pci_device_get_powerstate,
|
||||||
|
pci_device_set_powerstate
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user