mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
PCI: Add support for save/restore of extended capabilities
Current save/restore is specific to standard capabilities. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
157e876ffe
commit
fd0f7f73ca
2 changed files with 43 additions and 9 deletions
|
@ -861,18 +861,28 @@ EXPORT_SYMBOL(pci_choose_state);
|
||||||
#define PCI_EXP_SAVE_REGS 7
|
#define PCI_EXP_SAVE_REGS 7
|
||||||
|
|
||||||
|
|
||||||
static struct pci_cap_saved_state *pci_find_saved_cap(
|
static struct pci_cap_saved_state *_pci_find_saved_cap(struct pci_dev *pci_dev,
|
||||||
struct pci_dev *pci_dev, char cap)
|
u16 cap, bool extended)
|
||||||
{
|
{
|
||||||
struct pci_cap_saved_state *tmp;
|
struct pci_cap_saved_state *tmp;
|
||||||
|
|
||||||
hlist_for_each_entry(tmp, &pci_dev->saved_cap_space, next) {
|
hlist_for_each_entry(tmp, &pci_dev->saved_cap_space, next) {
|
||||||
if (tmp->cap.cap_nr == cap)
|
if (tmp->cap.cap_extended == extended && tmp->cap.cap_nr == cap)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct pci_cap_saved_state *pci_find_saved_cap(struct pci_dev *dev, char cap)
|
||||||
|
{
|
||||||
|
return _pci_find_saved_cap(dev, cap, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev, u16 cap)
|
||||||
|
{
|
||||||
|
return _pci_find_saved_cap(dev, cap, true);
|
||||||
|
}
|
||||||
|
|
||||||
static int pci_save_pcie_state(struct pci_dev *dev)
|
static int pci_save_pcie_state(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -1113,7 +1123,7 @@ int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state)
|
||||||
while (cap->size) {
|
while (cap->size) {
|
||||||
struct pci_cap_saved_state *tmp;
|
struct pci_cap_saved_state *tmp;
|
||||||
|
|
||||||
tmp = pci_find_saved_cap(dev, cap->cap_nr);
|
tmp = _pci_find_saved_cap(dev, cap->cap_nr, cap->cap_extended);
|
||||||
if (!tmp || tmp->cap.size != cap->size)
|
if (!tmp || tmp->cap.size != cap->size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -2047,18 +2057,24 @@ static void pci_add_saved_cap(struct pci_dev *pci_dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_add_cap_save_buffer - allocate buffer for saving given capability registers
|
* _pci_add_cap_save_buffer - allocate buffer for saving given
|
||||||
|
* capability registers
|
||||||
* @dev: the PCI device
|
* @dev: the PCI device
|
||||||
* @cap: the capability to allocate the buffer for
|
* @cap: the capability to allocate the buffer for
|
||||||
|
* @extended: Standard or Extended capability ID
|
||||||
* @size: requested size of the buffer
|
* @size: requested size of the buffer
|
||||||
*/
|
*/
|
||||||
static int pci_add_cap_save_buffer(
|
static int _pci_add_cap_save_buffer(struct pci_dev *dev, u16 cap,
|
||||||
struct pci_dev *dev, char cap, unsigned int size)
|
bool extended, unsigned int size)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
struct pci_cap_saved_state *save_state;
|
struct pci_cap_saved_state *save_state;
|
||||||
|
|
||||||
pos = pci_find_capability(dev, cap);
|
if (extended)
|
||||||
|
pos = pci_find_ext_capability(dev, cap);
|
||||||
|
else
|
||||||
|
pos = pci_find_capability(dev, cap);
|
||||||
|
|
||||||
if (pos <= 0)
|
if (pos <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -2067,12 +2083,23 @@ static int pci_add_cap_save_buffer(
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
save_state->cap.cap_nr = cap;
|
save_state->cap.cap_nr = cap;
|
||||||
|
save_state->cap.cap_extended = extended;
|
||||||
save_state->cap.size = size;
|
save_state->cap.size = size;
|
||||||
pci_add_saved_cap(dev, save_state);
|
pci_add_saved_cap(dev, save_state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pci_add_cap_save_buffer(struct pci_dev *dev, char cap, unsigned int size)
|
||||||
|
{
|
||||||
|
return _pci_add_cap_save_buffer(dev, cap, false, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pci_add_ext_cap_save_buffer(struct pci_dev *dev, u16 cap, unsigned int size)
|
||||||
|
{
|
||||||
|
return _pci_add_cap_save_buffer(dev, cap, true, size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_allocate_cap_save_buffers - allocate buffers for saving capabilities
|
* pci_allocate_cap_save_buffers - allocate buffers for saving capabilities
|
||||||
* @dev: the PCI device
|
* @dev: the PCI device
|
||||||
|
|
|
@ -224,7 +224,8 @@ enum pci_bus_speed {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pci_cap_saved_data {
|
struct pci_cap_saved_data {
|
||||||
char cap_nr;
|
u16 cap_nr;
|
||||||
|
bool cap_extended;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
u32 data[0];
|
u32 data[0];
|
||||||
};
|
};
|
||||||
|
@ -977,6 +978,12 @@ struct pci_saved_state *pci_store_saved_state(struct pci_dev *dev);
|
||||||
int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state);
|
int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state);
|
||||||
int pci_load_and_free_saved_state(struct pci_dev *dev,
|
int pci_load_and_free_saved_state(struct pci_dev *dev,
|
||||||
struct pci_saved_state **state);
|
struct pci_saved_state **state);
|
||||||
|
struct pci_cap_saved_state *pci_find_saved_cap(struct pci_dev *dev, char cap);
|
||||||
|
struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev,
|
||||||
|
u16 cap);
|
||||||
|
int pci_add_cap_save_buffer(struct pci_dev *dev, char cap, unsigned int size);
|
||||||
|
int pci_add_ext_cap_save_buffer(struct pci_dev *dev,
|
||||||
|
u16 cap, unsigned int size);
|
||||||
int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);
|
int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);
|
||||||
int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
|
int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
|
||||||
pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
|
pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue