提交 961d9120 编写于 作者: R Rafael J. Wysocki 提交者: Jesse Barnes

PCI: Introduce platform_pci_power_manageable function

Introduce function pointer platform_pci_power_manageable to be used
by the platform-related code to point to a function allowing us to
check if given device is power manageable by the platform.

Introduce acpi_pci_power_manageable() playing that role for ACPI.
Signed-off-by: NRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: NJesse Barnes <jbarnes@virtuousgeek.org>
上级 3737b2b1
...@@ -215,7 +215,6 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) ...@@ -215,7 +215,6 @@ acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
} }
EXPORT_SYMBOL(pci_osc_control_set); EXPORT_SYMBOL(pci_osc_control_set);
#ifdef CONFIG_ACPI_SLEEP
/* /*
* _SxD returns the D-state with the highest power * _SxD returns the D-state with the highest power
* (lowest D-state number) supported in the S-state "x". * (lowest D-state number) supported in the S-state "x".
...@@ -259,7 +258,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) ...@@ -259,7 +258,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
} }
return PCI_POWER_ERROR; return PCI_POWER_ERROR;
} }
#endif
static bool acpi_pci_power_manageable(struct pci_dev *dev)
{
acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
return handle ? acpi_bus_power_manageable(handle) : false;
}
static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{ {
...@@ -290,6 +295,11 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -290,6 +295,11 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return -EINVAL; return -EINVAL;
} }
static struct pci_platform_pm_ops acpi_pci_platform_pm = {
.is_manageable = acpi_pci_power_manageable,
.set_state = acpi_pci_set_power_state,
.choose_state = acpi_pci_choose_state,
};
/* ACPI bus type */ /* ACPI bus type */
static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
...@@ -341,10 +351,7 @@ static int __init acpi_pci_init(void) ...@@ -341,10 +351,7 @@ static int __init acpi_pci_init(void)
ret = register_acpi_bus_type(&acpi_pci_bus); ret = register_acpi_bus_type(&acpi_pci_bus);
if (ret) if (ret)
return 0; return 0;
#ifdef CONFIG_ACPI_SLEEP pci_set_platform_pm(&acpi_pci_platform_pm);
platform_pci_choose_state = acpi_pci_choose_state;
#endif
platform_pci_set_power_state = acpi_pci_set_power_state;
return 0; return 0;
} }
arch_initcall(acpi_pci_init); arch_initcall(acpi_pci_init);
...@@ -376,7 +376,32 @@ pci_restore_bars(struct pci_dev *dev) ...@@ -376,7 +376,32 @@ pci_restore_bars(struct pci_dev *dev)
pci_update_resource(dev, &dev->resource[i], i); pci_update_resource(dev, &dev->resource[i], i);
} }
int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); static struct pci_platform_pm_ops *pci_platform_pm;
int pci_set_platform_pm(struct pci_platform_pm_ops *ops)
{
if (!ops->is_manageable || !ops->set_state || !ops->choose_state)
return -EINVAL;
pci_platform_pm = ops;
return 0;
}
static inline bool platform_pci_power_manageable(struct pci_dev *dev)
{
return pci_platform_pm ? pci_platform_pm->is_manageable(dev) : false;
}
static inline int platform_pci_set_power_state(struct pci_dev *dev,
pci_power_t t)
{
return pci_platform_pm ? pci_platform_pm->set_state(dev, t) : -ENOSYS;
}
static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
{
return pci_platform_pm ?
pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
}
/** /**
* pci_set_power_state - Set the power state of a PCI device * pci_set_power_state - Set the power state of a PCI device
...@@ -479,7 +504,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -479,7 +504,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
* Give firmware a chance to be called, such as ACPI _PRx, _PSx * Give firmware a chance to be called, such as ACPI _PRx, _PSx
* Firmware method after native method ? * Firmware method after native method ?
*/ */
if (platform_pci_set_power_state)
platform_pci_set_power_state(dev, state); platform_pci_set_power_state(dev, state);
dev->current_state = state; dev->current_state = state;
...@@ -505,8 +529,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -505,8 +529,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return 0; return 0;
} }
pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev);
/** /**
* pci_choose_state - Choose the power state of a PCI device * pci_choose_state - Choose the power state of a PCI device
* @dev: PCI device to be suspended * @dev: PCI device to be suspended
...@@ -524,11 +546,9 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) ...@@ -524,11 +546,9 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
if (!pci_find_capability(dev, PCI_CAP_ID_PM)) if (!pci_find_capability(dev, PCI_CAP_ID_PM))
return PCI_D0; return PCI_D0;
if (platform_pci_choose_state) {
ret = platform_pci_choose_state(dev); ret = platform_pci_choose_state(dev);
if (ret != PCI_POWER_ERROR) if (ret != PCI_POWER_ERROR)
return ret; return ret;
}
switch (state.event) { switch (state.event) {
case PM_EVENT_ON: case PM_EVENT_ON:
......
...@@ -5,10 +5,28 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); ...@@ -5,10 +5,28 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev); extern void pci_cleanup_rom(struct pci_dev *dev);
/* Firmware callbacks */ /**
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev); * Firmware PM callbacks
extern int (*platform_pci_set_power_state)(struct pci_dev *dev, *
pci_power_t state); * @is_manageable - returns 'true' if given device is power manageable by the
* platform firmware
*
* @set_state - invokes the platform firmware to set the device's power state
*
* @choose_state - returns PCI power state of given device preferred by the
* platform; to be used during system-wide transitions from a
* sleeping state to the working state and vice versa
*
* If given platform is generally capable of power managing PCI devices, all of
* these callbacks are mandatory.
*/
struct pci_platform_pm_ops {
bool (*is_manageable)(struct pci_dev *dev);
int (*set_state)(struct pci_dev *dev, pci_power_t state);
pci_power_t (*choose_state)(struct pci_dev *dev);
};
extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops);
extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); extern int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); extern int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册