diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 943727a7117dae9f82d81bd8bde8ed3bcd0a8009..ba0c26c5a94dbbfefbbce10e821c2a15bfea4fe6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1690,7 +1690,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev) pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX; res = pdev->resource + bar_idx; - size = ilog2(resource_size(res)) - 20; + size = pci_rebar_bytes_to_size(resource_size(res)); ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE; ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT; pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl); @@ -3647,6 +3647,7 @@ u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) return cap >> 4; } +EXPORT_SYMBOL(pci_rebar_get_possible_sizes); /** * pci_rebar_get_current_size - get the current size of a BAR diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0bc9927c2f5dd3da5cbf894c67f26672b4d6cdbe..c5066b971711073b4b465267e8c815be4c6277b3 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -643,7 +643,6 @@ static inline int acpi_get_rc_resources(struct device *dev, const char *hid, } #endif -u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar); int pci_rebar_get_current_size(struct pci_dev *pdev, int bar); int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size); static inline u64 pci_rebar_size_to_bytes(int size) diff --git a/include/linux/pci.h b/include/linux/pci.h index 9c79cf6a61422e2b0e6de8479038feb92f7698ec..70a61e73d4d35c87e22f9df42e65cb44c5aecb9a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1319,6 +1319,15 @@ void pci_update_resource(struct pci_dev *dev, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align); void pci_release_resource(struct pci_dev *dev, int resno); +static inline int pci_rebar_bytes_to_size(u64 bytes) +{ + bytes = roundup_pow_of_two(bytes); + + /* Return BAR size as defined in the resizable BAR specification */ + return max(ilog2(bytes), 20) - 20; +} + +u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar); int __must_check pci_resize_resource(struct pci_dev *dev, int i, int size); int pci_select_bars(struct pci_dev *dev, unsigned long flags); bool pci_device_is_present(struct pci_dev *pdev);