Hello Bjorn,
I tried to meet your requests from the last feedback round as much as
possible. Especially, I removed a lot of code, made almost all
interfaces private and cut the series into smaller chunks where
possible.
Splitting it even smaller is unfortunately not possible because of the
Linux kernel build chain's rule on dead / unused code.
See also the changelog below.
Please tell me if that's enough to move forward here.
Regards,
P.
Changes in v7:
- Split the entire series in smaller, more atomic chunks / patches
(Bjorn)
- Remove functions (such as pcim_iomap_region_range()) that do not yet
have a user (Bjorn)
- Don't export interfaces publicly anymore, except for
pcim_iomap_range(), needed by vboxvideo (Bjorn)
- Mention the actual (vboxvideo) bug in "PCI: Warn users..." commit
(Bjorn)
- Drop docstring warnings on PCI-internal functions (Bjorn)
- Rework docstring warnings
- Fix spelling in a few places. Rewrapp paragraphs (Bjorn)
Changes in v6:
- Restructure the cleanup in pcim_iomap_regions_request_all() so that
it doesn't trigger a (false positive) test robot warning. No
behavior change intended. (Dan Carpenter)
Changes in v5:
- Add Hans's Reviewed-by to vboxvideo patch (Hans de Goede)
- Remove stable-kernel from CC in vboxvideo patch (Hans de Goede)
Changes in v4:
- Rebase against linux-next
Changes in v3:
- Use the term "PCI devres API" at some forgotten places.
- Fix more grammar errors in patch #3.
- Remove the comment advising to call (the outdated) pcim_intx() in pci.c
- Rename __pcim_request_region_range() flags-field "exclusive" to
"req_flags", since this is what the int actually represents.
- Remove the call to pcim_region_request() from patch #10. (Hans)
Changes in v2:
- Make commit head lines congruent with PCI's style (Bjorn)
- Add missing error checks for devm_add_action(). (Andy)
- Repair the "Returns: " marks for docu generation (Andy)
- Initialize the addr_devres struct with memset(). (Andy)
- Make pcim_intx() a PCI-internal function so that new drivers won't
be encouraged to use the outdated pci_intx() mechanism.
(Andy / Philipp)
- Fix grammar and spelling (Bjorn)
- Be more precise on why pcim_iomap_table() is problematic (Bjorn)
- Provide the actual structs' and functions' names in the commit
messages (Bjorn)
- Remove redundant variable initializers (Andy)
- Regroup PM bitfield members in struct pci_dev (Andy)
- Make pcim_intx() visible only for the PCI subsystem so that new
drivers won't use this outdated API (Andy, Myself)
- Add a NOTE to pcim_iomap() to warn about this function being the onee
xception that does just return NULL.
- Consistently use the term "PCI devres API"; also in Patch #10 (Bjorn)
¡Hola!
PCI's devres API suffers several weaknesses:
1. There are functions prefixed with pcim_. Those are always managed
counterparts to never-managed functions prefixed with pci_ – or so one
would like to think. There are some apparently unmanaged functions
(all region-request / release functions, and pci_intx()) which
suddenly become managed once the user has initialized the device with
pcim_enable_device() instead of pci_enable_device(). This "sometimes
yes, sometimes no" nature of those functions is confusing and
therefore bug-provoking. In fact, it has already caused a bug in DRM.
The last patch in this series fixes that bug.
2. iomappings: Instead of giving each mapping its own callback, the
existing API uses a statically allocated struct tracking one mapping
per bar. This is not extensible. Especially, you can't create
_ranged_ managed mappings that way, which many drivers want.
3. Managed request functions only exist as "plural versions" with a
bit-mask as a parameter. That's quite over-engineered considering
that each user only ever mapps one, maybe two bars.
This series:
- add a set of new "singular" devres functions that use devres the way
its intended, with one callback per resource.
- deprecates the existing iomap-table mechanism.
- deprecates the hybrid nature of pci_ functions.
- preserves backwards compatibility so that drivers using the existing
API won't notice any changes.
- adds documentation, especially some warning users about the
complicated nature of PCI's devres.
Note that this series is based on my "unify pci_iounmap"-series from a
few weeks ago. [1]
I tested this on a x86 VM with a simple pci test-device with two
regions. Operates and reserves resources as intended on my system.
Kasan and kmemleak didn't find any problems.
I believe this series cleans the API up as much as possible without
having to port all existing drivers to the new API. Especially, I think
that this implementation is easy to extend if the need for new managed
functions arises :)
Greetings,
P.
Philipp Stanner (13):
PCI: Add and use devres helper for bit masks
PCI: Add devres helpers for iomap table
PCI: Reimplement plural devres functions
PCI: Deprecate two surplus devres functions
PCI: Make devres region requests consistent
PCI: Warn users about complicated devres nature
PCI: Move dev-enabled status bit to struct pci_dev
PCI: Move pinned status bit to struct pci_dev
PCI: Give pcim_set_mwi() its own devres callback
PCI: Give pci(m)_intx its own devres callback
PCI: Remove legacy pcim_release()
PCI: Add pcim_iomap_range()
drm/vboxvideo: fix mapping leaks
drivers/gpu/drm/vboxvideo/vbox_main.c | 20 +-
drivers/pci/devres.c | 897 +++++++++++++++++++++-----
drivers/pci/iomap.c | 16 +
drivers/pci/pci.c | 107 ++-
drivers/pci/pci.h | 23 +-
include/linux/pci.h | 6 +-
6 files changed, 864 insertions(+), 205 deletions(-)
--
2.45.0
The PCI region-request functions become managed functions when
pcim_enable_device() has been called previously instead of
pci_enable_device().
This has already caused a bug (in 8558de401b5f) by confusing users, who
came to believe that all pci functions, such as pci_iomap_range(),
suddenly are managed that way.
This is not the case.
Add comments to the relevant functions' docstrings that warn users about
this behavior.
Signed-off-by: Philipp Stanner <[email protected]>
---
drivers/pci/iomap.c | 16 ++++++++++++++++
drivers/pci/pci.c | 42 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/iomap.c b/drivers/pci/iomap.c
index c9725428e387..a715a4803c95 100644
--- a/drivers/pci/iomap.c
+++ b/drivers/pci/iomap.c
@@ -23,6 +23,10 @@
*
* @maxlen specifies the maximum length to map. If you want to get access to
* the complete BAR from offset to the end, pass %0 here.
+ *
+ * NOTE:
+ * This function is never managed, even if you initialized with
+ * pcim_enable_device().
* */
void __iomem *pci_iomap_range(struct pci_dev *dev,
int bar,
@@ -63,6 +67,10 @@ EXPORT_SYMBOL(pci_iomap_range);
*
* @maxlen specifies the maximum length to map. If you want to get access to
* the complete BAR from offset to the end, pass %0 here.
+ *
+ * NOTE:
+ * This function is never managed, even if you initialized with
+ * pcim_enable_device().
* */
void __iomem *pci_iomap_wc_range(struct pci_dev *dev,
int bar,
@@ -106,6 +114,10 @@ EXPORT_SYMBOL_GPL(pci_iomap_wc_range);
*
* @maxlen specifies the maximum length to map. If you want to get access to
* the complete BAR without checking for its length first, pass %0 here.
+ *
+ * NOTE:
+ * This function is never managed, even if you initialized with
+ * pcim_enable_device(). If you need automatic cleanup, use pcim_iomap().
* */
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
@@ -127,6 +139,10 @@ EXPORT_SYMBOL(pci_iomap);
*
* @maxlen specifies the maximum length to map. If you want to get access to
* the complete BAR without checking for its length first, pass %0 here.
+ *
+ * NOTE:
+ * This function is never managed, even if you initialized with
+ * pcim_enable_device().
* */
void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen)
{
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e4feb093f097..8dd711b9a291 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3897,6 +3897,8 @@ EXPORT_SYMBOL(pci_release_region);
* @res_name: Name to be associated with resource.
* @exclusive: whether the region access is exclusive or not
*
+ * Returns: 0 on success, negative error code on failure.
+ *
* Mark the PCI region associated with PCI device @pdev BAR @bar as
* being reserved by owner @res_name. Do not access any
* address inside the PCI regions unless this call returns
@@ -3947,6 +3949,8 @@ static int __pci_request_region(struct pci_dev *pdev, int bar,
* @bar: BAR to be reserved
* @res_name: Name to be associated with resource
*
+ * Returns: 0 on success, negative error code on failure.
+ *
* Mark the PCI region associated with PCI device @pdev BAR @bar as
* being reserved by owner @res_name. Do not access any
* address inside the PCI regions unless this call returns
@@ -3954,6 +3958,11 @@ static int __pci_request_region(struct pci_dev *pdev, int bar,
*
* Returns 0 on success, or %EBUSY on error. A warning
* message is also printed on failure.
+ *
+ * NOTE:
+ * This is a "hybrid" function: It's normally unmanaged, but becomes managed
+ * when pcim_enable_device() has been called in advance. This hybrid feature is
+ * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead.
*/
int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
{
@@ -4004,6 +4013,13 @@ static int __pci_request_selected_regions(struct pci_dev *pdev, int bars,
* @pdev: PCI device whose resources are to be reserved
* @bars: Bitmask of BARs to be requested
* @res_name: Name to be associated with resource
+ *
+ * Returns: 0 on success, negative error code on failure.
+ *
+ * NOTE:
+ * This is a "hybrid" function: It's normally unmanaged, but becomes managed
+ * when pcim_enable_device() has been called in advance. This hybrid feature is
+ * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead.
*/
int pci_request_selected_regions(struct pci_dev *pdev, int bars,
const char *res_name)
@@ -4012,6 +4028,19 @@ int pci_request_selected_regions(struct pci_dev *pdev, int bars,
}
EXPORT_SYMBOL(pci_request_selected_regions);
+/**
+ * pci_request_selected_regions_exclusive - Request regions exclusively
+ * @pdev: PCI device to request regions from
+ * @bars: bit mask of bars to request
+ * @res_name: name to be associated with the requests
+ *
+ * Returns: 0 on success, negative error code on failure.
+ *
+ * NOTE:
+ * This is a "hybrid" function: It's normally unmanaged, but becomes managed
+ * when pcim_enable_device() has been called in advance. This hybrid feature is
+ * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead.
+ */
int pci_request_selected_regions_exclusive(struct pci_dev *pdev, int bars,
const char *res_name)
{
@@ -4029,7 +4058,6 @@ EXPORT_SYMBOL(pci_request_selected_regions_exclusive);
* successful call to pci_request_regions(). Call this function only
* after all use of the PCI regions has ceased.
*/
-
void pci_release_regions(struct pci_dev *pdev)
{
pci_release_selected_regions(pdev, (1 << PCI_STD_NUM_BARS) - 1);
@@ -4061,6 +4089,8 @@ EXPORT_SYMBOL(pci_request_regions);
* @pdev: PCI device whose resources are to be reserved
* @res_name: Name to be associated with resource.
*
+ * Returns: 0 on success, negative error code on failure.
+ *
* Mark all PCI regions associated with PCI device @pdev as being reserved
* by owner @res_name. Do not access any address inside the PCI regions
* unless this call returns successfully.
@@ -4070,6 +4100,11 @@ EXPORT_SYMBOL(pci_request_regions);
*
* Returns 0 on success, or %EBUSY on error. A warning message is also
* printed on failure.
+ *
+ * NOTE:
+ * This is a "hybrid" function: It's normally unmanaged, but becomes managed
+ * when pcim_enable_device() has been called in advance. This hybrid feature is
+ * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead.
*/
int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name)
{
@@ -4401,6 +4436,11 @@ void pci_disable_parity(struct pci_dev *dev)
* @enable: boolean: whether to enable or disable PCI INTx
*
* Enables/disables PCI INTx for device @pdev
+ *
+ * NOTE:
+ * This is a "hybrid" function: It's normally unmanaged, but becomes managed
+ * when pcim_enable_device() has been called in advance. This hybrid feature is
+ * DEPRECATED!
*/
void pci_intx(struct pci_dev *pdev, int enable)
{
--
2.45.0
Thanks to preceding cleanup steps, pcim_release() is now not needed
anymore and can be replaced by pcim_disable_device(), which is the exact
counterpart to pcim_enable_device().
This permits removing further parts of the old PCI devres implementation.
Replace pcim_release() with pcim_disable_device().
Remove the now surplus function get_pci_dr().
Remove the struct pci_devres from pci.h.
Remove the now surplus function find_pci_dr().
Signed-off-by: Philipp Stanner <[email protected]>
---
drivers/pci/devres.c | 53 +++++++++++++++++++++-----------------------
drivers/pci/pci.h | 18 ---------------
2 files changed, 25 insertions(+), 46 deletions(-)
diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c
index 9a997de280df..271ffd1aaf47 100644
--- a/drivers/pci/devres.c
+++ b/drivers/pci/devres.c
@@ -460,48 +460,45 @@ int pcim_intx(struct pci_dev *pdev, int enable)
return 0;
}
-static void pcim_release(struct device *gendev, void *res)
+static void pcim_disable_device(void *pdev_raw)
{
- struct pci_dev *dev = to_pci_dev(gendev);
-
- if (!dev->pinned)
- pci_disable_device(dev);
-}
-
-static struct pci_devres *get_pci_dr(struct pci_dev *pdev)
-{
- struct pci_devres *dr, *new_dr;
-
- dr = devres_find(&pdev->dev, pcim_release, NULL, NULL);
- if (dr)
- return dr;
+ struct pci_dev *pdev = pdev_raw;
- new_dr = devres_alloc(pcim_release, sizeof(*new_dr), GFP_KERNEL);
- if (!new_dr)
- return NULL;
- return devres_get(&pdev->dev, new_dr, NULL, NULL);
+ if (!pdev->pinned)
+ pci_disable_device(pdev);
}
/**
* pcim_enable_device - Managed pci_enable_device()
* @pdev: PCI device to be initialized
*
- * Managed pci_enable_device().
+ * Returns: 0 on success, negative error code on failure.
+ *
+ * Managed pci_enable_device(). Device will automatically be disabled on
+ * driver detach.
*/
int pcim_enable_device(struct pci_dev *pdev)
{
- struct pci_devres *dr;
- int rc;
+ int ret;
- dr = get_pci_dr(pdev);
- if (unlikely(!dr))
- return -ENOMEM;
+ ret = devm_add_action(&pdev->dev, pcim_disable_device, pdev);
+ if (ret != 0)
+ return ret;
- rc = pci_enable_device(pdev);
- if (!rc)
- pdev->is_managed = 1;
+ /*
+ * We prefer removing the action in case of an error over
+ * devm_add_action_or_reset() because the later could theoretically be
+ * disturbed by users having pinned the device too soon.
+ */
+ ret = pci_enable_device(pdev);
+ if (ret != 0) {
+ devm_remove_action(&pdev->dev, pcim_disable_device, pdev);
+ return ret;
+ }
- return rc;
+ pdev->is_managed = true;
+
+ return ret;
}
EXPORT_SYMBOL(pcim_enable_device);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3aa57cd8b3e5..6a9c4dd77d68 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -812,24 +812,6 @@ static inline pci_power_t mid_pci_get_power_state(struct pci_dev *pdev)
}
#endif
-/*
- * Managed PCI resources. This manages device on/off, INTx/MSI/MSI-X
- * on/off and BAR regions. pci_dev itself records MSI/MSI-X status, so
- * there's no need to track it separately. pci_devres is initialized
- * when a device is enabled using managed PCI device enable interface.
- *
- * TODO: Struct pci_devres and find_pci_dr() only need to be here because
- * they're used in pci.c. Port or move these functions to devres.c and
- * then remove them from here.
- */
-struct pci_devres {
- /*
- * TODO:
- * This struct is now surplus. Remove it by refactoring pci/devres.c
- */
-};
-
-struct pci_devres *find_pci_dr(struct pci_dev *pdev);
int pcim_intx(struct pci_dev *dev, int enable);
int pcim_request_region(struct pci_dev *pdev, int bar, const char *name);
--
2.45.0
The only managed mapping function currently is pcim_iomap() which
doesn't allow for mapping an area starting at a certain offset, which
many drivers want.
Add pcim_iomap_range() as an exported function.
Signed-off-by: Philipp Stanner <[email protected]>
---
drivers/pci/devres.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 2 ++
2 files changed, 46 insertions(+)
diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c
index 271ffd1aaf47..5ddcfe001d08 100644
--- a/drivers/pci/devres.c
+++ b/drivers/pci/devres.c
@@ -1007,3 +1007,47 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
}
}
EXPORT_SYMBOL(pcim_iounmap_regions);
+
+/**
+ * pcim_iomap_range - Create a ranged __iomap mapping within a PCI BAR
+ * @pdev: PCI device to map IO resources for
+ * @bar: Index of the BAR
+ * @offset: Offset from the begin of the BAR
+ * @len: Length in bytes for the mapping
+ *
+ * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure.
+ *
+ * Creates a new IO-Mapping within the specified @bar, ranging from @offset to
+ * @offset + @len.
+ *
+ * The mapping will automatically get unmapped on driver detach. If desired,
+ * release manually only with pcim_iounmap().
+ */
+void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar,
+ unsigned long offset, unsigned long len)
+{
+ void __iomem *mapping;
+ struct pcim_addr_devres *res;
+
+ res = pcim_addr_devres_alloc(pdev);
+ if (!res)
+ return IOMEM_ERR_PTR(-ENOMEM);
+
+ mapping = pci_iomap_range(pdev, bar, offset, len);
+ if (!mapping) {
+ pcim_addr_devres_free(res);
+ return IOMEM_ERR_PTR(-EINVAL);
+ }
+
+ res->type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
+ res->baseaddr = mapping;
+
+ /*
+ * Ranged mappings don't get added to the legacy-table, since the table
+ * only ever keeps track of whole BARs.
+ */
+
+ devres_add(&pdev->dev, res);
+ return mapping;
+}
+EXPORT_SYMBOL(pcim_iomap_range);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 3104c0238a42..f6918e49ea5f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2329,6 +2329,8 @@ int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name);
int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
const char *name);
void pcim_iounmap_regions(struct pci_dev *pdev, int mask);
+void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar,
+ unsigned long offset, unsigned long len);
extern int pci_pci_problems;
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
--
2.45.0
On Wed, Jun 05, 2024 at 10:15:52AM +0200, Philipp Stanner wrote:
> Hello Bjorn,
>
> I tried to meet your requests from the last feedback round as much as
> possible. Especially, I removed a lot of code, made almost all
> interfaces private and cut the series into smaller chunks where
> possible.
>
> Splitting it even smaller is unfortunately not possible because of the
> Linux kernel build chain's rule on dead / unused code.
>
> See also the changelog below.
>
> Please tell me if that's enough to move forward here.
>
> Regards,
> P.
>
>
> Changes in v7:
> - Split the entire series in smaller, more atomic chunks / patches
> (Bjorn)
> - Remove functions (such as pcim_iomap_region_range()) that do not yet
> have a user (Bjorn)
> - Don't export interfaces publicly anymore, except for
> pcim_iomap_range(), needed by vboxvideo (Bjorn)
> - Mention the actual (vboxvideo) bug in "PCI: Warn users..." commit
> (Bjorn)
> - Drop docstring warnings on PCI-internal functions (Bjorn)
> - Rework docstring warnings
> - Fix spelling in a few places. Rewrapp paragraphs (Bjorn)
>
> Changes in v6:
> - Restructure the cleanup in pcim_iomap_regions_request_all() so that
> it doesn't trigger a (false positive) test robot warning. No
> behavior change intended. (Dan Carpenter)
>
> Changes in v5:
> - Add Hans's Reviewed-by to vboxvideo patch (Hans de Goede)
> - Remove stable-kernel from CC in vboxvideo patch (Hans de Goede)
>
> Changes in v4:
> - Rebase against linux-next
>
> Changes in v3:
> - Use the term "PCI devres API" at some forgotten places.
> - Fix more grammar errors in patch #3.
> - Remove the comment advising to call (the outdated) pcim_intx() in pci.c
> - Rename __pcim_request_region_range() flags-field "exclusive" to
> "req_flags", since this is what the int actually represents.
> - Remove the call to pcim_region_request() from patch #10. (Hans)
>
> Changes in v2:
> - Make commit head lines congruent with PCI's style (Bjorn)
> - Add missing error checks for devm_add_action(). (Andy)
> - Repair the "Returns: " marks for docu generation (Andy)
> - Initialize the addr_devres struct with memset(). (Andy)
> - Make pcim_intx() a PCI-internal function so that new drivers won't
> be encouraged to use the outdated pci_intx() mechanism.
> (Andy / Philipp)
> - Fix grammar and spelling (Bjorn)
> - Be more precise on why pcim_iomap_table() is problematic (Bjorn)
> - Provide the actual structs' and functions' names in the commit
> messages (Bjorn)
> - Remove redundant variable initializers (Andy)
> - Regroup PM bitfield members in struct pci_dev (Andy)
> - Make pcim_intx() visible only for the PCI subsystem so that new
> drivers won't use this outdated API (Andy, Myself)
> - Add a NOTE to pcim_iomap() to warn about this function being the onee
> xception that does just return NULL.
> - Consistently use the term "PCI devres API"; also in Patch #10 (Bjorn)
>
>
> ¡Hola!
>
> PCI's devres API suffers several weaknesses:
>
> 1. There are functions prefixed with pcim_. Those are always managed
> counterparts to never-managed functions prefixed with pci_ – or so one
> would like to think. There are some apparently unmanaged functions
> (all region-request / release functions, and pci_intx()) which
> suddenly become managed once the user has initialized the device with
> pcim_enable_device() instead of pci_enable_device(). This "sometimes
> yes, sometimes no" nature of those functions is confusing and
> therefore bug-provoking. In fact, it has already caused a bug in DRM.
> The last patch in this series fixes that bug.
> 2. iomappings: Instead of giving each mapping its own callback, the
> existing API uses a statically allocated struct tracking one mapping
> per bar. This is not extensible. Especially, you can't create
> _ranged_ managed mappings that way, which many drivers want.
> 3. Managed request functions only exist as "plural versions" with a
> bit-mask as a parameter. That's quite over-engineered considering
> that each user only ever mapps one, maybe two bars.
>
> This series:
> - add a set of new "singular" devres functions that use devres the way
> its intended, with one callback per resource.
> - deprecates the existing iomap-table mechanism.
> - deprecates the hybrid nature of pci_ functions.
> - preserves backwards compatibility so that drivers using the existing
> API won't notice any changes.
> - adds documentation, especially some warning users about the
> complicated nature of PCI's devres.
>
>
> Note that this series is based on my "unify pci_iounmap"-series from a
> few weeks ago. [1]
>
> I tested this on a x86 VM with a simple pci test-device with two
> regions. Operates and reserves resources as intended on my system.
> Kasan and kmemleak didn't find any problems.
>
> I believe this series cleans the API up as much as possible without
> having to port all existing drivers to the new API. Especially, I think
> that this implementation is easy to extend if the need for new managed
> functions arises :)
>
> Greetings,
> P.
>
> Philipp Stanner (13):
> PCI: Add and use devres helper for bit masks
> PCI: Add devres helpers for iomap table
> PCI: Reimplement plural devres functions
> PCI: Deprecate two surplus devres functions
> PCI: Make devres region requests consistent
> PCI: Warn users about complicated devres nature
Applied the above to pci/devres for v6.11 with minor comment and
whitespace tweaks. Will watch for updates for the ones below to
consolidate "enabled" and "enable_cnt".
> PCI: Move dev-enabled status bit to struct pci_dev
> PCI: Move pinned status bit to struct pci_dev
> PCI: Give pcim_set_mwi() its own devres callback
> PCI: Give pci(m)_intx its own devres callback
> PCI: Remove legacy pcim_release()
> PCI: Add pcim_iomap_range()
> drm/vboxvideo: fix mapping leaks
>
> drivers/gpu/drm/vboxvideo/vbox_main.c | 20 +-
> drivers/pci/devres.c | 897 +++++++++++++++++++++-----
> drivers/pci/iomap.c | 16 +
> drivers/pci/pci.c | 107 ++-
> drivers/pci/pci.h | 23 +-
> include/linux/pci.h | 6 +-
> 6 files changed, 864 insertions(+), 205 deletions(-)
>
> --
> 2.45.0
>