diff options
author | Kishon Vijay Abraham I <kishon@ti.com> | 2021-02-02 01:27:55 +0530 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2021-02-23 14:10:34 -0600 |
commit | fa8fef0e104a23efe568b835d9e7e188d1d97610 (patch) | |
tree | 2851deb51e0e704cd62e85a18145ba0504b277c9 | |
parent | 959a48d0eac0321948c9f3d1707ba22c100e92d5 (diff) |
PCI: endpoint: Add helper API to get the 'next' unreserved BAR
Add an API to get the next unreserved BAR starting from a given BAR number
that can be used by the endpoint function.
Link: https://lore.kernel.org/r/20210201195809.7342-4-kishon@ti.com
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/pci/endpoint/pci-epc-core.c | 26 | ||||
-rw-r--r-- | include/linux/pci-epc.h | 2 |
2 files changed, 24 insertions, 4 deletions
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 25e57672e1a1..1afe5d9afb0d 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -87,17 +87,36 @@ EXPORT_SYMBOL_GPL(pci_epc_get); * pci_epc_get_first_free_bar() - helper to get first unreserved BAR * @epc_features: pci_epc_features structure that holds the reserved bar bitmap * - * Invoke to get the first unreserved BAR that can be used for endpoint + * Invoke to get the first unreserved BAR that can be used by the endpoint * function. For any incorrect value in reserved_bar return '0'. */ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features) { + return pci_epc_get_next_free_bar(epc_features, BAR_0); +} +EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar); + +/** + * pci_epc_get_next_free_bar() - helper to get unreserved BAR starting from @bar + * @epc_features: pci_epc_features structure that holds the reserved bar bitmap + * @bar: the starting BAR number from where unreserved BAR should be searched + * + * Invoke to get the next unreserved BAR starting from @bar that can be used + * for endpoint function. For any incorrect value in reserved_bar return '0'. + */ +unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features + *epc_features, enum pci_barno bar) +{ unsigned long free_bar; if (!epc_features) return 0; + /* If 'bar - 1' is a 64-bit BAR, move to the next BAR */ + if ((epc_features->bar_fixed_64bit << 1) & 1 << bar) + bar++; + /* Find if the reserved BAR is also a 64-bit BAR */ free_bar = epc_features->reserved_bar & epc_features->bar_fixed_64bit; @@ -105,14 +124,13 @@ unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features free_bar <<= 1; free_bar |= epc_features->reserved_bar; - /* Now find the free BAR */ - free_bar = ffz(free_bar); + free_bar = find_next_zero_bit(&free_bar, 6, bar); if (free_bar > 5) return 0; return free_bar; } -EXPORT_SYMBOL_GPL(pci_epc_get_first_free_bar); +EXPORT_SYMBOL_GPL(pci_epc_get_next_free_bar); /** * pci_epc_get_features() - get the features supported by EPC diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index cc66bec8be90..cfe9b427e6b7 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -203,6 +203,8 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, u8 func_no); unsigned int pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features); +unsigned int pci_epc_get_next_free_bar(const struct pci_epc_features + *epc_features, enum pci_barno bar); struct pci_epc *pci_epc_get(const char *epc_name); void pci_epc_put(struct pci_epc *epc); |