* Re: [PATCH v2 2/2] software node: Fix software_node_get_reference_args() with index -1
From: Zijun Hu @ 2026-06-26 23:50 UTC (permalink / raw)
To: Alban Bedel, driver-core, devicetree
Cc: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Rob Herring, Saravana Kannan, linux-kernel, Sashiko
In-Reply-To: <20260618152035.1600436-2-alban.bedel@lht.dlh.de>
On 6/18/2026 11:20 PM, Alban Bedel wrote:
> The bounds check for the index passed to
> software_node_get_reference_args() was failing when passed UINT_MAX,
> this in turn would lead to an out of bound access in the property
> array. Fix the bound check to also cover the UINT_MAX case.
>
> Fixes: 31e4e12e0e960 ("software node: Correct a OOB check in software_node_get_reference_args()")
i think the fix tag may not be right.
for original express before the fix tag: if (index * sizeof(*ref) > prop->length)
for UINT_MAX, multiplication overflow?
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Closes: https://lore.kernel.org/linux-devicetree/20260611103904.7CB131F00893@smtp.kernel.org/
> Signed-off-by: Alban Bedel <alban.bedel@lht.dlh.de>
> --
> v2: No changes. Only submit this patch along with the patch that
> triggered the Sashiko report, to hopefully avoid another useless
> report.
> ---
> drivers/base/swnode.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index 869228a65cb36..2bc76f01eb77d 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -537,7 +537,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> if (prop->is_inline)
> return -EINVAL;
>
> - if ((index + 1) * sizeof(*ref) > prop->length)
> + if (index >= prop->length / sizeof(*ref))
> return -ENOENT;
>
who will use UINT_MAX ?
This function is a interface function. the best fix should check
input parameter @index and return -EINVAL if it is not expected?
^ permalink raw reply
* Re: [PATCH 3/3] pci: fix UAF when probe runs concurrent to dyn ID removal
From: Gary Guo @ 2026-06-26 21:55 UTC (permalink / raw)
To: Gary Guo, Bjorn Helgaas, Zhenzhong Duan, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich
Cc: linux-pci, driver-core, linux-kernel, Sashiko
In-Reply-To: <20260626-pci_id_fix-v1-3-a35c803f1b95@garyguo.net>
On Fri Jun 26, 2026 at 8:49 PM BST, Gary Guo wrote:
> Dynamic IDs are only guaranteed to be valid when dynids.lock is held,
> as remove_id_store can free the node. Thus, make a copy in
> pci_match_device.
>
> Reported-by: Sashiko <sashiko-bot@kernel.org>
> Link: https://lore.kernel.org/all/20260619170503.518F61F00A3A@smtp.kernel.org/
> Fixes: 0994375e9614 ("PCI: add remove_id sysfs entry")
> Signed-off-by: Gary Guo <gary@garyguo.net>
Sashiko reports driver UAF issue with this:
https://sashiko.dev/#/patchset/20260626-pci_id_fix-v1-0-a35c803f1b95%40garyguo.net?part=3
All of these cases are already existing UAF issues, albeit now it is much easier
to trigger because this patch converts them to heap UAF for dynamic ID only to
stack UAF for all IDs.
One obvious fix is to instead keep a copy of the ID in pci_dev. However, in
practice I think it doesn't make much sense for drivers to keep pci_device_id
pointers at all; everything except driver_data can just be retrieved from
pci_dev.
So I think it's better to fix drivers that stores these IDs. I used this
coccinelle script to find cases:
---
@store@
identifier fn;
identifier id;
expression E;
parameter list[n] ps;
@@
fn(ps, const struct pci_device_id *id, ...)
{
...
* E = id
...
}
@store_cast@
identifier fn;
identifier id;
expression E;
type T;
parameter list[n] ps;
@@
fn(ps, const struct pci_device_id *id, ...)
{
...
* E = (T)id
...
}
@struct_const@
identifier s, fld;
@@
struct s {
...
* const struct pci_device_id *fld;
...
};
@struct_mut@
identifier s, fld;
@@
struct s {
...
* struct pci_device_id *fld;
...
};
---
And it looks like there're only 4 drivers that need fixing:
- mlxsw
- ipack/tpci200
- nsp32
- ata
Best,
Gary
^ permalink raw reply
* [PATCH 1/3] pci: make pci_match_one_device match on ID instead of device
From: Gary Guo @ 2026-06-26 19:49 UTC (permalink / raw)
To: Bjorn Helgaas, Zhenzhong Duan, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich
Cc: linux-pci, driver-core, linux-kernel, Gary Guo
In-Reply-To: <20260626-pci_id_fix-v1-0-a35c803f1b95@garyguo.net>
There is a need to match just IDs instead of against devices. Thus rename
this function to pci_match_one_id, and add a pci_id_from_device helper to
make it easy to convert users.
Similar convert pci_match_id to do_pci_match_id, however the existing API
is kept due to quite a few users.
Signed-off-by: Gary Guo <gary@garyguo.net>
---
drivers/pci/pci-driver.c | 38 ++++++++++++++++++++++++++++----------
drivers/pci/pci.h | 36 ++++++++++++++++++++++++++----------
drivers/pci/search.c | 6 ++++--
3 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f36778e62ac1..0507cb801310 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -90,6 +90,27 @@ static void pci_free_dynids(struct pci_driver *drv)
spin_unlock(&drv->dynids.lock);
}
+/**
+ * do_pci_match_id - See if a PCI ID matches a given pci_id table
+ * @ids: array of PCI device ID structures to search in
+ * @dev_id: the actual PCI device ID structure to match against.
+ *
+ * Returns the matching pci_device_id structure or
+ * %NULL if there is no match.
+ */
+static const struct pci_device_id *do_pci_match_id(const struct pci_device_id *ids,
+ const struct pci_device_id *dev_id)
+{
+ if (ids) {
+ while (ids->vendor || ids->subvendor || ids->class_mask) {
+ if (pci_match_one_id(ids, dev_id))
+ return ids;
+ ids++;
+ }
+ }
+ return NULL;
+}
+
/**
* pci_match_id - See if a PCI device matches a given pci_id table
* @ids: array of PCI device ID structures to search in
@@ -105,14 +126,9 @@ static void pci_free_dynids(struct pci_driver *drv)
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
struct pci_dev *dev)
{
- if (ids) {
- while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (pci_match_one_device(ids, dev))
- return ids;
- ids++;
- }
- }
- return NULL;
+ struct pci_device_id dev_id = pci_id_from_device(dev);
+
+ return do_pci_match_id(ids, &dev_id);
}
EXPORT_SYMBOL(pci_match_id);
@@ -138,6 +154,7 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
{
struct pci_dynid *dynid;
const struct pci_device_id *found_id = NULL, *ids;
+ struct pci_device_id dev_id;
int ret;
/* When driver_override is set, only bind to the matching driver */
@@ -145,10 +162,11 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
if (ret == 0)
return NULL;
+ dev_id = pci_id_from_device(dev);
/* Look at the dynamic ids first, before the static ones */
spin_lock(&drv->dynids.lock);
list_for_each_entry(dynid, &drv->dynids.list, node) {
- if (pci_match_one_device(&dynid->id, dev)) {
+ if (pci_match_one_id(&dynid->id, &dev_id)) {
found_id = &dynid->id;
break;
}
@@ -158,7 +176,7 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
if (found_id)
return found_id;
- for (ids = drv->id_table; (found_id = pci_match_id(ids, dev));
+ for (ids = drv->id_table; (found_id = do_pci_match_id(ids, &dev_id));
ids = found_id + 1) {
/*
* The match table is split based on driver_override.
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4469e1a77f3c..0567a8762baa 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -442,21 +442,37 @@ static inline int pci_setup_cardbus(char *str) { return -ENOENT; }
#endif /* CONFIG_CARDBUS */
/**
- * pci_match_one_device - Tell if a PCI device structure has a matching
- * PCI device id structure
- * @id: single PCI device id structure to match
- * @dev: the PCI device structure to match against
+ * pci_id_from_device - Obtain a pci_device_id from a PCI device
+ * @dev: the PCI device
+ *
+ * Returns a pci_device_id filled.
+ */
+static inline struct pci_device_id pci_id_from_device(const struct pci_dev *dev)
+{
+ return (struct pci_device_id) {
+ .vendor = dev->vendor,
+ .device = dev->device,
+ .subvendor = dev->subsystem_vendor,
+ .subdevice = dev->subsystem_device,
+ .class = dev->class,
+ };
+}
+
+/**
+ * pci_match_one_id - Tell if a PCI device ID matches a needle PCI device id
+ * @id: single PCI device id structure to match against (needle)
+ * @dev_id: the actual ID from the PCI device (can be created via pci_id_from_device)
*
* Returns the matching pci_device_id structure or %NULL if there is no match.
*/
static inline const struct pci_device_id *
-pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
+pci_match_one_id(const struct pci_device_id *id, const struct pci_device_id *dev_id)
{
- if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
- (id->device == PCI_ANY_ID || id->device == dev->device) &&
- (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
- (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
- !((id->class ^ dev->class) & id->class_mask))
+ if ((id->vendor == PCI_ANY_ID || id->vendor == dev_id->vendor) &&
+ (id->device == PCI_ANY_ID || id->device == dev_id->device) &&
+ (id->subvendor == PCI_ANY_ID || id->subvendor == dev_id->subvendor) &&
+ (id->subdevice == PCI_ANY_ID || id->subdevice == dev_id->subdevice) &&
+ !((id->class ^ dev_id->class) & id->class_mask))
return id;
return NULL;
}
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index e3d3177fce54..c8c4bfe7817b 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -245,8 +245,10 @@ static int match_pci_dev_by_id(struct device *dev, const void *data)
{
struct pci_dev *pdev = to_pci_dev(dev);
const struct pci_device_id *id = data;
+ struct pci_device_id dev_id;
- if (pci_match_one_device(id, pdev))
+ dev_id = pci_id_from_device(pdev);
+ if (pci_match_one_id(id, &dev_id))
return 1;
return 0;
}
@@ -418,7 +420,7 @@ EXPORT_SYMBOL(pci_get_class);
*
* Iterates through the list of known PCI devices. If a PCI device is found
* with a matching base class code, the reference count to the device is
- * incremented. See pci_match_one_device() to figure out how does this works.
+ * incremented. See pci_match_one_id() to figure out how does this works.
* A new search is initiated by passing %NULL as the @from argument.
* Otherwise if @from is not %NULL, searches continue from next device on the
* global list. The reference count for @from is always decremented if it is
--
2.54.0
^ permalink raw reply related
* [PATCH 0/3] pci: fix UAF and TOCTOU related to dynamic ID
From: Gary Guo @ 2026-06-26 19:49 UTC (permalink / raw)
To: Bjorn Helgaas, Zhenzhong Duan, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich
Cc: linux-pci, driver-core, linux-kernel, Gary Guo, Sashiko
While working on improving the Rust abstractions [1], Sashiko reported that
an existing UAF issue related to dynamic ID, which I find to be genuine.
When taking a look at the code I also find a TOCTOU issue where the
existence check of dynamic ID happens in a separate critical section as the
actual insertion. This series fix both issues.
There are two exported functions "pci_match_id" and "pci_add_dynid" which I
have to tweak to implement this cleanly; I created separate "do_xxx"
functions to keep the existing APIs because they all have multiple users.
Link: https://lore.kernel.org/all/20260618-id_info-v1-0-96af1e559ef9@garyguo.net/ [1]
Link: https://lore.kernel.org/all/20260619170503.518F61F00A3A@smtp.kernel.org/ [2]
Signed-off-by: Gary Guo <gary@garyguo.net>
---
Gary Guo (3):
pci: make pci_match_one_device match on ID instead of device
pci: fix dyn_id add TOCTOU
pci: fix UAF when probe runs concurrent to dyn ID removal
drivers/pci/pci-driver.c | 208 ++++++++++++++++++++++++++---------------------
drivers/pci/pci.h | 36 +++++---
drivers/pci/search.c | 6 +-
3 files changed, 147 insertions(+), 103 deletions(-)
---
base-commit: 6c94b38b83a04c43ea49004275f0391404051093
change-id: 20260626-pci_id_fix-83eaec007674
Best regards,
--
Gary Guo <gary@garyguo.net>
^ permalink raw reply
* [PATCH 3/3] pci: fix UAF when probe runs concurrent to dyn ID removal
From: Gary Guo @ 2026-06-26 19:49 UTC (permalink / raw)
To: Bjorn Helgaas, Zhenzhong Duan, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich
Cc: linux-pci, driver-core, linux-kernel, Gary Guo, Sashiko
In-Reply-To: <20260626-pci_id_fix-v1-0-a35c803f1b95@garyguo.net>
Dynamic IDs are only guaranteed to be valid when dynids.lock is held,
as remove_id_store can free the node. Thus, make a copy in
pci_match_device.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/all/20260619170503.518F61F00A3A@smtp.kernel.org/
Fixes: 0994375e9614 ("PCI: add remove_id sysfs entry")
Signed-off-by: Gary Guo <gary@garyguo.net>
---
drivers/pci/pci-driver.c | 60 ++++++++++++++++++++++--------------------------
1 file changed, 28 insertions(+), 32 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 464ee52346fa..2c76bba9a715 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -177,14 +177,16 @@ static const struct pci_device_id pci_device_id_any = {
* pci_match_device - See if a device matches a driver's list of IDs
* @drv: the PCI driver to match against
* @dev: the PCI device structure to match against
+ * @id: Matched pci_device_id
*
* Used by a driver to check whether a PCI device is in its list of
* supported devices or in the dynids list, which may have been augmented
- * via the sysfs "new_id" file. Returns the matching pci_device_id
- * structure or %NULL if there is no match.
+ * via the sysfs "new_id" file. Returns true if there is a match, the matched
+ * ID is stored in @id.
*/
-static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
- struct pci_dev *dev)
+static bool pci_match_device(struct pci_driver *drv,
+ struct pci_dev *dev,
+ struct pci_device_id *id)
{
struct pci_dynid *dynid;
const struct pci_device_id *found_id = NULL, *ids;
@@ -194,21 +196,19 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
/* When driver_override is set, only bind to the matching driver */
ret = device_match_driver_override(&dev->dev, &drv->driver);
if (ret == 0)
- return NULL;
+ return false;
dev_id = pci_id_from_device(dev);
/* Look at the dynamic ids first, before the static ones */
- spin_lock(&drv->dynids.lock);
- list_for_each_entry(dynid, &drv->dynids.list, node) {
- if (pci_match_one_id(&dynid->id, &dev_id)) {
- found_id = &dynid->id;
- break;
+ {
+ guard(spinlock)(&drv->dynids.lock);
+ list_for_each_entry(dynid, &drv->dynids.list, node) {
+ if (pci_match_one_id(&dynid->id, &dev_id)) {
+ *id = dynid->id;
+ return true;
+ }
}
}
- spin_unlock(&drv->dynids.lock);
-
- if (found_id)
- return found_id;
for (ids = drv->id_table; (found_id = do_pci_match_id(ids, &dev_id));
ids = found_id + 1) {
@@ -217,18 +217,19 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
* In case override_only was set, enforce driver_override
* matching.
*/
- if (found_id->override_only) {
- if (ret > 0)
- return found_id;
- } else {
- return found_id;
+ if (!found_id->override_only || ret > 0) {
+ *id = *found_id;
+ return true;
}
}
/* driver_override will always match, send a dummy id */
- if (ret > 0)
- return &pci_device_id_any;
- return NULL;
+ if (ret > 0) {
+ *id = pci_device_id_any;
+ return true;
+ }
+
+ return false;
}
/**
@@ -474,15 +475,14 @@ void pci_probe_flush_workqueue(void)
*/
static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
{
- const struct pci_device_id *id;
+ struct pci_device_id id;
int error = 0;
if (drv->probe) {
error = -ENODEV;
- id = pci_match_device(drv, pci_dev);
- if (id)
- error = pci_call_probe(drv, pci_dev, id);
+ if (pci_match_device(drv, pci_dev, &id))
+ error = pci_call_probe(drv, pci_dev, &id);
}
return error;
}
@@ -1567,17 +1567,13 @@ static int pci_bus_match(struct device *dev, const struct device_driver *drv)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_driver *pci_drv;
- const struct pci_device_id *found_id;
+ struct pci_device_id id;
if (pci_dev_binding_disallowed(pci_dev))
return 0;
pci_drv = (struct pci_driver *)to_pci_driver(drv);
- found_id = pci_match_device(pci_drv, pci_dev);
- if (found_id)
- return 1;
-
- return 0;
+ return pci_match_device(pci_drv, pci_dev, &id);
}
/**
--
2.54.0
^ permalink raw reply related
* [PATCH 2/3] pci: fix dyn_id add TOCTOU
From: Gary Guo @ 2026-06-26 19:49 UTC (permalink / raw)
To: Bjorn Helgaas, Zhenzhong Duan, Greg Kroah-Hartman,
Rafael J. Wysocki, Danilo Krummrich
Cc: linux-pci, driver-core, linux-kernel, Gary Guo
In-Reply-To: <20260626-pci_id_fix-v1-0-a35c803f1b95@garyguo.net>
Currently there is a TOCTOU issue in new_id_store as the dyn ID insertion
in pci_add_dynid and the pci_match_device are in separate critical
sections.
Fix this by moving the existing ID check to inside pci_add_dynid and only
check against the static ID table outside the critical section.
Fixes: 3853f9123c18 ("PCI: Avoid duplicate IDs in driver dynamic IDs list")
Signed-off-by: Gary Guo <gary@garyguo.net>
---
drivers/pci/pci-driver.c | 112 ++++++++++++++++++++++++++---------------------
1 file changed, 62 insertions(+), 50 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 0507cb801310..464ee52346fa 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -29,6 +29,48 @@ struct pci_dynid {
struct pci_device_id id;
};
+/**
+ * do_pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
+ * @drv: target pci driver
+ * @id: ID to be added
+ * @check_dup: whether to check if matching ID is already present
+ *
+ * Adds a new dynamic pci device ID to this driver and causes the
+ * driver to probe for all devices again. @drv must have been
+ * registered prior to calling this function.
+ *
+ * CONTEXT:
+ * Does GFP_KERNEL allocation.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int do_pci_add_dynid(struct pci_driver *drv, const struct pci_device_id *id, bool check_dup)
+{
+ struct pci_dynid *dynid, *existing_dynid;
+
+ dynid = kzalloc_obj(*dynid);
+ if (!dynid)
+ return -ENOMEM;
+
+ dynid->id = *id;
+
+ {
+ guard(spinlock)(&drv->dynids.lock);
+ if (check_dup) {
+ list_for_each_entry(existing_dynid, &drv->dynids.list, node) {
+ if (pci_match_one_id(&existing_dynid->id, id)) {
+ kfree(dynid);
+ return -EEXIST;
+ }
+ }
+ }
+ list_add_tail(&dynid->node, &drv->dynids.list);
+ }
+
+ return driver_attach(&drv->driver);
+}
+
/**
* pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
* @drv: target pci driver
@@ -56,25 +98,17 @@ int pci_add_dynid(struct pci_driver *drv,
unsigned int class, unsigned int class_mask,
unsigned long driver_data)
{
- struct pci_dynid *dynid;
-
- dynid = kzalloc_obj(*dynid);
- if (!dynid)
- return -ENOMEM;
-
- dynid->id.vendor = vendor;
- dynid->id.device = device;
- dynid->id.subvendor = subvendor;
- dynid->id.subdevice = subdevice;
- dynid->id.class = class;
- dynid->id.class_mask = class_mask;
- dynid->id.driver_data = driver_data;
-
- spin_lock(&drv->dynids.lock);
- list_add_tail(&dynid->node, &drv->dynids.list);
- spin_unlock(&drv->dynids.lock);
+ struct pci_device_id id = {
+ .vendor = vendor,
+ .device = device,
+ .subvendor = subvendor,
+ .subdevice = subdevice,
+ .class = class,
+ .class_mask = class_mask,
+ .driver_data = driver_data,
+ };
- return driver_attach(&drv->driver);
+ return do_pci_add_dynid(drv, &id, false);
}
EXPORT_SYMBOL_GPL(pci_add_dynid);
@@ -197,11 +231,6 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
return NULL;
}
-static void _pci_free_device(struct device *dev)
-{
- kfree(to_pci_dev(dev));
-}
-
/**
* new_id_store - sysfs frontend to pci_add_dynid()
* @driver: target device driver
@@ -215,38 +244,22 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
{
struct pci_driver *pdrv = to_pci_driver(driver);
const struct pci_device_id *ids = pdrv->id_table;
- u32 vendor, device, subvendor = PCI_ANY_ID,
- subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
- unsigned long driver_data = 0;
+ struct pci_device_id id = {
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID
+ };
int fields;
int retval = 0;
fields = sscanf(buf, "%x %x %x %x %x %x %lx",
- &vendor, &device, &subvendor, &subdevice,
- &class, &class_mask, &driver_data);
+ &id.vendor, &id.device, &id.subvendor, &id.subdevice,
+ &id.class, &id.class_mask, &id.driver_data);
if (fields < 2)
return -EINVAL;
if (fields != 7) {
- struct pci_dev *pdev = kzalloc_obj(*pdev);
- if (!pdev)
- return -ENOMEM;
-
- pdev->vendor = vendor;
- pdev->device = device;
- pdev->subsystem_vendor = subvendor;
- pdev->subsystem_device = subdevice;
- pdev->class = class;
- pdev->dev.release = _pci_free_device;
-
- device_initialize(&pdev->dev);
- if (pci_match_device(pdrv, pdev))
- retval = -EEXIST;
-
- put_device(&pdev->dev);
-
- if (retval)
- return retval;
+ if (do_pci_match_id(pdrv->id_table, &id))
+ return -EEXIST;
}
/* Only accept driver_data values that match an existing id_table
@@ -254,7 +267,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
if (ids) {
retval = -EINVAL;
while (ids->vendor || ids->subvendor || ids->class_mask) {
- if (driver_data == ids->driver_data) {
+ if (id.driver_data == ids->driver_data) {
retval = 0;
break;
}
@@ -264,8 +277,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
return retval;
}
- retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,
- class, class_mask, driver_data);
+ retval = do_pci_add_dynid(pdrv, &id, fields != 7);
if (retval)
return retval;
return count;
--
2.54.0
^ permalink raw reply related
* [PATCH v4 7/7] rust: io: mem: return DevresLt from IoMem/ExclusiveIoMem::into_devres()
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Implement ForLt and CovariantForLt for IoMem<'static, SIZE> and
ExclusiveIoMem<'static, SIZE> so that DevresLt can shorten the stored
'static lifetime back to the caller's borrow lifetime.
CovariantForLt is sound because both types only hold &'a Device<Bound>,
which is covariant over 'a.
Since DevresLt::new() handles the lifetime transmutation internally,
into_devres() no longer needs an explicit transmute to 'static.
Add DevresIoMem<SIZE> and DevresExclusiveIoMem<SIZE> type aliases.
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
drivers/pwm/pwm_th1520.rs | 5 ++-
rust/kernel/io/mem.rs | 65 +++++++++++++++++++++++++++------------
2 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs
index 3e3fa51ccef9..7102c60fd14b 100644
--- a/drivers/pwm/pwm_th1520.rs
+++ b/drivers/pwm/pwm_th1520.rs
@@ -24,9 +24,8 @@
use kernel::{
clk::Clk,
device::{Bound, Core, Device},
- devres,
io::{
- mem::IoMem,
+ mem::DevresIoMem,
Io, //
},
of, platform,
@@ -86,7 +85,7 @@ struct Th1520WfHw {
#[pin_data(PinnedDrop)]
struct Th1520PwmDriverData {
#[pin]
- iomem: devres::Devres<IoMem<'static, TH1520_PWM_REG_SIZE>>,
+ iomem: DevresIoMem<TH1520_PWM_REG_SIZE>,
clk: Clk,
}
diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs
index fc2a3e24f8d5..4691a01a3cf7 100644
--- a/rust/kernel/io/mem.rs
+++ b/rust/kernel/io/mem.rs
@@ -9,7 +9,7 @@
Bound,
Device, //
},
- devres::Devres,
+ devres::DevresLt,
io::{
self,
resource::{
@@ -20,6 +20,10 @@
MmioRaw, //
},
prelude::*,
+ types::{
+ CovariantForLt,
+ ForLt, //
+ },
};
/// An IO request for a specific device and resource.
@@ -172,6 +176,19 @@ pub struct ExclusiveIoMem<'a, const SIZE: usize> {
_region: Region,
}
+impl<const SIZE: usize> ForLt for ExclusiveIoMem<'static, SIZE> {
+ type Of<'a> = ExclusiveIoMem<'a, SIZE>;
+}
+
+// SAFETY: `ExclusiveIoMem<'a, SIZE>` is covariant over `'a`; it holds an `IoMem<'a, SIZE>`,
+// which holds `&'a Device<Bound>`, which is covariant.
+unsafe impl<const SIZE: usize> CovariantForLt for ExclusiveIoMem<'static, SIZE> {}
+
+/// A device-managed exclusive I/O memory region.
+///
+/// See [`ExclusiveIoMem::into_devres`].
+pub type DevresExclusiveIoMem<const SIZE: usize> = DevresLt<ExclusiveIoMem<'static, SIZE>>;
+
impl<'a, const SIZE: usize> ExclusiveIoMem<'a, SIZE> {
/// Creates a new `ExclusiveIoMem` instance.
fn ioremap(dev: &'a Device<Bound>, resource: &Resource) -> Result<Self> {
@@ -198,15 +215,13 @@ fn ioremap(dev: &'a Device<Bound>, resource: &Resource) -> Result<Self> {
/// Consume the `ExclusiveIoMem` and register it as a device-managed resource.
///
- /// The returned `Devres<ExclusiveIoMem<'static, SIZE>>` can outlive the original lifetime
- /// `'a`. Access to the I/O memory is revoked when the device is unbound.
- pub fn into_devres(self) -> Result<Devres<ExclusiveIoMem<'static, SIZE>>> {
- // SAFETY: Casting to `'static` is sound because `Devres` guarantees the
- // `ExclusiveIoMem` does not actually outlive the device -- access is revoked and the
- // resource is released when the device is unbound.
- let iomem: ExclusiveIoMem<'static, SIZE> = unsafe { core::mem::transmute(self) };
- let dev = iomem.iomem.dev;
- Devres::new(dev, iomem)
+ /// The returned [`DevresExclusiveIoMem`] can outlive the original borrow and be stored in
+ /// driver data. Access to the I/O memory is revoked automatically when the device is unbound.
+ pub fn into_devres(self) -> Result<DevresExclusiveIoMem<SIZE>> {
+ let dev = self.iomem.dev;
+ // SAFETY: `ExclusiveIoMem` only holds a device reference and an I/O mapping, both of
+ // which remain valid for the device's full bound scope, not just for `'a`.
+ unsafe { DevresLt::new(dev, self) }
}
}
@@ -232,6 +247,19 @@ pub struct IoMem<'a, const SIZE: usize = 0> {
io: MmioRaw<SIZE>,
}
+impl<const SIZE: usize> ForLt for IoMem<'static, SIZE> {
+ type Of<'a> = IoMem<'a, SIZE>;
+}
+
+// SAFETY: `IoMem<'a, SIZE>` is covariant over `'a`; it holds `&'a Device<Bound>`,
+// which is covariant.
+unsafe impl<const SIZE: usize> CovariantForLt for IoMem<'static, SIZE> {}
+
+/// A device-managed I/O memory region.
+///
+/// See [`IoMem::into_devres`].
+pub type DevresIoMem<const SIZE: usize> = DevresLt<IoMem<'static, SIZE>>;
+
impl<'a, const SIZE: usize> IoMem<'a, SIZE> {
fn ioremap(dev: &'a Device<Bound>, resource: &Resource) -> Result<Self> {
// Note: Some ioremap() implementations use types that depend on the CPU
@@ -271,16 +299,13 @@ fn ioremap(dev: &'a Device<Bound>, resource: &Resource) -> Result<Self> {
/// Consume the `IoMem` and register it as a device-managed resource.
///
- /// The returned `Devres<IoMem<'static, SIZE>>` can outlive the original
- /// lifetime `'a`. Access to the I/O memory is revoked when the device
- /// is unbound.
- pub fn into_devres(self) -> Result<Devres<IoMem<'static, SIZE>>> {
- // SAFETY: Casting to `'static` is sound because `Devres` guarantees the `IoMem` does not
- // actually outlive the device -- access is revoked and the resource is released when the
- // device is unbound.
- let iomem: IoMem<'static, SIZE> = unsafe { core::mem::transmute(self) };
- let dev = iomem.dev;
- Devres::new(dev, iomem)
+ /// The returned [`DevresIoMem`] can outlive the original borrow and be stored in driver data.
+ /// Access to the I/O memory is revoked automatically when the device is unbound.
+ pub fn into_devres(self) -> Result<DevresIoMem<SIZE>> {
+ let dev = self.dev;
+ // SAFETY: `IoMem` only holds a device reference and an I/O mapping, both of which
+ // remain valid for the device's full bound scope, not just for `'a`.
+ unsafe { DevresLt::new(dev, self) }
}
}
--
2.54.0
^ permalink raw reply related
* [PATCH v4 6/7] rust: pci: return DevresLt from Bar::into_devres()
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Implement ForLt and CovariantForLt for Bar<'static, SIZE> so that
DevresLt can shorten the stored 'static lifetime back to the caller's
borrow lifetime.
CovariantForLt is sound because Bar<'a, SIZE> only holds &'a
Device<Bound>, which is covariant over 'a.
Since DevresLt::new() handles the lifetime transmutation internally,
into_devres() no longer needs an explicit transmute to Bar<'static>.
Add a DevresBar<SIZE> type alias for convenience.
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/pci.rs | 1 +
rust/kernel/pci/io.rs | 37 ++++++++++++++++++++++++++-----------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 5071cae6543f..f783b9d9fa26 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -45,6 +45,7 @@
ConfigSpace,
ConfigSpaceKind,
ConfigSpaceSize,
+ DevresBar,
Extended,
Normal, //
};
diff --git a/rust/kernel/pci/io.rs b/rust/kernel/pci/io.rs
index 0461e01aaa20..7a0d2d74129d 100644
--- a/rust/kernel/pci/io.rs
+++ b/rust/kernel/pci/io.rs
@@ -6,7 +6,7 @@
use crate::{
bindings,
device,
- devres::Devres,
+ devres::DevresLt,
io::{
Io,
IoCapable,
@@ -14,7 +14,11 @@
Mmio,
MmioRaw, //
},
- prelude::*, //
+ prelude::*,
+ types::{
+ CovariantForLt,
+ ForLt, //
+ }, //
};
use core::{
marker::PhantomData,
@@ -151,6 +155,19 @@ pub struct Bar<'a, const SIZE: usize = 0> {
num: i32,
}
+impl<const SIZE: usize> ForLt for Bar<'static, SIZE> {
+ type Of<'a> = Bar<'a, SIZE>;
+}
+
+// SAFETY: `Bar<'a, SIZE>` is covariant over `'a`; it holds `&'a Device<Bound>`,
+// which is covariant.
+unsafe impl<const SIZE: usize> CovariantForLt for Bar<'static, SIZE> {}
+
+/// A device-managed PCI BAR mapping.
+///
+/// See [`Bar::into_devres`].
+pub type DevresBar<const SIZE: usize> = DevresLt<Bar<'static, SIZE>>;
+
impl<'a, const SIZE: usize> Bar<'a, SIZE> {
pub(super) fn new(
pdev: &'a Device<device::Bound>,
@@ -223,15 +240,13 @@ fn release(&self) {
/// Consume the `Bar` and register it as a device-managed resource.
///
- /// The returned `Devres<Bar<'static, SIZE>>` can outlive the original lifetime `'a`. Access
- /// to the BAR is revoked when the device is unbound.
- pub fn into_devres(self) -> Result<Devres<Bar<'static, SIZE>>> {
- // SAFETY: Casting to `'static` is sound because `Devres` guarantees the `Bar` does not
- // actually outlive the device -- access is revoked and the resource is released when the
- // device is unbound.
- let bar: Bar<'static, SIZE> = unsafe { core::mem::transmute(self) };
- let pdev = bar.pdev;
- Devres::new(pdev.as_ref(), bar)
+ /// The returned [`DevresBar`] can outlive the original borrow and be stored in driver data.
+ /// Access to the BAR is revoked automatically when the device is unbound.
+ pub fn into_devres(self) -> Result<DevresBar<SIZE>> {
+ let pdev = self.pdev;
+ // SAFETY: `Bar` only holds a reference to the device and an I/O mapping, both of which
+ // remain valid for the device's full bound scope, not just for `'a`.
+ unsafe { DevresLt::new(pdev.as_ref(), self) }
}
}
--
2.54.0
^ permalink raw reply related
* [PATCH v4 5/7] rust: devres: add DevresLt for ForLt-aware device resource access
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Devres<T> stores resources as T and returns &'a T from access(). For
lifetime-parameterized types like Bar<'a, SIZE> that are transmuted to
'static for storage, this exposes the synthetic 'static lifetime to
callers -- any method on the stored type that returns a reference with
its lifetime parameter would yield a &'static reference, which is
unsound.
Add DevresLt<F: ForLt>, a thin wrapper around Devres<F::Of<'static>>
that shortens the stored 'static lifetime to the caller's borrow
lifetime in all access methods.
DevresLt::new() is unsafe because the caller must guarantee that the
data remains valid for the device's full bound scope; the internal
transmute from F::Of<'a> to F::Of<'static> would otherwise allow
use-after-free.
Two access patterns are provided:
- CovariantForLt types get direct-reference accessors (access,
try_access) that return shortened references via
CovariantForLt::cast_ref.
- Plain ForLt types use closure-based accessors (access_with,
try_access_with) whose universally quantified lifetime prevents
callers from smuggling in concrete short-lived references.
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/devres.rs | 106 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
index 11ce500e9b76..b7c075a39ba4 100644
--- a/rust/kernel/devres.rs
+++ b/rust/kernel/devres.rs
@@ -24,6 +24,8 @@
Arc, //
},
types::{
+ CovariantForLt,
+ ForLt,
ForeignOwnable,
Opaque, //
},
@@ -365,6 +367,110 @@ fn drop(&mut self) {
}
}
+/// Guard returned by [`DevresLt::try_access`].
+///
+/// Dereferences to `F::Of<'a>`, shortening the lifetime of the stored data to the guard's borrow
+/// lifetime.
+pub struct DevresGuard<'a, F: CovariantForLt>(RevocableGuard<'a, F::Of<'static>>);
+
+impl<'a, F: CovariantForLt> core::ops::Deref for DevresGuard<'a, F> {
+ type Target = F::Of<'a>;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ F::cast_ref(&*self.0)
+ }
+}
+
+/// Device-managed resource with [`ForLt`](trait@ForLt)-aware access.
+///
+/// `DevresLt` wraps [`Devres`] and shortens the stored `'static` lifetime to the caller's borrow
+/// lifetime in all access methods.
+///
+/// Types that implement [`trait@CovariantForLt`] get direct-reference accessors ([`Self::access`],
+/// [`Self::try_access`]). Plain [`ForLt`](trait@ForLt) types use closure-based accessors
+/// ([`Self::access_with`], [`Self::try_access_with`]).
+pub struct DevresLt<F: ForLt>(Devres<F::Of<'static>>)
+where
+ for<'a> F::Of<'a>: Send;
+
+impl<F: ForLt> DevresLt<F>
+where
+ for<'a> F::Of<'a>: Send,
+{
+ /// Creates a new [`DevresLt`] instance of the given `data`.
+ ///
+ /// # Safety
+ ///
+ /// The data must remain valid for the device's full bound scope. [`DevresLt`] allows
+ /// access until the device is unbound, which may outlast `'a`.
+ pub unsafe fn new<'a, E>(
+ dev: &'a Device<Bound>,
+ data: impl PinInit<F::Of<'a>, E>,
+ ) -> Result<Self>
+ where
+ Error: From<E>,
+ {
+ // SAFETY: The caller guarantees the data is valid for the device's full bound scope.
+ // Lifetimes do not affect layout, so F::Of<'a> and F::Of<'static> have identical
+ // representation; casting the slot pointer is sound.
+ let data = unsafe {
+ pin_init::pin_init_from_closure::<F::Of<'static>, E>(move |slot| {
+ data.__pinned_init(slot.cast())
+ })
+ };
+
+ Ok(Self(Devres::new(dev, data)?))
+ }
+
+ /// Return a reference of the [`Device`] this [`DevresLt`] instance has been created with.
+ #[inline]
+ pub fn device(&self) -> &Device {
+ self.0.device()
+ }
+
+ /// Obtain `&F::Of<'_>`, bypassing the [`Revocable`], through a closure.
+ ///
+ /// This method works like [`DevresLt::access`](DevresLt::access) but accepts any
+ /// [`trait@ForLt`] type, not just [`trait@CovariantForLt`].
+ #[inline]
+ pub fn access_with<R, G>(&self, dev: &Device<Bound>, f: G) -> Result<R>
+ where
+ G: for<'a> FnOnce(&F::Of<'a>) -> R,
+ {
+ self.0.access(dev).map(f)
+ }
+
+ /// [`DevresLt`] accessor for [`Revocable::try_access_with`].
+ #[inline]
+ pub fn try_access_with<R, G>(&self, f: G) -> Option<R>
+ where
+ G: for<'a> FnOnce(&F::Of<'a>) -> R,
+ {
+ self.0.data().try_access_with(f)
+ }
+}
+
+impl<F: CovariantForLt> DevresLt<F>
+where
+ for<'a> F::Of<'a>: Send,
+{
+ /// Obtain `&'a F::Of<'a>`, bypassing the [`Revocable`].
+ ///
+ /// This method works like [`Devres::access`], but shortens the returned reference's lifetime
+ /// from `'static` to `'a` via [`CovariantForLt::cast_ref`].
+ #[inline]
+ pub fn access<'a>(&'a self, dev: &'a Device<Bound>) -> Result<&'a F::Of<'a>> {
+ self.0.access(dev).map(F::cast_ref)
+ }
+
+ /// [`DevresLt`] accessor for [`Revocable::try_access`].
+ #[inline]
+ pub fn try_access(&self) -> Option<DevresGuard<'_, F>> {
+ self.0.data().try_access().map(DevresGuard)
+ }
+}
+
/// Consume `data` and [`Drop::drop`] `data` once `dev` is unbound.
fn register_foreign<P>(dev: &Device<Bound>, data: P) -> Result
where
--
2.54.0
^ permalink raw reply related
* [PATCH v4 4/7] rust: auxiliary: sample: demonstrate ForLt with invariant Mutex type
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Extend the auxiliary driver sample to demonstrate both access patterns:
- registration_data() with CovariantForLt!(Data<'_>) for the covariant
data type that holds a plain &'bound reference.
- registration_data_with() with ForLt!(MutexData<'_>) for an invariant
data type that wraps a Mutex<&'bound Device>. Since Mutex<T> is
invariant over T, MutexData cannot implement CovariantForLt and must
use the closure-based accessor.
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
samples/rust/rust_driver_auxiliary.rs | 94 +++++++++++++++++++--------
1 file changed, 68 insertions(+), 26 deletions(-)
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index 92ee6a6d348e..e441ae81fa2c 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -11,14 +11,21 @@
Core, //
},
driver,
+ new_mutex,
pci,
prelude::*,
- types::CovariantForLt,
+ sync::Mutex,
+ types::{
+ CovariantForLt,
+ ForLt, //
+ },
InPlaceModule, //
};
const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
const AUXILIARY_NAME: &CStr = c"auxiliary";
+const COVARIANT_DEV_ID: u32 = 0;
+const INVARIANT_DEV_ID: u32 = 1;
struct AuxiliaryDriver;
@@ -56,12 +63,26 @@ struct Data<'bound> {
parent: &'bound pci::Device<Bound>,
}
+/// Registration data with interior mutability.
+///
+/// `Mutex<&'bound T>` is invariant over `'bound`, so this type cannot implement
+/// [`CovariantForLt`](trait@CovariantForLt). Access must go through the closure-based
+/// [`auxiliary::Device::registration_data_with()`].
+#[pin_data]
+struct MutexData<'bound> {
+ #[pin]
+ parent: Mutex<&'bound pci::Device<Bound>>,
+ index: u32,
+}
+
struct ParentDriver;
#[allow(clippy::type_complexity)]
+#[pin_data]
struct ParentData<'bound> {
_reg0: auxiliary::Registration<'bound, CovariantForLt!(Data<'_>)>,
- _reg1: auxiliary::Registration<'bound, CovariantForLt!(Data<'_>)>,
+ #[pin]
+ _reg1: auxiliary::Registration<'bound, ForLt!(MutexData<'_>)>,
}
kernel::pci_device_table!(
@@ -81,17 +102,17 @@ fn probe<'bound>(
pdev: &'bound pci::Device<Core<'_>>,
_info: &'bound Self::IdInfo,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
- Ok(ParentData {
+ try_pin_init!(ParentData {
// SAFETY: `ParentData` is the driver's private data, which is dropped when the
// device is unbound; i.e. `mem::forget()` is never called on it.
_reg0: unsafe {
auxiliary::Registration::new_with_lt(
pdev.as_ref(),
AUXILIARY_NAME,
- 0,
+ COVARIANT_DEV_ID,
MODULE_NAME,
Data {
- index: 0,
+ index: COVARIANT_DEV_ID,
parent: pdev,
},
)?
@@ -101,12 +122,16 @@ fn probe<'bound>(
auxiliary::Registration::new_with_lt(
pdev.as_ref(),
AUXILIARY_NAME,
- 1,
+ INVARIANT_DEV_ID,
MODULE_NAME,
- Data {
- index: 1,
- parent: pdev,
- },
+ pin_init!(MutexData {
+ parent <- {
+ let pdev: &pci::Device<Bound> = pdev;
+
+ new_mutex!(pdev)
+ },
+ index: INVARIANT_DEV_ID,
+ }),
)?
},
})
@@ -115,22 +140,39 @@ fn probe<'bound>(
impl ParentDriver {
fn connect(adev: &auxiliary::Device<Bound>) -> Result {
- let data = adev.registration_data::<CovariantForLt!(Data<'_>)>()?;
- let pdev = data.parent;
-
- dev_info!(
- pdev,
- "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n",
- adev.id(),
- pdev.vendor_id(),
- pdev.device_id()
- );
-
- dev_info!(
- pdev,
- "Connected to auxiliary device with index {}.\n",
- data.index
- );
+ match adev.id() {
+ // CovariantForLt types can use the direct-reference accessor.
+ COVARIANT_DEV_ID => {
+ let data = adev.registration_data::<CovariantForLt!(Data<'_>)>()?;
+ let pdev = data.parent;
+
+ dev_info!(
+ pdev,
+ "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n",
+ adev.id(),
+ pdev.vendor_id(),
+ pdev.device_id()
+ );
+
+ dev_info!(
+ pdev,
+ "Connected to auxiliary device with index {}.\n",
+ data.index
+ );
+ }
+ // Invariant ForLt types (e.g. containing a Mutex) require the closure-based accessor.
+ INVARIANT_DEV_ID => {
+ adev.registration_data_with::<ForLt!(MutexData<'_>), _>(|data| {
+ let pdev = *data.parent.lock();
+ dev_info!(
+ pdev,
+ "Connected to auxiliary device with index {} (via Mutex).\n",
+ data.index
+ );
+ })?;
+ }
+ _ => return Err(EINVAL),
+ }
Ok(())
}
--
2.54.0
^ permalink raw reply related
* [PATCH v4 3/7] rust: auxiliary: add registration_data_with() for ForLt types
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Add registration_data_with() taking a for<'a> closure that receives
Pin<&'a F::Of<'a>>, which works with any ForLt type. Taking a for<'a>
closure rather than returning a direct reference prevents callers from
choosing a concrete lifetime for the data, which is required for
soundness with non-covariant ForLt types.
Extract the common null-check, TypeId-check and KBox-borrow logic into a
private registration_data_pinned() helper shared by both
registration_data_with() and the existing registration_data().
Relax Registration's bound from CovariantForLt to ForLt so that
non-covariant types can be registered.
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/auxiliary.rs | 93 +++++++++++++++++++++++++++++-----------
1 file changed, 67 insertions(+), 26 deletions(-)
diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs
index 40a0af74a8e5..19a488700bb9 100644
--- a/rust/kernel/auxiliary.rs
+++ b/rust/kernel/auxiliary.rs
@@ -21,6 +21,7 @@
prelude::*,
types::{
CovariantForLt,
+ ForLt,
ForeignOwnable,
Opaque, //
},
@@ -270,18 +271,15 @@ pub fn parent(&self) -> &device::Device<device::Bound> {
unsafe { parent.as_bound() }
}
- /// Returns a pinned reference to the registration data set by the registering (parent) driver.
+ /// Returns the stored registration data as a pinned reference.
///
- /// `F` is the [`CovariantForLt`](trait@CovariantForLt) encoding of the data type. The returned
- /// reference has its lifetime shortened from `'static` to `&self`'s borrow lifetime via
- /// [`CovariantForLt::cast_ref`].
+ /// Performs null and [`TypeId`] checks, then borrows the stored [`KBox`].
///
- /// Returns [`EINVAL`] if `F` does not match the type used by the parent driver when calling
- /// [`Registration::new()`].
+ /// # Safety
///
- /// Returns [`ENOENT`] if no registration data has been set, e.g. when the device was
- /// registered by a C driver.
- pub fn registration_data<F: CovariantForLt + 'static>(&self) -> Result<Pin<&F::Of<'_>>> {
+ /// Callers must ensure that the lifetime shortening from the original `'static` storage to
+ /// `'_` is sound, e.g. via an HRTB closure or [`CovariantForLt`] guarantee.
+ unsafe fn registration_data_pinned<F: ForLt + 'static>(&self) -> Result<Pin<&F::Of<'_>>> {
// SAFETY: By the type invariant, `self.as_raw()` is a valid `struct auxiliary_device`.
let ptr = unsafe { (*self.as_raw()).registration_data_rust };
if ptr.is_null() {
@@ -300,17 +298,59 @@ pub fn registration_data<F: CovariantForLt + 'static>(&self) -> Result<Pin<&F::O
return Err(EINVAL);
}
- // SAFETY: The `TypeId` check above confirms that the stored type matches
- // `F::Of<'static>`; `ptr` remains valid until `Registration::drop()` calls
- // `from_foreign()`.
- let wrapper = unsafe { Pin::<KBox<RegistrationData<F::Of<'static>>>>::borrow(ptr) };
+ // SAFETY: The `TypeId` check above confirms that the stored type matches `F`'s
+ // encoding; lifetimes are erased at runtime, so borrowing as `F::Of<'_>` is
+ // layout-compatible with the stored `F::Of<'static>`. `ptr` remains valid until
+ // `Registration::drop()` calls `from_foreign()`.
+ let wrapper = unsafe { Pin::<KBox<RegistrationData<F::Of<'_>>>>::borrow(ptr) };
// SAFETY: `data` is a structurally pinned field of `RegistrationData`.
- let pinned: Pin<&F::Of<'_>> = unsafe { wrapper.map_unchecked(|w| &w.data) };
+ Ok(unsafe { wrapper.map_unchecked(|w| &w.data) })
+ }
- // SAFETY: The data was pinned when stored; `cast_ref` only shortens
- // the lifetime, so the pinning guarantee is preserved.
- Ok(unsafe { Pin::new_unchecked(F::cast_ref(pinned.get_ref())) })
+ /// Access the registration data set by the registering (parent) driver through a closure.
+ ///
+ /// `F` is the [`ForLt`](trait@ForLt) encoding of the data type. The closure receives a pinned
+ /// reference to the registration data.
+ ///
+ /// For covariant types that implement [`trait@CovariantForLt`], prefer
+ /// [`registration_data`](Self::registration_data) which returns a direct reference.
+ ///
+ /// Returns [`EINVAL`] if `F` does not match the type used by the parent driver when calling
+ /// [`Registration::new()`].
+ ///
+ /// Returns [`ENOENT`] if no registration data has been set, e.g. when the device was
+ /// registered by a C driver.
+ #[inline]
+ pub fn registration_data_with<F: ForLt + 'static, R>(
+ &self,
+ f: impl for<'a> FnOnce(Pin<&'a F::Of<'a>>) -> R,
+ ) -> Result<R> {
+ // SAFETY: The HRTB closure prevents the caller from smuggling in references with a
+ // concrete short lifetime, making the round-trip from `'static` sound regardless of
+ // variance.
+ let pinned = unsafe { self.registration_data_pinned::<F>()? };
+
+ Ok(f(pinned))
+ }
+
+ /// Returns a pinned reference to the registration data set by the registering (parent) driver.
+ ///
+ /// This method is only available when `F` implements [`trait@CovariantForLt`], which guarantees
+ /// that the lifetime shortening is sound.
+ ///
+ /// For non-covariant types, use the closure-based [`Self::registration_data_with`].
+ ///
+ /// Returns [`EINVAL`] if `F` does not match the type used by the parent driver when calling
+ /// [`Registration::new()`].
+ ///
+ /// Returns [`ENOENT`] if no registration data has been set, e.g. when the device was
+ /// registered by a C driver.
+ #[inline]
+ pub fn registration_data<F: CovariantForLt + 'static>(&self) -> Result<Pin<&F::Of<'_>>> {
+ // SAFETY: `CovariantForLt` guarantees covariance, which makes the lifetime shortening
+ // from `'static` to `'_` performed by `registration_data_pinned` sound.
+ unsafe { self.registration_data_pinned::<F>() }
}
}
@@ -399,22 +439,23 @@ struct RegistrationData<T> {
/// This type represents the registration of a [`struct auxiliary_device`]. When its parent device
/// is unbound, the corresponding auxiliary device will be unregistered from the system.
///
-/// The type parameter `F` is a [`CovariantForLt`](trait@CovariantForLt) encoding of the
-/// registration data type. For non-lifetime-parameterized types, use
-/// [`CovariantForLt!(T)`](macro@CovariantForLt).
-/// The data can be accessed by the auxiliary driver through [`Device::registration_data()`].
+/// The type parameter `F` is a [`ForLt`](trait@ForLt) encoding of the registration
+/// data type. For non-lifetime-parameterized types, use [`ForLt!(T)`](macro@ForLt).
+///
+/// The data can be accessed by the auxiliary driver through [`Device::registration_data()`] and
+/// [`Device::registration_data_with()`].
///
/// # Invariants
///
/// `self.adev` always holds a valid pointer to an initialized and registered
/// [`struct auxiliary_device`] whose `registration_data_rust` field points to a
/// valid `Pin<KBox<RegistrationData<F::Of<'static>>>>`.
-pub struct Registration<'a, F: CovariantForLt + 'static> {
+pub struct Registration<'a, F: ForLt + 'static> {
adev: NonNull<bindings::auxiliary_device>,
_phantom: PhantomData<F::Of<'a>>,
}
-impl<'a, F: CovariantForLt> Registration<'a, F>
+impl<'a, F: ForLt> Registration<'a, F>
where
for<'b> F::Of<'b>: Send + Sync,
{
@@ -526,7 +567,7 @@ pub fn new<E>(
}
}
-impl<F: CovariantForLt> Drop for Registration<'_, F> {
+impl<F: ForLt> Drop for Registration<'_, F> {
fn drop(&mut self) {
// SAFETY: By the type invariant of `Self`, `self.adev.as_ptr()` is a valid registered
// `struct auxiliary_device`.
@@ -548,7 +589,7 @@ fn drop(&mut self) {
}
// SAFETY: A `Registration` of a `struct auxiliary_device` can be released from any thread.
-unsafe impl<F: CovariantForLt> Send for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
+unsafe impl<F: ForLt> Send for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
// SAFETY: `Registration` does not expose any methods or fields that need synchronization.
-unsafe impl<F: CovariantForLt> Sync for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
+unsafe impl<F: ForLt> Sync for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
--
2.54.0
^ permalink raw reply related
* [PATCH v4 2/7] rust: types: introduce ForLt base trait for CovariantForLt
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Add a new ForLt trait as a base for CovariantForLt:
- ForLt (non-unsafe): represents a type generic over a lifetime, with
no covariance guarantee.
- CovariantForLt (unsafe): becomes a subtrait of ForLt that
additionally proves the type is covariant over its lifetime
parameter, providing a safe cast_ref() method.
This split allows non-covariant types (e.g. types behind a Mutex) to
implement ForLt and participate in DevresLt / registration data patterns
that use HRTB closures for sound access, without requiring a covariance
proof that would fail to compile.
Both macros share the UnsafeForLtImpl helper type, distinguished by
a const generic N: ForLt! emits N = 0 (no covariance proof),
CovariantForLt! emits N = 1 (with compile-time covariance proof).
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/types.rs | 1 +
rust/kernel/types/for_lt.rs | 72 +++++++++++++++++++++++++++++--------
rust/macros/for_lt.rs | 68 ++++++++++++++++++++++++-----------
rust/macros/lib.rs | 19 +++++++++-
4 files changed, 123 insertions(+), 37 deletions(-)
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index cbe6907042d3..c1ed05d1046c 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -14,6 +14,7 @@
#[doc(hidden)]
pub mod for_lt;
pub use for_lt::CovariantForLt;
+pub use for_lt::ForLt;
/// Used to transfer ownership to and from foreign (non-Rust) languages.
///
diff --git a/rust/kernel/types/for_lt.rs b/rust/kernel/types/for_lt.rs
index a11f7509633c..0b53494080b7 100644
--- a/rust/kernel/types/for_lt.rs
+++ b/rust/kernel/types/for_lt.rs
@@ -1,17 +1,59 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
-//! Provide implementation and test of the `CovariantForLt` trait and macro.
+//! Provide implementation and test of the `ForLt` and `CovariantForLt` traits and macros.
//!
-//! This module is hidden and user should just use `CovariantForLt!` directly.
+//! This module is hidden and users should just use `ForLt!` / `CovariantForLt!` directly.
use core::marker::PhantomData;
/// Representation of types generic over a lifetime.
///
-/// The type must be covariant over the generic lifetime, i.e. the lifetime parameter
-/// can be soundly shortened.
+/// # Macro
+///
+/// It is not recommended to implement this trait directly. `ForLt!` macro is provided to obtain a
+/// type that implements this trait.
///
-/// The lifetime involved must be covariant.
+/// The full syntax is
+///
+/// ```
+/// # use kernel::types::ForLt;
+/// # fn expect_lt<F: ForLt>() {}
+/// # struct TypeThatUse<'a>(&'a ());
+/// # expect_lt::<
+/// ForLt!(for<'a> TypeThatUse<'a>)
+/// # >();
+/// ```
+///
+/// which gives a type so that `<ForLt!(for<'a> TypeThatUse<'a>) as ForLt>::Of<'b>`
+/// is `TypeThatUse<'b>`.
+///
+/// You may also use a short-hand syntax which works similar to lifetime elision.
+/// The macro also accepts types that do not involve a lifetime at all.
+///
+/// ```
+/// # use kernel::types::ForLt;
+/// # fn expect_lt<F: ForLt>() {}
+/// # struct TypeThatUse<'a>(&'a ());
+/// # expect_lt::<
+/// ForLt!(TypeThatUse<'_>) // Equivalent to `ForLt!(for<'a> TypeThatUse<'a>)`.
+/// # >();
+/// # expect_lt::<
+/// ForLt!(&u32) // Equivalent to `ForLt!(for<'a> &'a u32)`.
+/// # >();
+/// # expect_lt::<
+/// ForLt!(u32) // Equivalent to `ForLt!(for<'a> u32)`.
+/// # >();
+/// ```
+pub trait ForLt {
+ /// The type parameterized by the lifetime.
+ type Of<'a>: 'a;
+}
+pub use macros::ForLt;
+
+/// [`trait@ForLt`] subtrait for types that are covariant over their lifetime parameter.
+///
+/// Provides a safe [`cast_ref`](CovariantForLt::cast_ref) method for types that are proven to be
+/// covariant. The `CovariantForLt!` macro syntax is the same as `ForLt!`.
///
/// # Macro
///
@@ -84,10 +126,7 @@
/// # Safety
///
/// `Self::Of<'a>` must be covariant over the lifetime `'a`.
-pub unsafe trait CovariantForLt {
- /// The type parameterized by the lifetime.
- type Of<'a>: 'a;
-
+pub unsafe trait CovariantForLt: ForLt {
/// Cast a reference to a shorter lifetime.
#[inline(always)]
fn cast_ref<'r, 'short: 'r, 'long: 'short>(long: &'r Self::Of<'long>) -> &'r Self::Of<'short> {
@@ -99,25 +138,28 @@ fn cast_ref<'r, 'short: 'r, 'long: 'short>(long: &'r Self::Of<'long>) -> &'r Sel
/// This is intended to be an "unsafe-to-refer-to" type.
///
-/// Must only be used by the `CovariantForLt!` macro.
+/// Must only be used by the `ForLt!` / `CovariantForLt!` macros.
///
/// `T` is the magic `dyn for<'a> WithLt<'a, TypeThatUse<'a>>` generated by macro.
///
/// `WF` is a type that the macro can use to assert some specific type is well-formed.
///
/// `N` is to provide the macro a place to emit arbitrary items, in case it needs to prove
-/// additional properties.
+/// additional properties. `ForLt!` emits `N = 0`; `CovariantForLt!` emits `N = 1` after a
+/// covariance proof.
#[doc(hidden)]
pub struct UnsafeForLtImpl<T: ?Sized, WF, const N: usize>(PhantomData<(WF, T)>);
-// This is a helper trait for implementation `CovariantForLt` to be able to use HRTB.
+// This is a helper trait for implementation of `ForLt` / `CovariantForLt` to be able to use HRTB.
#[doc(hidden)]
pub trait WithLt<'a> {
type Of: 'a;
}
-// SAFETY: In `CovariantForLt!` macro, a covariance proof is generated when naming
-// `UnsafeForLtImpl` and it will fail to evaluate if the type is not covariant.
-unsafe impl<T: ?Sized + for<'a> WithLt<'a>, WF> CovariantForLt for UnsafeForLtImpl<T, WF, 0> {
+impl<T: ?Sized + for<'a> WithLt<'a>, WF, const N: usize> ForLt for UnsafeForLtImpl<T, WF, N> {
type Of<'a> = <T as WithLt<'a>>::Of;
}
+
+// SAFETY: In `CovariantForLt!` macro, a covariance proof is generated in the `N` const generic
+// and it will fail to evaluate if the type is not covariant. Only `N = 1` gets this impl.
+unsafe impl<T: ?Sized + for<'a> WithLt<'a>, WF> CovariantForLt for UnsafeForLtImpl<T, WF, 1> {}
diff --git a/rust/macros/for_lt.rs b/rust/macros/for_lt.rs
index 9487a9352f1c..9270a069cd3a 100644
--- a/rust/macros/for_lt.rs
+++ b/rust/macros/for_lt.rs
@@ -176,8 +176,10 @@ fn prove(&mut self, ty: &'a Type) {
}
}
-pub(crate) fn covariant_for_lt(input: HigherRankedType) -> TokenStream {
- let (ty, lifetime) = match input {
+/// Resolve the higher-ranked type into a concrete `(ty, lifetime)` pair, expanding elided
+/// lifetimes as needed. Shared by both `for_lt` and `covariant_for_lt`.
+fn resolve_hrt(input: HigherRankedType) -> (Type, Lifetime) {
+ match input {
HigherRankedType::Explicit { lifetime, ty, .. } => (ty, lifetime),
HigherRankedType::Implicit { ty } => {
// If there's no explicit `for<'a>` binder, inject a synthetic `'__elided` lifetime
@@ -188,14 +190,33 @@ pub(crate) fn covariant_for_lt(input: HigherRankedType) -> TokenStream {
};
(ty.expand_elided_lifetime(&lifetime), lifetime)
}
- };
+ }
+}
+
+/// Produce the `'static`-substituted type for the WF check. Shared by both macros.
+fn ty_static(ty: &Type, lifetime: &Lifetime) -> Type {
+ ty.replace_lifetime(
+ lifetime,
+ &Lifetime {
+ apostrophe: Span::mixed_site(),
+ ident: format_ident!("static"),
+ },
+ )
+}
+
+/// Shared implementation for both `ForLt!` and `CovariantForLt!`.
+///
+/// Both macros run the prover and emit `ProveWf` structs to check well-formedness for all lifetime
+/// instances (workaround for <https://github.com/rust-lang/rust/issues/152489>). `CovariantForLt!`
+/// additionally emits covariance proof functions and sets `N = 1`.
+fn for_lt_inner(input: HigherRankedType, prove_covariance: bool) -> TokenStream {
+ let (ty, lifetime) = resolve_hrt(input);
let mut prover = Prover(&lifetime, Vec::new());
prover.prove(&ty);
let mut proof = Vec::new();
- // Emit proofs for every type that requires additional compiler help in proving covariance.
for (idx, required_proof) in prover.1.into_iter().enumerate() {
// Insert a proof that the type is well-formed.
//
@@ -210,15 +231,16 @@ struct #wf_proof_name<#lifetime>(
);
));
- // Insert a proof that the type is covariant.
- let cov_proof_name = format_ident!("prove_covariant_{idx}");
- proof.push(quote!(
- fn #cov_proof_name<'__short, '__long: '__short>(
- long: #wf_proof_name<'__long>
- ) -> #wf_proof_name<'__short> {
- long
- }
- ));
+ if prove_covariance {
+ let cov_proof_name = format_ident!("prove_covariant_{idx}");
+ proof.push(quote!(
+ fn #cov_proof_name<'__short, '__long: '__short>(
+ long: #wf_proof_name<'__long>
+ ) -> #wf_proof_name<'__short> {
+ long
+ }
+ ));
+ }
}
// Make sure that the type is wellformed when substituting lifetime with `'static`.
@@ -226,13 +248,9 @@ fn #cov_proof_name<'__short, '__long: '__short>(
// Currently the Rust compiler doesn't check this, see the above `ProveWf` documentation.
//
// We prefer to use this way of proving WF-ness as it can work when generics are involved.
- let ty_static = ty.replace_lifetime(
- &lifetime,
- &Lifetime {
- apostrophe: Span::mixed_site(),
- ident: format_ident!("static"),
- },
- );
+ let ty_static = ty_static(&ty, &lifetime);
+
+ let n: usize = prove_covariance.into();
quote!(
::kernel::types::for_lt::UnsafeForLtImpl::<
@@ -241,8 +259,16 @@ fn #cov_proof_name<'__short, '__long: '__short>(
{
#(#proof)*
- 0
+ #n
}
>
)
}
+
+pub(crate) fn for_lt(input: HigherRankedType) -> TokenStream {
+ for_lt_inner(input, false)
+}
+
+pub(crate) fn covariant_for_lt(input: HigherRankedType) -> TokenStream {
+ for_lt_inner(input, true)
+}
diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
index 2167cb270928..e970769609f3 100644
--- a/rust/macros/lib.rs
+++ b/rust/macros/lib.rs
@@ -491,11 +491,28 @@ pub fn kunit_tests(attr: TokenStream, input: TokenStream) -> TokenStream {
.into()
}
-/// Obtain a type that implements [`CovariantForLt`] for the given higher-ranked type.
+/// Obtain a type that implements [`ForLt`] for the given higher-ranked type.
+///
+/// Please refer to the documentation of the [`ForLt`] trait.
+///
+/// [`ForLt`]: trait.ForLt.html
+#[proc_macro]
+#[allow(non_snake_case)]
+pub fn ForLt(input: TokenStream) -> TokenStream {
+ for_lt::for_lt(parse_macro_input!(input)).into()
+}
+
+/// Obtain a type that implements [`CovariantForLt`] (and [`ForLt`]) for the given higher-ranked
+/// type.
+///
+/// Unlike [`ForLt!`], this macro additionally proves that the type is covariant over the lifetime,
+/// providing a safe [`CovariantForLt::cast_ref`] method.
///
/// Please refer to the documentation of the [`CovariantForLt`] trait.
///
/// [`CovariantForLt`]: trait.CovariantForLt.html
+/// [`CovariantForLt::cast_ref`]: trait.CovariantForLt.html#method.cast_ref
+/// [`ForLt`]: trait.ForLt.html
#[proc_macro]
#[allow(non_snake_case)]
pub fn CovariantForLt(input: TokenStream) -> TokenStream {
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v2 04/17] driver: core: Include headers for acpi_device_id and of_device_id for struct device_driver
From: Greg Kroah-Hartman @ 2026-06-26 18:35 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: Linus Torvalds, Rafael J. Wysocki, Danilo Krummrich, driver-core,
linux-kernel
In-Reply-To: <976ec5b0529016d63ca3cadf8792f7b2324ab58b.1782490566.git.u.kleine-koenig@baylibre.com>
On Fri, Jun 26, 2026 at 08:00:23PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> struct device_driver contains pointers of type struct of_device_id* and
> struct acpi_device_id* but doesn't ensure these are defined. To make the
> header self-contained add the (very lightweight) includes that contain
> the respective definitions.
>
> Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> ---
> include/linux/device/driver.h | 2 ++
> 1 file changed, 2 insertions(+)
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* [PATCH v4 1/7] rust: types: rename ForLt to CovariantForLt
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
In-Reply-To: <20260626183630.2585057-1-dakr@kernel.org>
Rename ForLt to CovariantForLt to prepare for the introduction of a new
ForLt base trait that does not require covariance.
The existing ForLt trait requires covariance, which enables the safe
cast_ref() method. This rename preserves the same semantics under a more
precise name, making room for a weaker ForLt trait in a subsequent
commit.
No functional change.
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
drivers/gpu/nova-core/driver.rs | 4 +-
rust/kernel/auxiliary.rs | 23 +++++------
rust/kernel/types.rs | 2 +-
rust/kernel/types/for_lt.rs | 57 ++++++++++++++-------------
rust/macros/for_lt.rs | 6 +--
rust/macros/lib.rs | 11 +++---
samples/rust/rust_driver_auxiliary.rs | 8 ++--
7 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index 5738d4ac521b..48380ac15f68 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -15,7 +15,7 @@
Atomic,
Relaxed, //
},
- types::ForLt,
+ types::CovariantForLt,
};
use crate::gpu::Gpu;
@@ -29,7 +29,7 @@ pub(crate) struct NovaCore<'bound> {
pub(crate) gpu: Gpu<'bound>,
bar: pci::Bar<'bound, BAR0_SIZE>,
#[allow(clippy::type_complexity)]
- _reg: auxiliary::Registration<'bound, ForLt!(())>,
+ _reg: auxiliary::Registration<'bound, CovariantForLt!(())>,
}
pub(crate) struct NovaCoreDriver;
diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs
index c42928d5a239..40a0af74a8e5 100644
--- a/rust/kernel/auxiliary.rs
+++ b/rust/kernel/auxiliary.rs
@@ -20,7 +20,7 @@
},
prelude::*,
types::{
- ForLt,
+ CovariantForLt,
ForeignOwnable,
Opaque, //
},
@@ -272,16 +272,16 @@ pub fn parent(&self) -> &device::Device<device::Bound> {
/// Returns a pinned reference to the registration data set by the registering (parent) driver.
///
- /// `F` is the [`ForLt`](trait@ForLt) encoding of the data type. The returned
+ /// `F` is the [`CovariantForLt`](trait@CovariantForLt) encoding of the data type. The returned
/// reference has its lifetime shortened from `'static` to `&self`'s borrow lifetime via
- /// [`ForLt::cast_ref`].
+ /// [`CovariantForLt::cast_ref`].
///
/// Returns [`EINVAL`] if `F` does not match the type used by the parent driver when calling
/// [`Registration::new()`].
///
/// Returns [`ENOENT`] if no registration data has been set, e.g. when the device was
/// registered by a C driver.
- pub fn registration_data<F: ForLt + 'static>(&self) -> Result<Pin<&F::Of<'_>>> {
+ pub fn registration_data<F: CovariantForLt + 'static>(&self) -> Result<Pin<&F::Of<'_>>> {
// SAFETY: By the type invariant, `self.as_raw()` is a valid `struct auxiliary_device`.
let ptr = unsafe { (*self.as_raw()).registration_data_rust };
if ptr.is_null() {
@@ -399,8 +399,9 @@ struct RegistrationData<T> {
/// This type represents the registration of a [`struct auxiliary_device`]. When its parent device
/// is unbound, the corresponding auxiliary device will be unregistered from the system.
///
-/// The type parameter `F` is a [`ForLt`](trait@ForLt) encoding of the registration
-/// data type. For non-lifetime-parameterized types, use [`ForLt!(T)`](macro@ForLt).
+/// The type parameter `F` is a [`CovariantForLt`](trait@CovariantForLt) encoding of the
+/// registration data type. For non-lifetime-parameterized types, use
+/// [`CovariantForLt!(T)`](macro@CovariantForLt).
/// The data can be accessed by the auxiliary driver through [`Device::registration_data()`].
///
/// # Invariants
@@ -408,12 +409,12 @@ struct RegistrationData<T> {
/// `self.adev` always holds a valid pointer to an initialized and registered
/// [`struct auxiliary_device`] whose `registration_data_rust` field points to a
/// valid `Pin<KBox<RegistrationData<F::Of<'static>>>>`.
-pub struct Registration<'a, F: ForLt + 'static> {
+pub struct Registration<'a, F: CovariantForLt + 'static> {
adev: NonNull<bindings::auxiliary_device>,
_phantom: PhantomData<F::Of<'a>>,
}
-impl<'a, F: ForLt> Registration<'a, F>
+impl<'a, F: CovariantForLt> Registration<'a, F>
where
for<'b> F::Of<'b>: Send + Sync,
{
@@ -525,7 +526,7 @@ pub fn new<E>(
}
}
-impl<F: ForLt> Drop for Registration<'_, F> {
+impl<F: CovariantForLt> Drop for Registration<'_, F> {
fn drop(&mut self) {
// SAFETY: By the type invariant of `Self`, `self.adev.as_ptr()` is a valid registered
// `struct auxiliary_device`.
@@ -547,7 +548,7 @@ fn drop(&mut self) {
}
// SAFETY: A `Registration` of a `struct auxiliary_device` can be released from any thread.
-unsafe impl<F: ForLt> Send for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
+unsafe impl<F: CovariantForLt> Send for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
// SAFETY: `Registration` does not expose any methods or fields that need synchronization.
-unsafe impl<F: ForLt> Sync for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
+unsafe impl<F: CovariantForLt> Sync for Registration<'_, F> where for<'a> F::Of<'a>: Send {}
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index ac316fd7b538..cbe6907042d3 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -13,7 +13,7 @@
#[doc(hidden)]
pub mod for_lt;
-pub use for_lt::ForLt;
+pub use for_lt::CovariantForLt;
/// Used to transfer ownership to and from foreign (non-Rust) languages.
///
diff --git a/rust/kernel/types/for_lt.rs b/rust/kernel/types/for_lt.rs
index d44323c28e8d..a11f7509633c 100644
--- a/rust/kernel/types/for_lt.rs
+++ b/rust/kernel/types/for_lt.rs
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT
-//! Provide implementation and test of the `ForLt` trait and macro.
+//! Provide implementation and test of the `CovariantForLt` trait and macro.
//!
-//! This module is hidden and user should just use `ForLt!` directly.
+//! This module is hidden and user should just use `CovariantForLt!` directly.
use core::marker::PhantomData;
@@ -15,38 +15,39 @@
///
/// # Macro
///
-/// It is not recommended to implement this trait directly. `ForLt!` macro is provided to obtain a
-/// type that implements this trait.
+/// It is not recommended to implement this trait directly. `CovariantForLt!` macro is provided to
+/// obtain a type that implements this trait.
///
/// The full syntax is
///
/// ```
-/// # use kernel::types::ForLt;
-/// # fn expect_lt<F: ForLt>() {}
+/// # use kernel::types::CovariantForLt;
+/// # fn expect_lt<F: CovariantForLt>() {}
/// # struct TypeThatUse<'a>(&'a ());
/// # expect_lt::<
-/// ForLt!(for<'a> TypeThatUse<'a>)
+/// CovariantForLt!(for<'a> TypeThatUse<'a>)
/// # >();
/// ```
///
-/// which gives a type so that `<ForLt!(for<'a> TypeThatUse<'a>) as ForLt>::Of<'b>`
+/// which gives a type so that
+/// `<CovariantForLt!(for<'a> TypeThatUse<'a>) as CovariantForLt>::Of<'b>`
/// is `TypeThatUse<'b>`.
///
/// You may also use a short-hand syntax which works similar to lifetime elision.
/// The macro also accepts types that do not involve a lifetime at all.
///
/// ```
-/// # use kernel::types::ForLt;
-/// # fn expect_lt<F: ForLt>() {}
+/// # use kernel::types::CovariantForLt;
+/// # fn expect_lt<F: CovariantForLt>() {}
/// # struct TypeThatUse<'a>(&'a ());
/// # expect_lt::<
-/// ForLt!(TypeThatUse<'_>) // Equivalent to `ForLt!(for<'a> TypeThatUse<'a>)`.
+/// CovariantForLt!(TypeThatUse<'_>) // Equivalent to `CovariantForLt!(for<'a> TypeThatUse<'a>)`.
/// # >();
/// # expect_lt::<
-/// ForLt!(&u32) // Equivalent to `ForLt!(for<'a> &'a u32)`.
+/// CovariantForLt!(&u32) // Equivalent to `CovariantForLt!(for<'a> &'a u32)`.
/// # >();
/// # expect_lt::<
-/// ForLt!(u32) // Equivalent to `ForLt!(for<'a> u32)`.
+/// CovariantForLt!(u32) // Equivalent to `CovariantForLt!(for<'a> u32)`.
/// # >();
/// ```
///
@@ -55,10 +56,10 @@
/// it.
///
/// ```ignore,compile_fail
-/// # use kernel::types::ForLt;
-/// # fn expect_lt<F: ForLt>() {}
+/// # use kernel::types::CovariantForLt;
+/// # fn expect_lt<F: CovariantForLt>() {}
/// # expect_lt::<
-/// ForLt!(fn(&u32)) // Contravariant, will fail compilation.
+/// CovariantForLt!(fn(&u32)) // Contravariant, will fail compilation.
/// # >();
/// ```
///
@@ -67,23 +68,23 @@
/// the generic parameter but is in a separate item.
///
/// ```
-/// # use kernel::types::ForLt;
-/// fn expect_lt<F: ForLt>() {}
+/// # use kernel::types::CovariantForLt;
+/// fn expect_lt<F: CovariantForLt>() {}
/// # #[allow(clippy::unnecessary_safety_comment, reason = "false positive")]
/// fn generic_fn<T: 'static>() {
/// // Syntactically proven by the macro
-/// expect_lt::<ForLt!(&T)>();
+/// expect_lt::<CovariantForLt!(&T)>();
/// // Syntactically proven by the macro
-/// expect_lt::<ForLt!(&KBox<T>)>();
+/// expect_lt::<CovariantForLt!(&KBox<T>)>();
/// // Cannot be syntactically proven, need to check covariance of `KBox`
-/// // expect_lt::<ForLt!(&KBox<&T>)>();
+/// // expect_lt::<CovariantForLt!(&KBox<&T>)>();
/// }
/// ```
///
/// # Safety
///
/// `Self::Of<'a>` must be covariant over the lifetime `'a`.
-pub unsafe trait ForLt {
+pub unsafe trait CovariantForLt {
/// The type parameterized by the lifetime.
type Of<'a>: 'a;
@@ -94,11 +95,11 @@ fn cast_ref<'r, 'short: 'r, 'long: 'short>(long: &'r Self::Of<'long>) -> &'r Sel
unsafe { core::mem::transmute(long) }
}
}
-pub use macros::ForLt;
+pub use macros::CovariantForLt;
/// This is intended to be an "unsafe-to-refer-to" type.
///
-/// Must only be used by the `ForLt!` macro.
+/// Must only be used by the `CovariantForLt!` macro.
///
/// `T` is the magic `dyn for<'a> WithLt<'a, TypeThatUse<'a>>` generated by macro.
///
@@ -109,14 +110,14 @@ fn cast_ref<'r, 'short: 'r, 'long: 'short>(long: &'r Self::Of<'long>) -> &'r Sel
#[doc(hidden)]
pub struct UnsafeForLtImpl<T: ?Sized, WF, const N: usize>(PhantomData<(WF, T)>);
-// This is a helper trait for implementation `ForLt` to be able to use HRTB.
+// This is a helper trait for implementation `CovariantForLt` to be able to use HRTB.
#[doc(hidden)]
pub trait WithLt<'a> {
type Of: 'a;
}
-// SAFETY: In `ForLt!` macro, a covariance proof is generated when naming `UnsafeForLtImpl`
-// and it will fail to evaluate if the type is not covariant.
-unsafe impl<T: ?Sized + for<'a> WithLt<'a>, WF> ForLt for UnsafeForLtImpl<T, WF, 0> {
+// SAFETY: In `CovariantForLt!` macro, a covariance proof is generated when naming
+// `UnsafeForLtImpl` and it will fail to evaluate if the type is not covariant.
+unsafe impl<T: ?Sized + for<'a> WithLt<'a>, WF> CovariantForLt for UnsafeForLtImpl<T, WF, 0> {
type Of<'a> = <T as WithLt<'a>>::Of;
}
diff --git a/rust/macros/for_lt.rs b/rust/macros/for_lt.rs
index 364d4113cd10..9487a9352f1c 100644
--- a/rust/macros/for_lt.rs
+++ b/rust/macros/for_lt.rs
@@ -154,8 +154,8 @@ fn prove(&mut self, ty: &'a Type) {
// Note that if we encounter `&'other_lt T`, then we still need to make sure the type
// is wellformed if `T` involves `&'lt`, so we defer to the compiler.
//
- // This is to block cases like `ForLt!(for<'a> &'static &'a u32)`, as the presence of
- // the type implies `'a: 'static` but this is unsound.
+ // This is to block cases like `CovariantForLt!(for<'a> &'static &'a u32)`, as the
+ // presence of the type implies `'a: 'static` but this is unsound.
Type::Reference(ty)
if ty.mutability.is_none() && ty.lifetime.as_ref() == Some(self.0) =>
{
@@ -176,7 +176,7 @@ fn prove(&mut self, ty: &'a Type) {
}
}
-pub(crate) fn for_lt(input: HigherRankedType) -> TokenStream {
+pub(crate) fn covariant_for_lt(input: HigherRankedType) -> TokenStream {
let (ty, lifetime) = match input {
HigherRankedType::Explicit { lifetime, ty, .. } => (ty, lifetime),
HigherRankedType::Implicit { ty } => {
diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
index 4a48fabbc268..2167cb270928 100644
--- a/rust/macros/lib.rs
+++ b/rust/macros/lib.rs
@@ -491,14 +491,13 @@ pub fn kunit_tests(attr: TokenStream, input: TokenStream) -> TokenStream {
.into()
}
-/// Obtain a type that implements [`ForLt`] for the given higher-ranked type.
+/// Obtain a type that implements [`CovariantForLt`] for the given higher-ranked type.
///
-/// Please refer to the documentation of the [`ForLt`] trait.
+/// Please refer to the documentation of the [`CovariantForLt`] trait.
///
-/// [`ForLt`]: trait.ForLt.html
+/// [`CovariantForLt`]: trait.CovariantForLt.html
#[proc_macro]
-// The macro shares the name with the trait.
#[allow(non_snake_case)]
-pub fn ForLt(input: TokenStream) -> TokenStream {
- for_lt::for_lt(parse_macro_input!(input)).into()
+pub fn CovariantForLt(input: TokenStream) -> TokenStream {
+ for_lt::covariant_for_lt(parse_macro_input!(input)).into()
}
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
index 2c1351040e45..92ee6a6d348e 100644
--- a/samples/rust/rust_driver_auxiliary.rs
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -13,7 +13,7 @@
driver,
pci,
prelude::*,
- types::ForLt,
+ types::CovariantForLt,
InPlaceModule, //
};
@@ -60,8 +60,8 @@ struct Data<'bound> {
#[allow(clippy::type_complexity)]
struct ParentData<'bound> {
- _reg0: auxiliary::Registration<'bound, ForLt!(Data<'_>)>,
- _reg1: auxiliary::Registration<'bound, ForLt!(Data<'_>)>,
+ _reg0: auxiliary::Registration<'bound, CovariantForLt!(Data<'_>)>,
+ _reg1: auxiliary::Registration<'bound, CovariantForLt!(Data<'_>)>,
}
kernel::pci_device_table!(
@@ -115,7 +115,7 @@ fn probe<'bound>(
impl ParentDriver {
fn connect(adev: &auxiliary::Device<Bound>) -> Result {
- let data = adev.registration_data::<ForLt!(Data<'_>)>()?;
+ let data = adev.registration_data::<CovariantForLt!(Data<'_>)>()?;
let pdev = data.parent;
dev_info!(
--
2.54.0
^ permalink raw reply related
* [PATCH v4 0/7] ForLt/CovariantForLt split, auxiliary closure API and DevresLt
From: Danilo Krummrich @ 2026-06-26 18:36 UTC (permalink / raw)
To: gregkh, rafael, dakr, ojeda, boqun, gary, bjorn3_gh, lossin,
a.hindborg, aliceryhl, tmgross, acourbot, ecourtney, m.wilczynski,
david.m.ertman, ira.weiny, leon, daniel.almeida, bhelgaas,
kwilczynski
Cc: driver-core, linux-kernel, nova-gpu, dri-devel, linux-pwm,
rust-for-linux
The ForLt trait currently guarantees covariance, which allows safe
lifetime shortening via cast_ref(). However, some types (e.g. those
containing Mutex<&'bound T>) are invariant over their lifetime parameter
and cannot safely use cast_ref().
This series splits ForLt into two traits:
- ForLt: base trait for all lifetime-parameterized types, providing
only the Of<'a> GAT.
- CovariantForLt: unsafe subtrait that guarantees covariance,
providing a safe cast_ref() method.
For invariant types, a closure-based API (registration_data_with()) is
added to the auxiliary subsystem. The closure's HRTB prevents the caller
from choosing a concrete lifetime, which would be unsound for invariant
types.
On top of that, this series adds DevresLt<F: ForLt>, a thin wrapper
around Devres<F::Of<'static>> that shortens the stored 'static lifetime
back to the caller's borrow scope. DevresLt provides both closure-based
access (access_with/try_access_with for ForLt types) and direct
reference access (access/try_access for CovariantForLt types).
Also implement ForLt and CovariantForLt for Bar, IoMem and
ExclusiveIoMem, and update their into_devres() methods to return
DevresLt. Provide convenience type aliases DevresBar, DevresIoMem and
DevresExclusiveIoMem.
Changes in v4:
- ForLt! macro: run the Prover and emit ProveWf structs for
well-formedness checks
- DevresLt: change Send bound from F::Of<'static>: Send to the
correct for<'a> F::Of<'a>: Send
- Add #[inline] to forwarding functions in registration_data_with,
registration_data, and all DevresLt accessors
Changes in v3:
- Keep UnsafeForLtImpl as the shared helper for both ForLt! and
CovariantForLt!, distinguished by const generic N
- Remove cast_ref_unchecked() from ForLt; lifetime shortening is
handled by borrowing with the target lifetime directly or by
decoupling the HRTB from the outer reference lifetime
Changes in v2:
- Fold the ForLt -> CovariantForLt rename and the new ForLt base trait
into this series
- Add closure-based registration_data_with() for auxiliary ForLt types
- Add auxiliary sample demonstrating ForLt with an invariant Mutex type
- DevresLt: add closure-based access_with()/try_access_with() for ForLt
types alongside direct access()/try_access() for CovariantForLt types
- Make DevresLt::new() unsafe; callers must guarantee the data outlives
the device binding
- Implement both ForLt and CovariantForLt (previously just ForLt) for
Bar, IoMem, ExclusiveIoMem
- Various safety comment and documentation improvements
Danilo Krummrich (7):
rust: types: rename ForLt to CovariantForLt
rust: types: introduce ForLt base trait for CovariantForLt
rust: auxiliary: add registration_data_with() for ForLt types
rust: auxiliary: sample: demonstrate ForLt with invariant Mutex type
rust: devres: add DevresLt for ForLt-aware device resource access
rust: pci: return DevresLt from Bar::into_devres()
rust: io: mem: return DevresLt from
IoMem/ExclusiveIoMem::into_devres()
drivers/gpu/nova-core/driver.rs | 4 +-
drivers/pwm/pwm_th1520.rs | 5 +-
rust/kernel/auxiliary.rs | 78 ++++++++++++++-----
rust/kernel/devres.rs | 106 ++++++++++++++++++++++++++
rust/kernel/io/mem.rs | 65 +++++++++++-----
rust/kernel/pci.rs | 1 +
rust/kernel/pci/io.rs | 37 ++++++---
rust/kernel/types.rs | 1 +
rust/kernel/types/for_lt.rs | 95 ++++++++++++++++-------
rust/macros/for_lt.rs | 72 +++++++++++------
rust/macros/lib.rs | 18 ++++-
samples/rust/rust_driver_auxiliary.rs | 96 ++++++++++++++++-------
12 files changed, 447 insertions(+), 131 deletions(-)
base-commit: 51cb1aa1250c36269474b8b6ca6b6319e170f5a5
--
2.54.0
^ permalink raw reply
* Re: [PATCH v2 04/17] driver: core: Include headers for acpi_device_id and of_device_id for struct device_driver
From: Linus Torvalds @ 2026-06-26 18:30 UTC (permalink / raw)
To: Uwe Kleine-König (The Capable Hub)
Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
driver-core, linux-kernel
In-Reply-To: <976ec5b0529016d63ca3cadf8792f7b2324ab58b.1782490566.git.u.kleine-koenig@baylibre.com>
Ok, looking at these patches, I realize that I hate the pathname.
On Fri, 26 Jun 2026 at 11:01, Uwe Kleine-König (The Capable Hub)
<u.kleine-koenig@baylibre.com> wrote:
>
> +#include <linux/mod_device_id/acpi.h>
> +#include <linux/mod_device_id/of.h>
Honestly, that "mod_" part of the path name makes no sense to me.
Yes, it came from the old header name "mod_devicetable.h", and yes, it
comes from the fact that the device ID structures are also used for
module loading rules. So there's a historical reason for the "mod",
but I don't think it's a particularly good reason, and not a reason to
keep it.
None of the structures are called that - they are just called
"xyz_device_id", and while module loading may be *one* of the uses for
it, it certainly isn't the only one - or even the main one. Arguably a
much bigger reason for those device ids tend to be all the bus
matching code (ie acpi_match_device() and friends).
So let's just get rid of the "mod" part from the name, ok?
Linus
^ permalink raw reply
* [PATCH v2 04/17] driver: core: Include headers for acpi_device_id and of_device_id for struct device_driver
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-26 18:00 UTC (permalink / raw)
To: Linus Torvalds, Greg Kroah-Hartman
Cc: Rafael J. Wysocki, Danilo Krummrich, driver-core, linux-kernel
In-Reply-To: <cover.1782490566.git.u.kleine-koenig@baylibre.com>
struct device_driver contains pointers of type struct of_device_id* and
struct acpi_device_id* but doesn't ensure these are defined. To make the
header self-contained add the (very lightweight) includes that contain
the respective definitions.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
include/linux/device/driver.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
index 38048e74d10a..5323157571a5 100644
--- a/include/linux/device/driver.h
+++ b/include/linux/device/driver.h
@@ -19,6 +19,8 @@
#include <linux/pm.h>
#include <linux/device/bus.h>
#include <linux/module.h>
+#include <linux/mod_device_id/acpi.h>
+#include <linux/mod_device_id/of.h>
/**
* enum probe_type - device driver probe type to try
--
2.47.3
^ permalink raw reply related
* [PATCH v2 00/17] mod_devicetable.h: Split into per subsystem headers
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-26 18:00 UTC (permalink / raw)
To: Linus Torvalds, Greg Kroah-Hartman, Mark Brown
Cc: Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Raag Jadav, Sohil Mehta, Dave Hansen, Rob Herring,
Saravana Kannan, Bjorn Helgaas, Rafael J. Wysocki, Len Brown,
Andi Shyti, linux-kernel, Yemike Abhilash Chandra,
Mauro Carvalho Chehab, linux-media, Nicolas Frattaroli,
Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Heiko Stuebner,
linux-rockchip, linux-sound, linux-arm-kernel, Danilo Krummrich,
driver-core, Jonathan Cameron, Dmitry Torokhov,
Bartosz Golaszewski, Pei Xiao, Shashank Balaji, Ben Horgan,
Johan Hovold, linux-usb, Nikita Kravets, Hans de Goede,
Ilpo Järvinen, platform-driver-x86, devicetree, linux-i2c,
Daniel Scally, Sakari Ailus, Minas Harutyunyan, Tianrui Zhao,
Bibo Mao, Huacai Chen, WANG Xuerui, kvm, loongarch
Hello,
this is v2 of
https://lore.kernel.org/lkml/20260622210733.1743063-2-u.kleine-koenig@baylibre.com
which only consisted of the patch that is the first in this series.
Changes to this first patch are mostly cosmetic (whitespace cleanups)
and I renamed tee.h to tee_client.h to match tee_client_device_id.
The following 14 patches are preparations for patch #16 that replaces
the include of <linux/mod_devicetable.h> in several key header files by
a subset of the split headers that are needed for these. As there are
some drivers that rely on e.g. <linux/i2c.h> pulling in the definition
for usb_device_id, these must be prepared before <linux/i2c.h> stops
providing this definition.
patch #17 adapts various .c files to stop including
<linux/mod_devicetable.h>. These are easier as the device_ids that have
to be provided are only those used in that .c file. This last patch was
created by the Python script below. That also checks if the needed
headers are present for the files that don't explicitly include
<linux/mod_devicetable.h>. There are 131 files where the script was
unable to prove the includes to be sufficient. Most of them are covered
by build testing, the few remaining ones (12 .c files, 36 headers) were
checked semi-manually.
This series was compile tested for alpha, arc, arm64, loongarch, m68k,
mips, powerpc, riscv, s390, sh, sparc, and x86_64 using an allmodconfig
configuration.
There are a few remaining usages of <linux/mod_devicetable.h>, I plan to
tackle them for the next merge window. These also shouldn't affect so
many files any more and so these changes will annoy less (i.e. result in
less recompilation during bisection and/or development).
Preparing this series took me longer than I hoped, so it's too late to
get it into next before -rc1. I will push this series to
https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git device-id-rework
Given that there are a few merge conflicts with what is in Linus's tree
in the meantime, my plan is to rebase this branch to v7.2-rc1, retest
and then hopefully consider it ready for v7.2-rc2 after cooking in next
for a few days. This has the advantage that hardly any new conflicts
should get introduced in Linus's tree then.
Sounds like a sensible plan?
@Mark: I hope to have the rebase ready before you start working on
next-20260629. If not, just drop this branch from your list for this
day.
Best regards
Uwe
------->8--------
#!/usr/bin/env python3
import re
import os
# Maps a struct name to a set of headers that are enough to provide that struct.
symbol_header_map = {
'acpi_device_id': (
'linux/mod_device_id/acpi.h',
'linux/acpi.h', # includes <linux/mod_devicetable.h>
'linux/i2c.h', # includes <linux/acpi.h>
'linux/device.h', # includes <linux/device/driver.h> which includes linux/mod_device_id/acpi.h
'linux/spi/spi.h', # includes <linux/device.h>
'linux/backlight.h', # includes <linux/device.h>
'linux/pci.h', # includes <linux/device.h>
'linux/platform_device.h', # includes <linux/device.h>
'linux/auxiliary_bus.h', # includes <linux/device.h>
'sound/soc.h', # includes <linux/platform_device.h>
'sound/sof.h', # includes <linux/device.h>
),
'amba_id': (
'linux/mod_device_id/amba.h',
'linux/amba/bus.h', # includes <linux/mod_devicetable.h>
),
'ap_device_id': (
'linux/mod_device_id/ap.h',
),
'apr_device_id': (
'linux/mod_device_id/apr.h',
'linux/soc/qcom/apr.h', # includes <linux/mod_devicetable.h>
),
'auxiliary_device_id': (
'linux/mod_device_id/auxiliary.h',
'linux/auxiliary_bus.h', # includes <linux/mod_devicetable.h>
'linux/misc/keba.h', # includes <linux/auxiliary_bus.h>
'linux/mlx4/driver.h', # includes <linux/auxiliary_bus.h>
'linux/soc/cirrus/ep93xx.h', # includes <linux/auxiliary_bus.h>
),
'bcma_device_id': (
'linux/mod_device_id/bcma.h',
'linux/bcma/bcma.h', # includes <linux/mod_devicetable.h>
),
'ccw_device_id': (
'linux/mod_device_id/ccw.h',
'asm/ccwdev.h', # includes <linux/mod_devicetable.h>
),
'cdx_device_id': (
'linux/mod_device_id/cdx.h',
'linux/cdx/cdx_bus.h', # includes <linux/mod_devicetable.h>
),
'coreboot_device_id': (
'linux/mod_device_id/coreboot.h',
),
'css_device_id': (
'linux/mod_device_id/css.h',
'css.h',
),
'dfl_device_id': (
'linux/mod_device_id/dfl.h',
'linux/dfl.h', # includes <linux/mod_devicetable.h>
),
'dmi_(device|system)_id': (
'linux/mod_device_id/dmi.h',
'linux/dmi.h', # includes <linux/mod_devicetable.h>
),
'eisa_device_id': (
'linux/mod_device_id/eisa.h',
'linux/eisa.h', # includes <linux/mod_devicetable.h>
),
'fsl_mc_device_id': (
'linux/mod_device_id/fsl_mc.h',
'linux/fsl/mc.h', # includes <linux/mod_devicetable.h>
),
'hda_device_id': (
'linux/mod_device_id/hda.h',
'sound/hda_codec.h', # includes <linux/mod_devicetable.h>
),
'hid_device_id': (
'linux/mod_device_id/hid.h',
'linux/hid.h', # includes <linux/mod_devicetable.h>
'linux/hidraw.h', # includes <linux/hid.h> transitively
),
'hv_vmbus_device_id': (
'linux/mod_device_id/hv_vmbus.h',
'linux/hyperv.h', # includes linux/mod_devicetable.h>
'hyperv_net.h', # includes linux/hyperv.h
),
'i2c_device_id': (
'linux/mod_device_id/i2c.h',
'linux/i2c.h', # includes <linux/mod_devicetable.h>
'linux/mfd/lp873x.h', # includes <linux/i2c.h>
'media/dvb_frontend.h', # includes <linux/i2c.h>
),
'i3c_device_id': (
'linux/mod_device_id/i3c.h',
'linux/i3c/device.h', # includes <linux/mod_devicetable.h>
'linux/i3c/master.h', # includes <linux/i3c/device.h>
),
'ieee1394_device_id': (
'linux/mod_device_id/ieee1394.h',
'linux/firewire.h', # should include <linux/mod_device_id/ieee1394.h>, instead of fwd decl
),
'input_device_id': (
'linux/mod_device_id/input.h',
'linux/input.h', # includes <linux/mod_devicetable.h>
),
'ipack_device_id': (
'linux/mod_device_id/ipack.h',
'linux/ipack.h', # includes <linux/mod_devicetable.h>
),
'isapnp_device_id': (
'linux/mod_device_id/isapnp.h',
'linux/isapnp.h', # includes <linux/mod_devicetable.h>
),
'ishtp_device_id': (
'linux/mod_device_id/ishtp.h',
'linux/intel-ish-client-if.h', # includes <linux/mod_devicetable.h>
),
'mcb_device_id': (
'linux/mod_device_id/mcb.h',
'linux/mcb.h', # includes <linux/mod_devicetable.h>
),
'mdio_device_id': (
'linux/mod_device_id/mdio.h',
'linux/phy.h', # includes <linux/mod_devicetable.h>
),
'mei_cl_device_id': (
'linux/mod_device_id/mei_cl.h',
'linux/mei_cl_bus.h', # includes <linux/mod_devicetable.h>
),
'mhi_device_id': (
'linux/mod_device_id/mhi.h',
'linux/mhi.h', # should include <linux/mod_device_id/mhi.h>
),
'mips_cdmm_device_id': (
'linux/mod_device_id/mips_cdmm.h',
'asm/cdmm.h', # arch/mips/include/asm/cdmm.h includes mod_devicetable.h
),
'of_device_id': (
'linux/mod_device_id/of.h',
'linux/of.h', # includes <linux/mod_devicetable.h>
'linux/of_address.h', # includes <linux/of.h>
'linux/of_platform.h', # includes <linux/mod_devicetable.h>
'linux/device/driver.h', # includes <linux/mod_device_id/of.h>
'linux/device.h', # includes <linux/device/driver.h>
'linux/acpi.h', # includes <linux/device.h>
'linux/backlight.h', # includes <linux/device.h>
'linux/moxtet.h', # includes <linux/device.h>
'linux/greybus.h', # includes <linux/device.h>
'linux/platform_device.h', # includes <linux/device.h>
'linux/powercap.h', # includes <linux/device.h>
'linux/auxiliary_bus.h', # includes <linux/device.h>
'linux/i2c.h', # includes <linux/of.h>
'linux/reset.h', # includes <linux/of.h>
'linux/spi/spi.h', # includes <linux/device.h>
'asm/machine.h', # arch/mips/include/asm/machine.h includes <linux/of.h>
'asm/macio.h', # arch/powerpc/include/asm/macio.h includes <linux/of.h>
'sound/soc.h', # includes <linux/platform_device.h>
'sound/dmaengine_pcm.h', # includes <sound/soc.h>
'linux/pm_qos.h', # includes <linux/device.h>
'linux/clk-provider.h', # includes <linux/of.h>
),
'parisc_device_id': (
'linux/mod_device_id/parisc.h',
'asm/parisc-device.h', # should include <linux/mod_device_id/parisc.h>
'asm/hardware.h', # includes <linux/mod_devicetable.h>
),
'pci_device_id': (
'linux/mod_device_id/pci.h',
'linux/pci.h', # includes <linux/mod_devicetable.h>
'linux/comedi/comedi_pci.h', # includes <linux/pci.h>
'sound/hdaudio.h', # includes <linux/pci.h>
'sound/hdaudio_ext.h', # includes <sound/hdaudio.h>
),
'pci_epf_device_id': (
'linux/mod_device_id/pci.h',
'linux/pci-epf.h', # includes <linux/mod_devicetable.h>
),
'pcmcia_device_id': (
'linux/mod_device_id/pcmcia.h',
'pcmcia/ds.h', # includes <linux/mod_devicetable.h>
'linux/comedi/comedi_pcmcia.h', # includes <pcmcia/ds.h>
),
'platform_device_id': (
'linux/mod_device_id/platform.h',
'linux/platform_device.h', # includes <linux/mod_device_id/platform.h>
'linux/mfd/core.h', # includes <linux/platform_device.h>
'linux/ipmi_smi.h', # includes <linux/platform_device.h>
'sound/soc.h', # includes <linux/platform_device.h>
'sound/dmaengine_pcm.h', # includes <sound/soc.h>
),
'pnp_(card_)?device_id': (
'linux/mod_device_id/pnp.h',
'linux/pnp.h', # includes <linux/mod_devicetable.h>
'linux/isapnp.h', # includes <linux/pnp.h>
),
'rio_device_id': (
'linux/mod_device_id/rio.h',
'linux/rio.h', # includes <linux/mod_devicetable.h>
),
'rpmsg_device_id': (
'linux/mod_device_id/rpmsg.h',
'linux/rpmsg.h', # includes <linux/mod_devicetable.h>
),
'sdio_device_id': (
'linux/mod_device_id/sdio.h',
'linux/mmc/sdio_func.h', # includes <linux/mod_devicetable.h>
),
'sdw_device_id': (
'linux/mod_device_id/sdw.h',
'linux/soundwire/sdw.h', # includes <linux/mod_devicetable.h>
),
'serio_device_id': (
'linux/mod_device_id/serio.h',
'linux/serio.h', # includes <linux/mod_devicetable.h>
'linux/hil_mlc.h', # includes <linux/serio.h>
),
'slim_device_id': (
'linux/mod_device_id/slim.h',
'linux/slimbus.h', # includes <linux/mod_devicetable.h>
),
'spi_device_id': (
'linux/mod_device_id/spi.h',
'linux/spi/spi.h', # includes <linux/mod_devicetable.h>
),
'spmi_device_id': (
'linux/mod_device_id/spmi.h',
),
'ssam_device_id': (
'linux/mod_device_id/ssam.h',
'linux/surface_aggregator/device.h', # includes <linux/mod_devicetable.h>
),
'ssb_device_id': (
'linux/mod_device_id/ssb.h',
'linux/ssb/ssb.h', # includes <linux/mod_devicetable.h>
),
'tb_service_id': (
'linux/mod_device_id/tb.h',
'linux/thunderbolt.h', # includes <linux/mod_devicetable.h>
'tb.h', # drivers/thunderbolt/tb.h includes <linux/thunderbolt.h>
),
'tee_client_device_id': (
'linux/mod_device_id/tee_client.h',
'linux/tee_drv.h', # includes <linux/mod_devicetable.h>
'linux/tee_core.h', # includes <linux/tee_drv.h>
),
'typec_device_id': (
'linux/mod_device_id/typec.h',
'linux/usb/typec_altmode.h', # includes <linux/mod_devicetable.h>
'linux/usb/typec_dp.h', # includes <linux/usb/typec_altmode.h>
),
'ulpi_device_id': (
'linux/mod_device_id/ulpi.h',
'linux/ulpi/driver.h', # includes <linux/mod_devicetable.h>
),
'usb_device_id': (
'linux/mod_device_id/usb.h',
'linux/usb.h', # includes <linux/mod_devicetable.h>
'linux/comedi/comedi_usb.h', # includes <linux/usb.h>
'linux/usb/input.h', # includes <linux/usb.h>
),
'vchiq_device_id': (
'linux/mod_device_id/vchiq.h',
'linux/raspberrypi/vchiq_bus.h', # includes <linux/mod_devicetable.h>
),
'virtio_device_id': (
'linux/mod_device_id/virtio.h',
'linux/virtio.h', # includes <linux/mod_devicetable.h>
'linux/virtio_config.h', # includes <linux/virtio.h>
'uapi/linux/virtio_pmem.h', # includes <linux/virtio_config.h>
),
'wmi_device_id': (
'linux/mod_device_id/wmi.h',
'linux/wmi.h', # includes <linux/mod_devicetable.h>
),
'x86_(cpu|device)_id': (
'linux/mod_device_id/x86_cpu.h',
'linux/platform_data/x86/soc.h', # includes <linux/mod_devicetable.h>
'asm/cpu_device_id.h', # includes <linux/mod_devicetable.h>
),
'zorro_device_id': (
'linux/mod_device_id/zorro.h',
'linux/zorro.h', # includes <linux/mod_devicetable.h>
),
'cpu_feature': (
'linux/mod_devicetable.h',
'linux/cpufeature.h', # includes <linux/mod_devicetable.h>
),
}
for dirpath, dirnames, filenames in os.walk('.'):
for fn in (os.path.join(dirpath, f) for f in filenames if re.match(r'.*\.[ch]$', f)):
if fn in ('./scripts/mod/devicetable-offsets.c', './scripts/mod/file2alias.c'):
continue
with open(fn) as f:
try:
filecontent = f.read()
except Exception as e:
print(f"Error { e } while reading { fn }")
continue
# If the file has an include of the legacy header, drop it
if momdt := re.search(r'#[ \t]*include\s*[<"]linux/mod_devicetable.h[>"]([ \t]*/\*[^*]*\*/)?[ \t]*\n', filecontent):
filecontent = filecontent[:momdt.start()] + filecontent[momdt.end():]
for s, hs in symbol_header_map.items():
if re.search(fr'\bstruct\s*{ s }\b\s*;', filecontent):
# with a forward declaration assume we're fine (unsafe!)
continue
if re.search(fr'\bstruct\s*{ s }\b', filecontent):
if fn.endswith(tuple('/' + h for h in hs)):
break
# include local headers
seenheaders = set()
expanded_filecontent = filecontent
while mo := re.search(r'#\s*include\s*"([^"]*)"', expanded_filecontent):
start, end = mo.span(0)
lhn = mo.group(1)
if lhn in seenheaders:
expanded_filecontent = expanded_filecontent[:start] + expanded_filecontent[end:]
else:
seenheaders.add(lhn)
try:
with open(os.path.join(dirpath, lhn)) as lh:
lhcontent = lh.read()
expanded_filecontent = expanded_filecontent[:start] + lhcontent + expanded_filecontent[end:]
except Exception:
expanded_filecontent = expanded_filecontent[:start] + expanded_filecontent[end:]
for h in hs:
if re.search(fr'#\s*include\s*[<"]{ h }[>"]', expanded_filecontent):
break
else:
# only rewrite .c files, headers need more care
if momdt:
if fn.endswith('.c'):
filecontent = filecontent[:momdt.start()] + f'#include <{ hs[0] }>\n' + filecontent[momdt.start():]
else:
print(f"Header for { s } missing in { fn }")
if momdt and fn.endswith('.c'):
with open(fn, "w") as f:
f.write(filecontent)
------->8--------
Uwe Kleine-König (The Capable Hub) (17):
mod_devicetable.h: Split into per subsystem headers
media: ti: vpe: #include <linux/platform_device.h> explicitly
ASoC: rockchip: rockchip_sai: #include <linux/platform_device.h>
explicitly
driver: core: Include headers for acpi_device_id and of_device_id for
struct device_driver
driver core: platform: Include header for struct platform_device_id
usb: serial: Include <linux/usb.h> in <linux/usb/serial.h>
platform/x86: msi-ec: Ensure dmi_system_id is defined
of: Explicitly include <linux/types.h> and <linux/err.h>
i2c: Let i2c-core.h include <linux/i2c.h>
platform/x86: x86-android-tablets: Add include defining struct
dmi_system_id
platform/x86: int3472: Add include defining struct dmi_system_id
usb: dwc2: Add include defining struct pci_device_id
ALSA: hda/core: Add include defining struct hda_device_id
LoongArch: KVM: Add include defining struct cpu_feature
media: em28xx: Add include for struct usb_device_id
Replace <linux/mod_devicetable.h> by more specific
<linux/mod_device_id/*.h> (headers)
Replace <linux/mod_devicetable.h> by more specific
<linux/mod_device_id/*.h> (c files)
arch/arm/mach-omap2/board-generic.c | 1 -
arch/loongarch/kvm/main.c | 1 +
arch/mips/include/asm/cdmm.h | 2 +-
arch/mips/lantiq/xway/dcdc.c | 1 -
arch/mips/lantiq/xway/gptu.c | 1 -
arch/mips/lantiq/xway/vmmc.c | 1 -
arch/mips/pci/pci-rt2880.c | 1 -
arch/mips/ralink/timer.c | 1 -
arch/parisc/include/asm/hardware.h | 4 +-
arch/parisc/include/asm/parisc-device.h | 1 +
.../powerpc/platforms/83xx/mcu_mpc8349emitx.c | 1 -
arch/powerpc/platforms/86xx/common.c | 1 -
arch/powerpc/sysdev/fsl_lbc.c | 1 -
arch/powerpc/sysdev/fsl_pmc.c | 1 -
arch/s390/include/asm/ccwdev.h | 2 +-
arch/sh/drivers/platform_early.c | 2 +-
arch/sparc/crypto/crop_devid.c | 2 +-
arch/sparc/kernel/of_device_32.c | 1 -
arch/sparc/kernel/of_device_64.c | 1 -
arch/sparc/kernel/of_device_common.c | 1 -
arch/x86/include/asm/cpu_device_id.h | 5 +-
arch/x86/kvm/svm/svm.c | 1 -
arch/x86/kvm/vmx/vmx.c | 1 -
drivers/accel/ethosu/ethosu_drv.c | 1 -
drivers/accel/qaic/qaic_timesync.c | 1 -
drivers/accel/qaic/sahara.c | 1 -
drivers/ata/ahci_platform.c | 1 -
drivers/ata/ahci_sunxi.c | 1 -
drivers/ata/pata_buddha.c | 1 -
drivers/ata/pata_ep93xx.c | 1 -
drivers/ata/pata_imx.c | 1 -
drivers/auxdisplay/arm-charlcd.c | 1 -
drivers/auxdisplay/hd44780.c | 1 -
drivers/auxdisplay/lcd2s.c | 1 -
drivers/auxdisplay/max6959.c | 1 -
drivers/auxdisplay/seg-led-gpio.c | 1 -
drivers/block/floppy.c | 2 +-
drivers/bluetooth/hci_h5.c | 1 -
drivers/bluetooth/hci_qca.c | 1 -
drivers/bus/mhi/ep/main.c | 1 -
drivers/bus/mhi/host/init.c | 1 -
drivers/cache/hisi_soc_hha.c | 1 -
drivers/cdx/controller/cdx_controller.c | 1 -
drivers/char/hw_random/airoha-trng.c | 1 -
drivers/char/hw_random/atmel-rng.c | 1 -
drivers/char/hw_random/ba431-rng.c | 1 -
drivers/char/hw_random/bcm74110-rng.c | 1 -
drivers/char/hw_random/exynos-trng.c | 1 -
drivers/char/hw_random/histb-rng.c | 1 -
drivers/char/hw_random/imx-rngc.c | 1 -
drivers/char/hw_random/ingenic-trng.c | 1 -
drivers/char/hw_random/iproc-rng200.c | 1 -
drivers/char/hw_random/pasemi-rng.c | 1 -
drivers/char/hw_random/pic32-rng.c | 1 -
drivers/char/hw_random/powernv-rng.c | 1 -
drivers/char/hw_random/xgene-rng.c | 1 -
drivers/char/hw_random/xilinx-trng.c | 1 -
drivers/char/hw_random/xiphera-trng.c | 1 -
drivers/clk/aspeed/clk-ast2600.c | 1 -
drivers/clk/aspeed/clk-ast2700.c | 1 -
drivers/clk/clk-axi-clkgen.c | 1 -
drivers/clk/clk-bm1880.c | 1 -
drivers/clk/clk-cdce706.c | 1 -
drivers/clk/clk-eyeq.c | 1 -
drivers/clk/clk-renesas-pcie.c | 1 -
drivers/clk/clk-si521xx.c | 1 -
drivers/clk/clk-versaclock5.c | 1 -
drivers/clk/imx/clk-imx8mp-audiomix.c | 1 -
drivers/clk/mediatek/clk-mt2701-g3d.c | 1 -
drivers/clk/mediatek/clk-mt2701.c | 1 -
drivers/clk/mediatek/clk-mt2712.c | 1 -
drivers/clk/mediatek/clk-mt6765.c | 1 -
drivers/clk/mediatek/clk-mt6779-aud.c | 1 -
drivers/clk/mediatek/clk-mt7622-eth.c | 1 -
drivers/clk/mediatek/clk-mt7622-hif.c | 1 -
drivers/clk/mediatek/clk-mt7622.c | 1 -
drivers/clk/mediatek/clk-mt7629-hif.c | 1 -
drivers/clk/mediatek/clk-mt7981-apmixed.c | 1 -
drivers/clk/mediatek/clk-mt7981-eth.c | 1 -
drivers/clk/mediatek/clk-mt7981-infracfg.c | 1 -
drivers/clk/mediatek/clk-mt7981-topckgen.c | 1 -
drivers/clk/mediatek/clk-mt7986-apmixed.c | 1 -
drivers/clk/mediatek/clk-mt7986-eth.c | 1 -
drivers/clk/mediatek/clk-mt7986-infracfg.c | 1 -
drivers/clk/mediatek/clk-mt7986-topckgen.c | 1 -
drivers/clk/mediatek/clk-mt8167-aud.c | 1 -
drivers/clk/mediatek/clk-mt8167-img.c | 1 -
drivers/clk/mediatek/clk-mt8167-mfgcfg.c | 1 -
drivers/clk/mediatek/clk-mt8167-mm.c | 1 -
drivers/clk/mediatek/clk-mt8167-vdec.c | 1 -
drivers/clk/mediatek/clk-mt8173-mm.c | 1 -
drivers/clk/mediatek/clk-mt8183.c | 1 -
.../clk/mediatek/clk-mt8188-adsp_audio26m.c | 1 -
drivers/clk/mediatek/clk-mt8188-apmixedsys.c | 1 -
.../clk/mediatek/clk-mt8188-imp_iic_wrap.c | 1 -
drivers/clk/mediatek/clk-mt8188-topckgen.c | 1 -
drivers/clk/mediatek/clk-mt8188-vdo0.c | 1 -
drivers/clk/mediatek/clk-mt8188-vdo1.c | 1 -
drivers/clk/mediatek/clk-mt8188-venc.c | 1 -
drivers/clk/mediatek/clk-mt8188-wpe.c | 1 -
drivers/clk/mediatek/clk-mt8192-cam.c | 1 -
drivers/clk/mediatek/clk-mt8192-img.c | 1 -
.../clk/mediatek/clk-mt8192-imp_iic_wrap.c | 1 -
drivers/clk/mediatek/clk-mt8192-ipe.c | 1 -
drivers/clk/mediatek/clk-mt8192-mdp.c | 1 -
drivers/clk/mediatek/clk-mt8192-mfg.c | 1 -
drivers/clk/mediatek/clk-mt8192-msdc.c | 1 -
drivers/clk/mediatek/clk-mt8192-scp_adsp.c | 1 -
drivers/clk/mediatek/clk-mt8192-vdec.c | 1 -
drivers/clk/mediatek/clk-mt8192-venc.c | 1 -
drivers/clk/mediatek/clk-mt8192.c | 1 -
drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 1 -
drivers/clk/mediatek/clk-mt8195-topckgen.c | 1 -
drivers/clk/mediatek/clk-mt8365.c | 1 -
drivers/clk/mediatek/clk-mt8516-aud.c | 1 -
drivers/clk/meson/a1-peripherals.c | 1 -
drivers/clk/meson/a1-pll.c | 1 -
drivers/clk/meson/axg.c | 1 -
drivers/clk/meson/gxbb.c | 1 -
drivers/clk/qcom/cambistmclkcc-kaanapali.c | 1 -
drivers/clk/qcom/cambistmclkcc-sm8750.c | 1 -
drivers/clk/qcom/camcc-kaanapali.c | 1 -
drivers/clk/qcom/camcc-milos.c | 1 -
drivers/clk/qcom/camcc-qcs615.c | 1 -
drivers/clk/qcom/camcc-sa8775p.c | 1 -
drivers/clk/qcom/camcc-sc7180.c | 1 -
drivers/clk/qcom/camcc-sc7280.c | 1 -
drivers/clk/qcom/camcc-sc8180x.c | 1 -
drivers/clk/qcom/camcc-sc8280xp.c | 1 -
drivers/clk/qcom/camcc-sdm845.c | 1 -
drivers/clk/qcom/camcc-sm4450.c | 1 -
drivers/clk/qcom/camcc-sm6350.c | 1 -
drivers/clk/qcom/camcc-sm7150.c | 1 -
drivers/clk/qcom/camcc-sm8150.c | 1 -
drivers/clk/qcom/camcc-sm8250.c | 1 -
drivers/clk/qcom/camcc-sm8450.c | 1 -
drivers/clk/qcom/camcc-sm8550.c | 1 -
drivers/clk/qcom/camcc-sm8650.c | 1 -
drivers/clk/qcom/camcc-sm8750.c | 1 -
drivers/clk/qcom/camcc-x1e80100.c | 1 -
drivers/clk/qcom/dispcc-eliza.c | 1 -
drivers/clk/qcom/dispcc-glymur.c | 1 -
drivers/clk/qcom/dispcc-kaanapali.c | 1 -
drivers/clk/qcom/dispcc-milos.c | 1 -
drivers/clk/qcom/dispcc-qcm2290.c | 1 -
drivers/clk/qcom/dispcc-qcs615.c | 1 -
drivers/clk/qcom/dispcc-sc7180.c | 1 -
drivers/clk/qcom/dispcc-sc7280.c | 1 -
drivers/clk/qcom/dispcc-sc8280xp.c | 1 -
drivers/clk/qcom/dispcc-sdm845.c | 1 -
drivers/clk/qcom/dispcc-sm4450.c | 1 -
drivers/clk/qcom/dispcc-sm6115.c | 1 -
drivers/clk/qcom/dispcc-sm6125.c | 1 -
drivers/clk/qcom/dispcc-sm6350.c | 1 -
drivers/clk/qcom/dispcc-sm6375.c | 1 -
drivers/clk/qcom/dispcc-sm7150.c | 1 -
drivers/clk/qcom/dispcc-sm8250.c | 1 -
drivers/clk/qcom/dispcc-sm8450.c | 1 -
drivers/clk/qcom/dispcc-sm8550.c | 1 -
drivers/clk/qcom/dispcc-sm8750.c | 1 -
drivers/clk/qcom/dispcc-x1e80100.c | 1 -
drivers/clk/qcom/dispcc0-sa8775p.c | 1 -
drivers/clk/qcom/dispcc1-sa8775p.c | 1 -
drivers/clk/qcom/ecpricc-qdu1000.c | 1 -
drivers/clk/qcom/gcc-eliza.c | 1 -
drivers/clk/qcom/gcc-glymur.c | 1 -
drivers/clk/qcom/gcc-ipq5018.c | 1 -
drivers/clk/qcom/gcc-ipq5332.c | 1 -
drivers/clk/qcom/gcc-kaanapali.c | 1 -
drivers/clk/qcom/gcc-milos.c | 1 -
drivers/clk/qcom/gcc-nord.c | 1 -
drivers/clk/qcom/gcc-qcs615.c | 1 -
drivers/clk/qcom/gcc-qcs8300.c | 1 -
drivers/clk/qcom/gcc-sa8775p.c | 1 -
drivers/clk/qcom/gcc-sdx75.c | 1 -
drivers/clk/qcom/gcc-sm4450.c | 1 -
drivers/clk/qcom/gcc-sm7150.c | 1 -
drivers/clk/qcom/gcc-sm8650.c | 1 -
drivers/clk/qcom/gcc-sm8750.c | 1 -
drivers/clk/qcom/gcc-x1e80100.c | 1 -
drivers/clk/qcom/gpucc-glymur.c | 1 -
drivers/clk/qcom/gpucc-kaanapali.c | 1 -
drivers/clk/qcom/gpucc-milos.c | 1 -
drivers/clk/qcom/gpucc-msm8998.c | 1 -
drivers/clk/qcom/gpucc-qcm2290.c | 1 -
drivers/clk/qcom/gpucc-qcs615.c | 1 -
drivers/clk/qcom/gpucc-sa8775p.c | 1 -
drivers/clk/qcom/gpucc-sar2130p.c | 1 -
drivers/clk/qcom/gpucc-sc7180.c | 1 -
drivers/clk/qcom/gpucc-sc7280.c | 1 -
drivers/clk/qcom/gpucc-sc8280xp.c | 1 -
drivers/clk/qcom/gpucc-sdm660.c | 1 -
drivers/clk/qcom/gpucc-sdm845.c | 1 -
drivers/clk/qcom/gpucc-sm4450.c | 1 -
drivers/clk/qcom/gpucc-sm6115.c | 1 -
drivers/clk/qcom/gpucc-sm6125.c | 1 -
drivers/clk/qcom/gpucc-sm6350.c | 1 -
drivers/clk/qcom/gpucc-sm6375.c | 1 -
drivers/clk/qcom/gpucc-sm8150.c | 1 -
drivers/clk/qcom/gpucc-sm8250.c | 1 -
drivers/clk/qcom/gpucc-sm8350.c | 1 -
drivers/clk/qcom/gpucc-sm8450.c | 1 -
drivers/clk/qcom/gpucc-sm8550.c | 1 -
drivers/clk/qcom/gpucc-sm8650.c | 1 -
drivers/clk/qcom/gpucc-sm8750.c | 1 -
drivers/clk/qcom/gpucc-x1e80100.c | 1 -
drivers/clk/qcom/gpucc-x1p42100.c | 1 -
drivers/clk/qcom/gxclkctl-kaanapali.c | 1 -
drivers/clk/qcom/ipq-cmn-pll.c | 1 -
drivers/clk/qcom/lpasscc-sc8280xp.c | 1 -
drivers/clk/qcom/lpasscc-sm6115.c | 1 -
drivers/clk/qcom/mmcc-apq8084.c | 1 -
drivers/clk/qcom/mmcc-msm8960.c | 1 -
drivers/clk/qcom/mmcc-msm8974.c | 1 -
drivers/clk/qcom/mmcc-msm8994.c | 1 -
drivers/clk/qcom/mmcc-msm8996.c | 1 -
drivers/clk/qcom/mmcc-msm8998.c | 1 -
drivers/clk/qcom/mmcc-sdm660.c | 1 -
drivers/clk/qcom/negcc-nord.c | 1 -
drivers/clk/qcom/nwgcc-nord.c | 1 -
drivers/clk/qcom/segcc-nord.c | 1 -
drivers/clk/qcom/tcsrcc-eliza.c | 1 -
drivers/clk/qcom/tcsrcc-glymur.c | 1 -
drivers/clk/qcom/tcsrcc-nord.c | 1 -
drivers/clk/qcom/tcsrcc-sm8650.c | 1 -
drivers/clk/qcom/tcsrcc-sm8750.c | 1 -
drivers/clk/qcom/tcsrcc-x1e80100.c | 1 -
drivers/clk/qcom/videocc-glymur.c | 1 -
drivers/clk/qcom/videocc-kaanapali.c | 1 -
drivers/clk/qcom/videocc-milos.c | 1 -
drivers/clk/qcom/videocc-qcs615.c | 1 -
drivers/clk/qcom/videocc-sa8775p.c | 1 -
drivers/clk/qcom/videocc-sm7150.c | 1 -
drivers/clk/qcom/videocc-sm8450.c | 1 -
drivers/clk/qcom/videocc-sm8550.c | 1 -
drivers/clk/qcom/videocc-sm8750.c | 1 -
drivers/clk/renesas/clk-vbattb.c | 1 -
drivers/clk/renesas/renesas-cpg-mssr.c | 1 -
drivers/clk/renesas/rzg2l-cpg.c | 1 -
drivers/clk/renesas/rzv2h-cpg.c | 1 -
drivers/clk/samsung/clk-exynos-audss.c | 1 -
drivers/clk/samsung/clk-exynos-clkout.c | 1 -
drivers/clk/samsung/clk-exynos2200.c | 1 -
drivers/clk/samsung/clk-exynos3250.c | 1 -
drivers/clk/samsung/clk-exynos4.c | 1 -
drivers/clk/samsung/clk-exynos4412-isp.c | 1 -
drivers/clk/samsung/clk-exynos5-subcmu.c | 1 -
drivers/clk/samsung/clk-exynos5250.c | 1 -
drivers/clk/samsung/clk-exynos5420.c | 1 -
drivers/clk/samsung/clk-exynos5433.c | 1 -
drivers/clk/samsung/clk-exynos7870.c | 1 -
drivers/clk/samsung/clk-exynos7885.c | 1 -
drivers/clk/samsung/clk-exynos850.c | 1 -
drivers/clk/samsung/clk-exynos8895.c | 1 -
drivers/clk/samsung/clk-exynos990.c | 1 -
drivers/clk/samsung/clk-exynosautov9.c | 1 -
drivers/clk/samsung/clk-exynosautov920.c | 1 -
drivers/clk/samsung/clk-fsd.c | 1 -
drivers/clk/samsung/clk-gs101.c | 1 -
drivers/clk/samsung/clk-s5pv210-audss.c | 1 -
drivers/clk/samsung/clk.c | 1 -
drivers/clk/sprd/ums512-clk.c | 1 -
.../clk/starfive/clk-starfive-jh7100-audio.c | 1 -
drivers/clk/starfive/clk-starfive-jh7100.c | 1 -
drivers/clk/tegra/clk-device.c | 1 -
drivers/clk/xilinx/xlnx_vcu.c | 1 -
drivers/counter/interrupt-cnt.c | 1 -
drivers/counter/stm32-lptimer-cnt.c | 1 -
drivers/counter/stm32-timer-cnt.c | 1 -
drivers/counter/ti-ecap-capture.c | 1 -
drivers/counter/ti-eqep.c | 1 -
drivers/cpufreq/amd_freq_sensitivity.c | 1 -
drivers/cpufreq/armada-37xx-cpufreq.c | 1 -
drivers/crypto/atmel-aes.c | 1 -
drivers/crypto/atmel-sha.c | 1 -
drivers/crypto/atmel-tdes.c | 1 -
drivers/crypto/hifn_795x.c | 1 -
drivers/crypto/img-hash.c | 1 -
.../intel/keembay/keembay-ocs-hcu-core.c | 1 -
drivers/crypto/qce/core.c | 1 -
drivers/crypto/starfive/jh7110-cryp.c | 1 -
drivers/crypto/talitos.c | 1 -
drivers/crypto/tegra/tegra-se-main.c | 1 -
drivers/crypto/ti/dthev2-common.c | 1 -
drivers/crypto/xilinx/zynqmp-aes-gcm.c | 1 -
drivers/devfreq/hisi_uncore_freq.c | 1 -
drivers/devfreq/imx8m-ddrc.c | 1 -
drivers/dma/amd/qdma/qdma.c | 1 -
drivers/dma/ep93xx_dma.c | 1 -
drivers/dma/qcom/hidma.c | 1 -
drivers/dma/sf-pdma/sf-pdma.c | 1 -
drivers/dma/xgene-dma.c | 1 -
drivers/dma/xilinx/xdma.c | 1 -
drivers/dpll/zl3073x/dpll.c | 1 -
drivers/edac/fsl_ddr_edac.c | 1 -
drivers/edac/mpc85xx_edac.c | 1 -
drivers/edac/pnd2_edac.c | 1 -
drivers/edac/sb_edac.c | 1 -
drivers/extcon/extcon-intel-cht-wc.c | 1 -
drivers/extcon/extcon-intel-mrfld.c | 1 -
drivers/extcon/extcon-max14526.c | 1 -
drivers/extcon/extcon-max3355.c | 1 -
drivers/extcon/extcon-qcom-spmi-misc.c | 1 -
drivers/extcon/extcon-usb-gpio.c | 1 -
drivers/firewire/core-device.c | 1 -
drivers/firewire/net.c | 1 -
drivers/firewire/sbp2.c | 1 -
drivers/firmware/google/cbmem.c | 2 +-
drivers/firmware/google/coreboot_table.c | 2 +-
.../firmware/google/framebuffer-coreboot.c | 2 +-
drivers/firmware/google/memconsole-coreboot.c | 2 +-
drivers/firmware/google/vpd.c | 2 +-
drivers/firmware/qemu_fw_cfg.c | 1 -
drivers/fpga/altera-freeze-bridge.c | 1 -
drivers/fpga/altera-pr-ip-core-plat.c | 1 -
drivers/fpga/ice40-spi.c | 1 -
drivers/fpga/intel-m10-bmc-sec-update.c | 1 -
drivers/fpga/xilinx-selectmap.c | 1 -
drivers/fpga/xilinx-spi.c | 1 -
drivers/fsi/fsi-master-i2cr.c | 1 -
drivers/fsi/fsi-scom.c | 2 +-
drivers/fsi/i2cr-scom.c | 1 -
drivers/gpib/eastwood/fluke_gpib.c | 1 -
drivers/gpio/gpio-74xx-mmio.c | 1 -
drivers/gpio/gpio-adnp.c | 1 -
drivers/gpio/gpio-aggregator.c | 1 -
drivers/gpio/gpio-altera-a10sr.c | 2 +-
drivers/gpio/gpio-altera.c | 1 -
drivers/gpio/gpio-ath79.c | 1 -
drivers/gpio/gpio-bcm-kona.c | 1 -
drivers/gpio/gpio-by-pinctrl.c | 1 -
drivers/gpio/gpio-cros-ec.c | 1 -
drivers/gpio/gpio-dwapb.c | 1 -
drivers/gpio/gpio-en7523.c | 1 -
drivers/gpio/gpio-ge.c | 1 -
drivers/gpio/gpio-graniterapids.c | 1 -
drivers/gpio/gpio-hisi.c | 1 -
drivers/gpio/gpio-idt3243x.c | 1 -
drivers/gpio/gpio-latch.c | 1 -
drivers/gpio/gpio-line-mux.c | 1 -
drivers/gpio/gpio-ltc4283.c | 1 -
drivers/gpio/gpio-max7360.c | 1 -
drivers/gpio/gpio-max77759.c | 1 -
drivers/gpio/gpio-mb86s7x.c | 1 -
drivers/gpio/gpio-mlxbf2.c | 1 -
drivers/gpio/gpio-mmio.c | 1 -
drivers/gpio/gpio-mockup.c | 1 -
drivers/gpio/gpio-mpc8xxx.c | 1 -
drivers/gpio/gpio-mpfs.c | 1 -
drivers/gpio/gpio-nomadik.c | 1 -
drivers/gpio/gpio-pca953x.c | 1 -
drivers/gpio/gpio-pcf857x.c | 1 -
drivers/gpio/gpio-qixis-fpga.c | 1 -
drivers/gpio/gpio-realtek-otto.c | 1 -
drivers/gpio/gpio-shared-proxy.c | 1 -
drivers/gpio/gpio-sim.c | 1 -
drivers/gpio/gpio-sl28cpld.c | 1 -
drivers/gpio/gpio-sloppy-logic-analyzer.c | 1 -
drivers/gpio/gpio-sprd.c | 1 -
drivers/gpio/gpio-tn48m.c | 1 -
drivers/gpio/gpio-virtuser.c | 1 -
drivers/gpio/gpio-wcd934x.c | 1 -
drivers/gpio/gpio-xgene-sb.c | 1 -
drivers/gpio/gpio-xra1403.c | 1 -
drivers/gpio/gpio-zevio.c | 1 -
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 1 -
drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx.c | 1 -
drivers/gpu/drm/bridge/inno-hdmi.c | 1 -
drivers/gpu/drm/bridge/ssd2825.c | 1 -
drivers/gpu/drm/bridge/tc358762.c | 2 +-
drivers/gpu/drm/bridge/tc358764.c | 2 +-
drivers/gpu/drm/bridge/th1520-dw-hdmi.c | 1 -
drivers/gpu/drm/drm_panel_backlight_quirks.c | 1 -
drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 1 -
drivers/gpu/drm/exynos/exynos_drm_gsc.c | 1 -
drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 1 -
drivers/gpu/drm/imagination/pvr_drv.c | 1 -
drivers/gpu/drm/imx/dc/dc-cf.c | 1 -
drivers/gpu/drm/imx/dc/dc-de.c | 1 -
drivers/gpu/drm/imx/dc/dc-drv.c | 1 -
drivers/gpu/drm/imx/dc/dc-ed.c | 1 -
drivers/gpu/drm/imx/dc/dc-fg.c | 1 -
drivers/gpu/drm/imx/dc/dc-fl.c | 1 -
drivers/gpu/drm/imx/dc/dc-fw.c | 1 -
drivers/gpu/drm/imx/dc/dc-lb.c | 1 -
drivers/gpu/drm/imx/dc/dc-pe.c | 1 -
drivers/gpu/drm/imx/dc/dc-tc.c | 1 -
drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 1 -
drivers/gpu/drm/mediatek/mtk_cec.c | 1 -
drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 1 -
drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 1 -
drivers/gpu/drm/mxsfb/mxsfb_drv.c | 1 -
drivers/gpu/drm/panel/panel-arm-versatile.c | 1 -
drivers/gpu/drm/panel/panel-auo-a030jtn01.c | 1 -
drivers/gpu/drm/panel/panel-boe-td4320.c | 2 +-
.../gpu/drm/panel/panel-feixin-k101-im2ba02.c | 2 +-
.../drm/panel/panel-feiyang-fy07024di26a30d.c | 2 +-
drivers/gpu/drm/panel/panel-himax-hx83112b.c | 1 -
drivers/gpu/drm/panel/panel-himax-hx83121a.c | 1 -
drivers/gpu/drm/panel/panel-himax-hx8394.c | 1 -
drivers/gpu/drm/panel/panel-hydis-hv101hd1.c | 2 +-
drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1 -
.../gpu/drm/panel/panel-ilitek-ili9806e-dsi.c | 1 -
drivers/gpu/drm/panel/panel-lg-ld070wx3.c | 2 +-
drivers/gpu/drm/panel/panel-motorola-mot.c | 2 +-
drivers/gpu/drm/panel/panel-novatek-nt35532.c | 2 +-
drivers/gpu/drm/panel/panel-novatek-nt37801.c | 1 -
.../gpu/drm/panel/panel-orisetech-otm8009a.c | 1 -
drivers/gpu/drm/panel/panel-raydium-rm67200.c | 2 +-
drivers/gpu/drm/panel/panel-raydium-rm68200.c | 2 +-
drivers/gpu/drm/panel/panel-renesas-r61307.c | 2 +-
drivers/gpu/drm/panel/panel-renesas-r69328.c | 2 +-
.../gpu/drm/panel/panel-samsung-ltl106hl02.c | 2 +-
drivers/gpu/drm/panel/panel-samsung-s6d16d0.c | 2 +-
.../gpu/drm/panel/panel-samsung-s6e63j0x03.c | 1 -
.../gpu/drm/panel/panel-samsung-s6e63m0-dsi.c | 2 +-
.../panel/panel-samsung-s6e88a0-ams427ap24.c | 1 -
.../drm/panel/panel-samsung-s6e8fc0-m1906f9.c | 1 -
drivers/gpu/drm/panel/panel-sitronix-st7703.c | 1 -
drivers/gpu/drm/panel/panel-summit.c | 1 -
.../gpu/drm/panel/panel-visionox-rm69299.c | 1 -
.../gpu/drm/panel/panel-visionox-rm692e5.c | 1 -
.../gpu/drm/renesas/rcar-du/rcar_dw_hdmi.c | 1 -
.../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 1 -
drivers/gpu/drm/rockchip/inno_hdmi-rockchip.c | 1 -
drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 1 -
drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 1 -
drivers/gpu/drm/sprd/sprd_drm.c | 1 -
drivers/gpu/drm/sti/sti_hda.c | 1 -
drivers/gpu/drm/stm/drv.c | 1 -
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 1 -
drivers/gpu/drm/sun4i/sun6i_drc.c | 1 -
drivers/gpu/drm/tilcdc/tilcdc_drv.c | 1 -
drivers/gpu/drm/tiny/sharp-memory.c | 1 -
drivers/gpu/drm/vc4/vc4_dpi.c | 1 -
drivers/gpu/drm/vc4/vc4_txp.c | 1 -
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 1 -
drivers/hid/intel-ish-hid/ishtp/bus.h | 2 +-
drivers/hsi/controllers/omap_ssi_port.c | 1 -
drivers/hte/hte-tegra194-test.c | 1 -
drivers/hwmon/adcxx.c | 1 -
drivers/hwmon/adt7410.c | 1 -
drivers/hwmon/adt7462.c | 1 -
drivers/hwmon/adt7475.c | 1 -
drivers/hwmon/as370-hwmon.c | 1 -
drivers/hwmon/axi-fan-control.c | 1 -
drivers/hwmon/cros_ec_hwmon.c | 1 -
drivers/hwmon/gxp-fan-ctrl.c | 1 -
drivers/hwmon/iio_hwmon.c | 1 -
drivers/hwmon/intel-m10-bmc-hwmon.c | 1 -
drivers/hwmon/jc42.c | 1 -
drivers/hwmon/lan966x-hwmon.c | 1 -
drivers/hwmon/lm70.c | 1 -
drivers/hwmon/lm75.c | 1 -
drivers/hwmon/ltc2947-core.c | 1 -
drivers/hwmon/ltc4282.c | 1 -
drivers/hwmon/ltc4283.c | 1 -
drivers/hwmon/ltq-cputemp.c | 1 -
drivers/hwmon/max197.c | 1 -
drivers/hwmon/mc13783-adc.c | 1 -
drivers/hwmon/mr75203.c | 1 -
drivers/hwmon/ntc_thermistor.c | 1 -
drivers/hwmon/occ/p9_sbe.c | 1 -
drivers/hwmon/pmbus/adp1050.c | 1 -
drivers/hwmon/pmbus/e50sn12051.c | 1 -
drivers/hwmon/pmbus/lt3074.c | 1 -
drivers/hwmon/pmbus/max17616.c | 1 -
drivers/hwmon/pmbus/max20830.c | 1 -
drivers/hwmon/pmbus/mp2975.c | 1 -
drivers/hwmon/pmbus/stef48h28.c | 1 -
drivers/hwmon/pwm-fan.c | 1 -
drivers/hwmon/sch5627.c | 1 -
drivers/hwmon/sch5636.c | 1 -
drivers/hwmon/sl28cpld-hwmon.c | 1 -
drivers/hwmon/smpro-hwmon.c | 1 -
drivers/hwmon/sparx5-temp.c | 1 -
drivers/hwmon/tmp102.c | 1 -
drivers/hwmon/tmp108.c | 1 -
drivers/hwtracing/coresight/ultrasoc-smb.c | 1 -
drivers/i2c/busses/i2c-amd-asf-plat.c | 1 -
drivers/i2c/busses/i2c-gxp.c | 1 -
drivers/i2c/busses/i2c-hisi.c | 1 -
drivers/i2c/busses/i2c-rtl9300.c | 1 -
drivers/i2c/busses/i2c-rzv2m.c | 1 -
drivers/i2c/i2c-core.h | 1 +
drivers/iio/accel/adxl313_i2c.c | 1 -
drivers/iio/accel/adxl313_spi.c | 1 -
drivers/iio/accel/adxl355_core.c | 1 -
drivers/iio/accel/adxl355_i2c.c | 1 -
drivers/iio/accel/adxl355_spi.c | 1 -
drivers/iio/accel/adxl367.c | 1 -
drivers/iio/accel/adxl367_i2c.c | 1 -
drivers/iio/accel/adxl367_spi.c | 1 -
drivers/iio/accel/adxl372_i2c.c | 1 -
drivers/iio/accel/adxl372_spi.c | 1 -
drivers/iio/accel/adxl380_i2c.c | 1 -
drivers/iio/accel/adxl380_spi.c | 1 -
drivers/iio/accel/bma180.c | 1 -
drivers/iio/accel/bma220_core.c | 1 -
drivers/iio/accel/bma220_i2c.c | 1 -
drivers/iio/accel/bma220_spi.c | 1 -
drivers/iio/accel/bma400_i2c.c | 1 -
drivers/iio/accel/bma400_spi.c | 1 -
drivers/iio/accel/bmc150-accel-i2c.c | 1 -
drivers/iio/accel/bmc150-accel-spi.c | 1 -
drivers/iio/accel/bmi088-accel-i2c.c | 1 -
drivers/iio/accel/dmard06.c | 1 -
drivers/iio/accel/fxls8962af-core.c | 1 -
drivers/iio/accel/fxls8962af-i2c.c | 1 -
drivers/iio/accel/fxls8962af-spi.c | 1 -
drivers/iio/accel/hid-sensor-accel-3d.c | 1 -
drivers/iio/accel/kxcjk-1013.c | 1 -
drivers/iio/accel/kxsd9-i2c.c | 1 -
drivers/iio/accel/kxsd9-spi.c | 1 -
drivers/iio/accel/mma7660.c | 1 -
drivers/iio/accel/mma8452.c | 1 -
drivers/iio/accel/mma9551.c | 1 -
drivers/iio/accel/mma9553.c | 1 -
drivers/iio/accel/msa311.c | 1 -
drivers/iio/accel/mxc4005.c | 1 -
drivers/iio/accel/mxc6255.c | 1 -
drivers/iio/accel/st_accel_i2c.c | 1 -
drivers/iio/accel/st_accel_spi.c | 1 -
drivers/iio/accel/stk8ba50.c | 1 -
drivers/iio/adc/88pm886-gpadc.c | 1 -
drivers/iio/adc/ad4000.c | 1 -
drivers/iio/adc/ad4080.c | 1 -
drivers/iio/adc/ad4134.c | 1 -
drivers/iio/adc/ad4851.c | 1 -
drivers/iio/adc/ad7124.c | 1 -
drivers/iio/adc/ad7173.c | 1 -
drivers/iio/adc/ad7191.c | 1 -
drivers/iio/adc/ad7192.c | 1 -
drivers/iio/adc/ad7280a.c | 1 -
drivers/iio/adc/ad7292.c | 1 -
drivers/iio/adc/ad7298.c | 1 -
drivers/iio/adc/ad7405.c | 1 -
drivers/iio/adc/ad7606_par.c | 1 -
drivers/iio/adc/ad7625.c | 1 -
drivers/iio/adc/ad7779.c | 1 -
drivers/iio/adc/adi-axi-adc.c | 1 -
drivers/iio/adc/at91-sama5d2_adc.c | 1 -
drivers/iio/adc/axp20x_adc.c | 1 -
drivers/iio/adc/bcm_iproc_adc.c | 1 -
drivers/iio/adc/berlin2-adc.c | 1 -
drivers/iio/adc/cpcap-adc.c | 1 -
drivers/iio/adc/envelope-detector.c | 1 -
drivers/iio/adc/fsl-imx25-gcq.c | 1 -
drivers/iio/adc/hi8435.c | 1 -
drivers/iio/adc/hx711.c | 1 -
drivers/iio/adc/imx7d_adc.c | 1 -
drivers/iio/adc/imx8qxp-adc.c | 1 -
drivers/iio/adc/imx93_adc.c | 1 -
drivers/iio/adc/ingenic-adc.c | 1 -
drivers/iio/adc/intel_dc_ti_adc.c | 1 -
drivers/iio/adc/intel_mrfld_adc.c | 1 -
drivers/iio/adc/lpc18xx_adc.c | 1 -
drivers/iio/adc/lpc32xx_adc.c | 1 -
drivers/iio/adc/ltc2496.c | 1 -
drivers/iio/adc/ltc2497.c | 1 -
drivers/iio/adc/max1027.c | 1 -
drivers/iio/adc/max11100.c | 1 -
drivers/iio/adc/max1118.c | 1 -
drivers/iio/adc/max1363.c | 1 -
drivers/iio/adc/max14001.c | 1 -
drivers/iio/adc/max34408.c | 1 -
drivers/iio/adc/max77541-adc.c | 1 -
drivers/iio/adc/max9611.c | 1 -
drivers/iio/adc/mcp320x.c | 1 -
drivers/iio/adc/mcp3422.c | 1 -
drivers/iio/adc/mcp3911.c | 1 -
drivers/iio/adc/mp2629_adc.c | 1 -
drivers/iio/adc/mt6359-auxadc.c | 1 -
drivers/iio/adc/mt6360-adc.c | 1 -
drivers/iio/adc/mt6370-adc.c | 1 -
drivers/iio/adc/mt6577_auxadc.c | 1 -
drivers/iio/adc/nau7802.c | 1 -
drivers/iio/adc/nct7201.c | 1 -
drivers/iio/adc/npcm_adc.c | 1 -
drivers/iio/adc/nxp-sar-adc.c | 1 -
drivers/iio/adc/qcom-pm8xxx-xoadc.c | 1 -
drivers/iio/adc/qcom-spmi-adc5-gen3.c | 1 -
drivers/iio/adc/qcom-spmi-adc5.c | 1 -
drivers/iio/adc/qcom-spmi-rradc.c | 1 -
drivers/iio/adc/qcom-spmi-vadc.c | 1 -
drivers/iio/adc/rohm-bd79112.c | 1 -
drivers/iio/adc/rohm-bd79124.c | 1 -
drivers/iio/adc/rtq6056.c | 1 -
drivers/iio/adc/rzg2l_adc.c | 1 -
drivers/iio/adc/rzn1-adc.c | 1 -
drivers/iio/adc/rzt2h_adc.c | 1 -
drivers/iio/adc/sd_adc_modulator.c | 1 -
drivers/iio/adc/sophgo-cv1800b-adc.c | 1 -
drivers/iio/adc/spear_adc.c | 1 -
drivers/iio/adc/stm32-adc.c | 1 -
drivers/iio/adc/sun20i-gpadc-iio.c | 1 -
drivers/iio/adc/ti-adc081c.c | 1 -
drivers/iio/adc/ti-adc0832.c | 1 -
drivers/iio/adc/ti-adc084s021.c | 1 -
drivers/iio/adc/ti-adc108s102.c | 1 -
drivers/iio/adc/ti-adc128s052.c | 1 -
drivers/iio/adc/ti-adc161s626.c | 1 -
drivers/iio/adc/ti-ads1018.c | 1 -
drivers/iio/adc/ti-ads124s08.c | 1 -
drivers/iio/adc/ti-ads131m02.c | 1 -
drivers/iio/adc/ti-ads8688.c | 1 -
drivers/iio/adc/ti-tlc4541.c | 1 -
drivers/iio/adc/twl4030-madc.c | 1 -
drivers/iio/adc/twl6030-gpadc.c | 1 -
drivers/iio/adc/vf610_adc.c | 1 -
drivers/iio/adc/xilinx-ams.c | 1 -
drivers/iio/adc/xilinx-xadc-core.c | 1 -
drivers/iio/addac/ad74413r.c | 1 -
drivers/iio/afe/iio-rescale.c | 1 -
drivers/iio/amplifiers/ad8366.c | 1 -
drivers/iio/amplifiers/adl8113.c | 1 -
drivers/iio/amplifiers/hmc425a.c | 1 -
drivers/iio/cdc/ad7150.c | 1 -
drivers/iio/chemical/ams-iaq-core.c | 1 -
drivers/iio/chemical/atlas-ezo-sensor.c | 1 -
drivers/iio/chemical/atlas-sensor.c | 1 -
drivers/iio/chemical/bme680_spi.c | 1 -
drivers/iio/chemical/mhz19b.c | 1 -
drivers/iio/chemical/pms7003.c | 1 -
drivers/iio/chemical/scd30_i2c.c | 1 -
drivers/iio/chemical/scd30_serial.c | 1 -
drivers/iio/chemical/sgp30.c | 1 -
drivers/iio/chemical/sps30_i2c.c | 1 -
drivers/iio/chemical/sps30_serial.c | 1 -
drivers/iio/chemical/sunrise_co2.c | 1 -
drivers/iio/chemical/vz89x.c | 1 -
.../cros_ec_sensors/cros_ec_lid_angle.c | 1 -
.../common/cros_ec_sensors/cros_ec_sensors.c | 1 -
drivers/iio/common/ssp_sensors/ssp_dev.c | 1 -
drivers/iio/dac/ad3530r.c | 1 -
drivers/iio/dac/ad3552r-hs.c | 1 -
drivers/iio/dac/ad5446-i2c.c | 1 -
drivers/iio/dac/ad5446-spi.c | 1 -
drivers/iio/dac/ad5592r.c | 1 -
drivers/iio/dac/ad5593r.c | 1 -
drivers/iio/dac/ad5758.c | 1 -
drivers/iio/dac/ad7293.c | 1 -
drivers/iio/dac/ad7303.c | 1 -
drivers/iio/dac/ad8460.c | 1 -
drivers/iio/dac/ad9739a.c | 1 -
drivers/iio/dac/adi-axi-dac.c | 1 -
drivers/iio/dac/dpot-dac.c | 1 -
drivers/iio/dac/lpc18xx_dac.c | 1 -
drivers/iio/dac/ltc2664.c | 1 -
drivers/iio/dac/ltc2688.c | 1 -
drivers/iio/dac/max22007.c | 1 -
drivers/iio/dac/max5522.c | 1 -
drivers/iio/dac/mcp4725.c | 1 -
drivers/iio/dac/mcp4728.c | 1 -
drivers/iio/dac/mcp47feb02.c | 1 -
drivers/iio/dac/mcp4821.c | 1 -
drivers/iio/dac/stm32-dac-core.c | 1 -
drivers/iio/dac/stm32-dac.c | 1 -
drivers/iio/dac/ti-dac082s085.c | 1 -
drivers/iio/dac/ti-dac5571.c | 1 -
drivers/iio/dac/vf610_dac.c | 1 -
drivers/iio/filter/admv8818.c | 1 -
drivers/iio/frequency/adf4350.c | 1 -
drivers/iio/frequency/admfm2000.c | 1 -
drivers/iio/frequency/admv1013.c | 1 -
drivers/iio/frequency/admv1014.c | 1 -
drivers/iio/frequency/adrf6780.c | 1 -
drivers/iio/gyro/bmg160_i2c.c | 1 -
drivers/iio/gyro/fxas21002c_i2c.c | 1 -
drivers/iio/gyro/fxas21002c_spi.c | 1 -
drivers/iio/gyro/hid-sensor-gyro-3d.c | 1 -
drivers/iio/gyro/st_gyro_i2c.c | 1 -
drivers/iio/gyro/st_gyro_spi.c | 1 -
drivers/iio/health/max30102.c | 1 -
drivers/iio/humidity/dht11.c | 1 -
drivers/iio/humidity/ens210.c | 1 -
drivers/iio/humidity/hdc100x.c | 1 -
drivers/iio/humidity/hid-sensor-humidity.c | 1 -
drivers/iio/humidity/hts221_i2c.c | 1 -
drivers/iio/humidity/htu21.c | 1 -
drivers/iio/humidity/si7020.c | 1 -
drivers/iio/imu/adis16475.c | 1 -
drivers/iio/imu/adis16480.c | 1 -
drivers/iio/imu/adis16550.c | 1 -
drivers/iio/imu/bmi160/bmi160_i2c.c | 1 -
drivers/iio/imu/bmi160/bmi160_spi.c | 1 -
drivers/iio/imu/bmi270/bmi270_i2c.c | 1 -
drivers/iio/imu/bmi270/bmi270_spi.c | 1 -
drivers/iio/imu/bmi323/bmi323_i2c.c | 1 -
drivers/iio/imu/bmi323/bmi323_spi.c | 1 -
drivers/iio/imu/bno055/bno055_i2c.c | 1 -
drivers/iio/imu/bno055/bno055_ser_core.c | 1 -
drivers/iio/imu/fxos8700_i2c.c | 1 -
drivers/iio/imu/fxos8700_spi.c | 1 -
.../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 1 -
.../iio/imu/inv_icm42600/inv_icm42600_spi.c | 1 -
.../iio/imu/inv_icm45600/inv_icm45600_i2c.c | 1 -
.../iio/imu/inv_icm45600/inv_icm45600_i3c.c | 1 -
.../iio/imu/inv_icm45600/inv_icm45600_spi.c | 1 -
drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 1 -
drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 1 -
drivers/iio/imu/kmx61.c | 1 -
drivers/iio/imu/smi330/smi330_i2c.c | 1 -
drivers/iio/imu/smi330/smi330_spi.c | 1 -
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i3c.c | 1 -
drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_i2c.c | 1 -
drivers/iio/imu/st_lsm9ds0/st_lsm9ds0_spi.c | 1 -
drivers/iio/light/al3000a.c | 1 -
drivers/iio/light/al3010.c | 1 -
drivers/iio/light/al3320a.c | 1 -
drivers/iio/light/bh1780.c | 1 -
drivers/iio/light/cm32181.c | 1 -
drivers/iio/light/cm3232.c | 1 -
drivers/iio/light/cm3605.c | 1 -
drivers/iio/light/cros_ec_light_prox.c | 1 -
drivers/iio/light/gp2ap020a00f.c | 1 -
drivers/iio/light/hid-sensor-als.c | 1 -
drivers/iio/light/hid-sensor-prox.c | 1 -
drivers/iio/light/isl29018.c | 1 -
drivers/iio/light/jsa1212.c | 1 -
drivers/iio/light/ltr501.c | 1 -
drivers/iio/light/ltrf216a.c | 1 -
drivers/iio/light/max44000.c | 1 -
drivers/iio/light/opt3001.c | 1 -
drivers/iio/light/rpr0521.c | 1 -
drivers/iio/light/st_uvis25_i2c.c | 1 -
drivers/iio/light/st_uvis25_spi.c | 1 -
drivers/iio/light/stk3310.c | 1 -
drivers/iio/light/tsl2563.c | 1 -
drivers/iio/light/us5182d.c | 1 -
drivers/iio/light/veml6046x00.c | 1 -
drivers/iio/light/vl6180.c | 1 -
drivers/iio/magnetometer/ak8974.c | 1 -
drivers/iio/magnetometer/ak8975.c | 1 -
drivers/iio/magnetometer/bmc150_magn_i2c.c | 1 -
drivers/iio/magnetometer/bmc150_magn_spi.c | 1 -
drivers/iio/magnetometer/hid-sensor-magn-3d.c | 1 -
drivers/iio/magnetometer/mmc35240.c | 1 -
drivers/iio/magnetometer/mmc5633.c | 1 -
drivers/iio/magnetometer/si7210.c | 1 -
drivers/iio/magnetometer/st_magn_i2c.c | 1 -
drivers/iio/magnetometer/st_magn_spi.c | 1 -
drivers/iio/magnetometer/tlv493d.c | 1 -
drivers/iio/magnetometer/yamaha-yas530.c | 1 -
drivers/iio/multiplexer/iio-mux.c | 1 -
drivers/iio/orientation/hid-sensor-incl-3d.c | 1 -
drivers/iio/orientation/hid-sensor-rotation.c | 1 -
.../position/hid-sensor-custom-intel-hinge.c | 1 -
drivers/iio/potentiometer/ad5272.c | 1 -
drivers/iio/potentiometer/ds1803.c | 1 -
drivers/iio/potentiometer/max5432.c | 1 -
drivers/iio/potentiometer/max5481.c | 1 -
drivers/iio/potentiometer/max5487.c | 1 -
drivers/iio/potentiometer/mcp4018.c | 1 -
drivers/iio/potentiometer/mcp41010.c | 1 -
drivers/iio/potentiometer/mcp4131.c | 1 -
drivers/iio/potentiometer/mcp4531.c | 1 -
drivers/iio/potentiostat/lmp91000.c | 1 -
drivers/iio/pressure/abp2030pa_i2c.c | 1 -
drivers/iio/pressure/abp2030pa_spi.c | 1 -
drivers/iio/pressure/adp810.c | 1 -
drivers/iio/pressure/cros_ec_baro.c | 1 -
drivers/iio/pressure/hid-sensor-press.c | 1 -
drivers/iio/pressure/hp206c.c | 1 -
drivers/iio/pressure/hsc030pa.c | 1 -
drivers/iio/pressure/hsc030pa_i2c.c | 1 -
drivers/iio/pressure/hsc030pa_spi.c | 1 -
drivers/iio/pressure/icp10100.c | 1 -
drivers/iio/pressure/mprls0025pa.c | 1 -
drivers/iio/pressure/mprls0025pa_i2c.c | 1 -
drivers/iio/pressure/mprls0025pa_spi.c | 1 -
drivers/iio/pressure/ms5611_i2c.c | 1 -
drivers/iio/pressure/ms5611_spi.c | 1 -
drivers/iio/pressure/ms5637.c | 1 -
drivers/iio/pressure/sdp500.c | 1 -
drivers/iio/pressure/st_pressure_i2c.c | 1 -
drivers/iio/pressure/st_pressure_spi.c | 1 -
drivers/iio/pressure/zpa2326_i2c.c | 1 -
drivers/iio/pressure/zpa2326_spi.c | 1 -
drivers/iio/proximity/as3935.c | 1 -
.../iio/proximity/cros_ec_mkbp_proximity.c | 1 -
drivers/iio/proximity/d3323aa.c | 1 -
drivers/iio/proximity/hx9023s.c | 1 -
drivers/iio/proximity/isl29501.c | 1 -
drivers/iio/proximity/mb1232.c | 1 -
drivers/iio/proximity/ping.c | 1 -
.../iio/proximity/pulsedlight-lidar-lite-v2.c | 1 -
drivers/iio/proximity/srf04.c | 1 -
drivers/iio/proximity/sx9310.c | 1 -
drivers/iio/proximity/sx9324.c | 1 -
drivers/iio/proximity/sx9360.c | 1 -
drivers/iio/proximity/vl53l1x-i2c.c | 1 -
drivers/iio/resolver/ad2s1200.c | 1 -
.../iio/temperature/hid-sensor-temperature.c | 1 -
drivers/iio/temperature/ltc2983.c | 1 -
drivers/iio/temperature/max31856.c | 1 -
drivers/iio/temperature/max31865.c | 1 -
drivers/iio/temperature/maxim_thermocouple.c | 1 -
drivers/iio/temperature/mcp9600.c | 1 -
drivers/iio/temperature/mlx90614.c | 1 -
drivers/iio/temperature/mlx90632.c | 1 -
drivers/iio/temperature/mlx90635.c | 1 -
drivers/iio/temperature/tmp006.c | 1 -
drivers/iio/temperature/tmp007.c | 1 -
drivers/iio/temperature/tsys01.c | 1 -
drivers/iio/trigger/stm32-lptimer-trigger.c | 1 -
drivers/iio/trigger/stm32-timer-trigger.c | 1 -
drivers/input/keyboard/adp5585-keys.c | 1 -
drivers/input/keyboard/adp5588-keys.c | 1 -
drivers/input/keyboard/charlieplex_keypad.c | 1 -
drivers/input/keyboard/clps711x-keypad.c | 1 -
drivers/input/keyboard/ep93xx_keypad.c | 1 -
drivers/input/keyboard/max7360-keypad.c | 1 -
drivers/input/keyboard/pinephone-keyboard.c | 1 -
drivers/input/misc/ariel-pwrbutton.c | 1 -
drivers/input/misc/da9063_onkey.c | 1 -
drivers/input/misc/gpio_decoder.c | 1 -
drivers/input/misc/iqs269a.c | 1 -
drivers/input/misc/iqs626a.c | 1 -
drivers/input/misc/iqs7222.c | 1 -
drivers/input/misc/mma8450.c | 1 -
drivers/input/misc/rt5120-pwrkey.c | 1 -
drivers/input/misc/sc27xx-vibra.c | 1 -
drivers/input/misc/twl4030-pwrbutton.c | 1 -
drivers/input/serio/sun4i-ps2.c | 1 -
drivers/input/serio/xilinx_ps2.c | 1 -
drivers/input/touchscreen/cyttsp5.c | 1 -
drivers/input/touchscreen/himax_hx852x.c | 1 -
drivers/input/touchscreen/hynitron_cstxxx.c | 1 -
drivers/input/touchscreen/ili210x.c | 1 -
drivers/input/touchscreen/iqs5xx.c | 1 -
drivers/input/touchscreen/msg2638.c | 1 -
.../input/touchscreen/resistive-adc-touch.c | 1 -
drivers/input/touchscreen/tsc2007_core.c | 1 -
drivers/interconnect/mediatek/mt8183.c | 1 -
drivers/interconnect/mediatek/mt8195.c | 1 -
drivers/interconnect/mediatek/mt8196.c | 1 -
drivers/interconnect/qcom/msm8909.c | 1 -
drivers/interconnect/qcom/msm8937.c | 1 -
drivers/interconnect/qcom/msm8939.c | 1 -
drivers/interconnect/qcom/msm8953.c | 1 -
drivers/interconnect/qcom/msm8976.c | 1 -
drivers/interconnect/qcom/msm8996.c | 1 -
drivers/interconnect/qcom/qcm2290.c | 1 -
drivers/interconnect/qcom/qcs404.c | 1 -
drivers/interconnect/qcom/qdu1000.c | 1 -
drivers/interconnect/qcom/sa8775p.c | 1 -
drivers/interconnect/qcom/sc7180.c | 1 -
drivers/interconnect/qcom/sc7280.c | 1 -
drivers/interconnect/qcom/sc8180x.c | 1 -
drivers/interconnect/qcom/sc8280xp.c | 1 -
drivers/interconnect/qcom/sdm660.c | 1 -
drivers/interconnect/qcom/sdm670.c | 1 -
drivers/interconnect/qcom/sdm845.c | 1 -
drivers/interconnect/qcom/sdx55.c | 1 -
drivers/interconnect/qcom/sdx65.c | 1 -
drivers/interconnect/qcom/sm6115.c | 1 -
drivers/interconnect/qcom/sm6350.c | 1 -
drivers/interconnect/qcom/sm7150.c | 1 -
drivers/interconnect/qcom/sm8150.c | 1 -
drivers/interconnect/qcom/sm8250.c | 1 -
drivers/interconnect/qcom/sm8350.c | 1 -
drivers/interconnect/qcom/sm8450.c | 1 -
drivers/interconnect/qcom/sm8550.c | 1 -
.../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c | 1 -
drivers/irqchip/irq-imx-intmux.c | 1 -
drivers/irqchip/irq-lan966x-oic.c | 1 -
drivers/irqchip/irq-sl28cpld.c | 1 -
drivers/irqchip/irq-stm32mp-exti.c | 1 -
drivers/leds/flash/leds-rt8515.c | 1 -
drivers/leds/leds-aw200xx.c | 1 -
drivers/leds/leds-bd2606mvv.c | 1 -
drivers/leds/leds-cht-wcove.c | 1 -
drivers/leds/leds-cr0014114.c | 1 -
drivers/leds/leds-cros_ec.c | 1 -
drivers/leds/leds-el15203000.c | 1 -
drivers/leds/leds-gpio.c | 1 -
drivers/leds/leds-is31fl319x.c | 1 -
drivers/leds/leds-lm36274.c | 1 -
drivers/leds/leds-lm3692x.c | 1 -
drivers/leds/leds-lm3697.c | 1 -
drivers/leds/leds-lp50xx.c | 1 -
drivers/leds/leds-lt3593.c | 1 -
drivers/leds/leds-max5970.c | 1 -
drivers/leds/leds-mlxcpld.c | 1 -
drivers/leds/leds-nic78bx.c | 1 -
drivers/leds/leds-pca995x.c | 1 -
drivers/leds/leds-regulator.c | 1 -
drivers/leds/leds-spi-byte.c | 1 -
drivers/leds/leds-sun50i-a100.c | 1 -
drivers/leds/rgb/leds-group-multicolor.c | 1 -
drivers/leds/rgb/leds-mt6370-rgb.c | 1 -
drivers/leds/rgb/leds-pwm-multicolor.c | 1 -
drivers/mailbox/mailbox-mpfs.c | 1 -
drivers/mailbox/platform_mhu.c | 1 -
.../media/cec/platform/cros-ec/cros-ec-cec.c | 1 -
drivers/media/firewire/firedtv-fw.c | 1 -
drivers/media/i2c/adv7180.c | 1 -
drivers/media/i2c/cvs/core.c | 1 -
drivers/media/i2c/gc0308.c | 1 -
drivers/media/i2c/gc05a2.c | 1 -
drivers/media/i2c/gc08a3.c | 1 -
drivers/media/i2c/lm3560.c | 1 -
drivers/media/i2c/mt9m114.c | 1 -
drivers/media/i2c/mt9p031.c | 1 -
drivers/media/i2c/mt9v032.c | 1 -
drivers/media/i2c/ov2680.c | 1 -
drivers/media/i2c/ov5640.c | 1 -
drivers/media/i2c/ov5670.c | 1 -
drivers/media/i2c/ov5675.c | 1 -
drivers/media/i2c/ov64a40.c | 1 -
drivers/media/i2c/ov7251.c | 1 -
drivers/media/i2c/ov7670.c | 1 -
drivers/media/i2c/ov8865.c | 1 -
drivers/media/i2c/t4ka3.c | 1 -
drivers/media/i2c/tvp514x.c | 1 -
drivers/media/i2c/video-i2c.c | 1 -
.../platform/arm/mali-c55/mali-c55-core.c | 1 -
.../platform/chips-media/coda/imx-vdoa.c | 1 -
.../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 1 -
.../platform/microchip/microchip-csi2dc.c | 1 -
drivers/media/platform/qcom/venus/vdec.c | 1 -
drivers/media/platform/qcom/venus/venc.c | 1 -
drivers/media/platform/renesas/rcar-fcp.c | 1 -
.../platform/renesas/rzg2l-cru/rzg2l-core.c | 1 -
drivers/media/platform/st/sti/hva/hva-v4l2.c | 1 -
.../media/platform/sunxi/sun8i-di/sun8i-di.c | 1 -
.../sunxi/sun8i-rotate/sun8i_rotate.c | 1 -
drivers/media/platform/ti/vpe/vip.c | 1 +
drivers/media/rc/ir-spi.c | 1 -
drivers/media/usb/em28xx/em28xx.h | 1 +
drivers/memory/stm32_omm.c | 1 -
drivers/memory/tegra/tegra186-emc.c | 1 -
drivers/memory/tegra/tegra186.c | 1 -
drivers/memory/tegra/tegra210-emc-core.c | 1 -
drivers/mfd/adp5585.c | 1 -
drivers/mfd/atmel-hlcdc.c | 1 -
drivers/mfd/atmel-smc.c | 1 -
drivers/mfd/cros_ec_dev.c | 1 -
drivers/mfd/cs42l43-i2c.c | 1 -
drivers/mfd/cs42l43-sdw.c | 1 -
drivers/mfd/hi655x-pmic.c | 1 -
drivers/mfd/intel-lpss-acpi.c | 1 -
drivers/mfd/intel-lpss-pci.c | 1 -
drivers/mfd/intel_soc_pmic_bxtwc.c | 1 -
drivers/mfd/intel_soc_pmic_crc.c | 1 -
drivers/mfd/kempld-core.c | 1 -
drivers/mfd/lochnagar-i2c.c | 1 -
drivers/mfd/lp873x.c | 2 +-
drivers/mfd/lp87565.c | 1 -
drivers/mfd/max14577.c | 1 -
drivers/mfd/max7360.c | 1 -
drivers/mfd/max77759.c | 1 -
drivers/mfd/max77843.c | 1 -
drivers/mfd/mc13xxx-spi.c | 1 -
drivers/mfd/motorola-cpcap.c | 1 -
drivers/mfd/ocelot-spi.c | 1 -
drivers/mfd/rt5033.c | 3 +-
drivers/mfd/rt5120.c | 1 -
drivers/mfd/rz-mtu3.c | 1 -
drivers/mfd/sec-acpm.c | 1 -
drivers/mfd/sec-i2c.c | 1 -
drivers/mfd/simple-mfd-i2c.c | 1 -
drivers/mfd/tps6594-i2c.c | 1 -
drivers/mfd/tps6594-spi.c | 1 -
drivers/mfd/upboard-fpga.c | 1 -
drivers/mfd/wm831x-core.c | 2 +-
drivers/misc/eeprom/at24.c | 1 -
drivers/misc/eeprom/ee1004.c | 1 -
drivers/misc/eeprom/eeprom_93xx46.c | 1 -
drivers/misc/eeprom/idt_89hpesx.c | 1 -
drivers/misc/hisi_hikey_usb.c | 1 -
drivers/misc/pvpanic/pvpanic-mmio.c | 1 -
drivers/misc/pvpanic/pvpanic.c | 1 -
drivers/misc/smpro-errmon.c | 1 -
drivers/misc/smpro-misc.c | 1 -
drivers/mmc/host/litex_mmc.c | 1 -
drivers/mmc/host/owl-mmc.c | 1 -
drivers/mmc/host/renesas_sdhi_internal_dmac.c | 1 -
drivers/mmc/host/renesas_sdhi_sys_dmac.c | 1 -
drivers/mmc/host/sdhci-npcm.c | 1 -
drivers/mmc/host/sdhci-of-ma35d1.c | 1 -
drivers/mmc/host/sh_mmcif.c | 1 -
drivers/mmc/host/sunxi-mmc.c | 1 -
drivers/mtd/nand/raw/brcmnand/brcmstb_nand.c | 1 -
drivers/mux/adgs1408.c | 1 -
drivers/mux/gpio.c | 1 -
drivers/net/can/spi/hi311x.c | 1 -
.../net/can/spi/mcp251xfd/mcp251xfd-core.c | 1 -
drivers/net/dsa/microchip/ksz8863_smi.c | 2 +-
drivers/net/dsa/mt7530-mmio.c | 1 -
drivers/net/dsa/ocelot/seville_vsc9953.c | 1 -
drivers/net/ethernet/calxeda/xgmac.c | 1 -
drivers/net/ethernet/ezchip/nps_enet.c | 1 -
drivers/net/ethernet/faraday/ftmac100.c | 1 -
.../net/ethernet/freescale/dpaa/dpaa_eth.c | 1 -
.../net/ethernet/freescale/enetc/enetc_ierb.c | 1 -
drivers/net/ethernet/ibm/emac/tah.c | 1 -
drivers/net/ethernet/ibm/emac/zmii.c | 1 -
drivers/net/ethernet/marvell/mvmdio.c | 1 -
.../mellanox/mlxbf_gige/mlxbf_gige_mdio.c | 1 -
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 1 -
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 1 -
.../ethernet/stmicro/stmmac/dwmac-nuvoton.c | 1 -
.../ethernet/stmicro/stmmac/dwmac-sophgo.c | 1 -
.../ethernet/stmicro/stmmac/dwmac-spacemit.c | 1 -
.../ethernet/stmicro/stmmac/dwmac-starfive.c | 1 -
drivers/net/ethernet/xscale/ptp_ixp46x.c | 1 -
drivers/net/ieee802154/mrf24j40.c | 1 -
drivers/net/mdio/mdio-realtek-rtl9300.c | 1 -
drivers/net/mhi_net.c | 1 -
drivers/net/wan/fsl_qmc_hdlc.c | 1 -
drivers/net/wireless/ath/ath9k/ahb.c | 1 -
.../broadcom/brcm80211/brcmfmac/dmi.c | 1 -
drivers/net/wireless/intersil/p54/p54spi.c | 1 -
drivers/net/wireless/ti/wl1251/sdio.c | 1 -
drivers/net/wireless/ti/wl12xx/main.c | 1 -
drivers/net/wireless/ti/wl18xx/main.c | 1 -
drivers/net/wwan/mhi_wwan_ctrl.c | 1 -
drivers/net/wwan/mhi_wwan_mbim.c | 1 -
drivers/net/wwan/qcom_bam_dmux.c | 1 -
drivers/net/wwan/rpmsg_wwan_ctrl.c | 1 -
drivers/nfc/microread/mei.c | 1 -
drivers/nfc/pn544/mei.c | 1 -
drivers/nfc/s3fwrn5/uart.c | 1 -
drivers/nvmem/an8855-efuse.c | 1 -
drivers/nvmem/apple-efuses.c | 1 -
drivers/nvmem/brcm_nvram.c | 1 -
drivers/nvmem/layerscape-sfp.c | 1 -
drivers/nvmem/lpc18xx_eeprom.c | 1 -
drivers/nvmem/max77759-nvmem.c | 1 -
drivers/nvmem/mtk-efuse.c | 1 -
drivers/nvmem/nintendo-otp.c | 1 -
drivers/nvmem/qfprom.c | 1 -
drivers/nvmem/qoriq-efuse.c | 1 -
drivers/nvmem/rcar-efuse.c | 1 -
drivers/nvmem/sec-qfprom.c | 1 -
drivers/nvmem/sunplus-ocotp.c | 1 -
drivers/nvmem/u-boot-env.c | 1 -
drivers/nvmem/uniphier-efuse.c | 1 -
drivers/of/device.c | 1 -
drivers/pci/controller/cadence/pcie-sg2042.c | 1 -
drivers/pci/controller/dwc/pci-exynos.c | 1 -
drivers/pci/controller/dwc/pci-meson.c | 1 -
drivers/pci/controller/dwc/pcie-intel-gw.c | 1 -
drivers/pci/controller/dwc/pcie-keembay.c | 1 -
drivers/pci/controller/dwc/pcie-spacemit-k1.c | 1 -
drivers/pci/controller/dwc/pcie-stm32.c | 1 -
drivers/pci/pwrctrl/generic.c | 1 -
drivers/pci/pwrctrl/pci-pwrctrl-pwrseq.c | 1 -
drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 1 -
drivers/perf/arm-ccn.c | 1 -
drivers/perf/fujitsu_uncore_pmu.c | 1 -
drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 1 -
drivers/perf/hisilicon/hisi_uncore_noc_pmu.c | 1 -
drivers/perf/hisilicon/hisi_uncore_uc_pmu.c | 1 -
drivers/perf/riscv_pmu_legacy.c | 1 -
drivers/perf/riscv_pmu_sbi.c | 1 -
drivers/perf/starfive_starlink_pmu.c | 1 -
drivers/phy/allwinner/phy-sun50i-usb3.c | 1 -
drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c | 1 -
drivers/phy/amlogic/phy-meson-axg-pcie.c | 1 -
drivers/phy/amlogic/phy-meson-gxl-usb2.c | 1 -
drivers/phy/amlogic/phy-meson8b-usb2.c | 1 -
drivers/phy/cadence/cdns-dphy-rx.c | 1 -
drivers/phy/hisilicon/phy-hi3670-pcie.c | 1 -
drivers/phy/hisilicon/phy-hi6220-usb.c | 1 -
drivers/phy/intel/phy-intel-keembay-usb.c | 1 -
drivers/phy/marvell/phy-mmp3-hsic.c | 1 -
drivers/phy/marvell/phy-mmp3-usb.c | 1 -
drivers/phy/marvell/phy-mvebu-sata.c | 1 -
drivers/phy/mediatek/phy-mtk-ufs.c | 1 -
drivers/phy/phy-snps-eusb2.c | 1 -
drivers/phy/qualcomm/phy-ath79-usb.c | 1 -
.../phy/rockchip/phy-rockchip-samsung-dcphy.c | 1 -
drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 -
drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c | 1 -
drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 1 -
drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 1 -
drivers/pinctrl/bcm/pinctrl-bcm4908.c | 1 -
drivers/pinctrl/bcm/pinctrl-bcm63xx.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx-scmi.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx23.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx25.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx27.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx28.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx35.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx50.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx51.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx53.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx6dl.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx6q.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx6sl.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx6sll.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx6sx.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx7ulp.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx8dxl.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx8mq.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx8qxp.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx8ulp.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx91.c | 1 -
drivers/pinctrl/freescale/pinctrl-imx93.c | 1 -
drivers/pinctrl/freescale/pinctrl-vf610.c | 1 -
drivers/pinctrl/intel/pinctrl-alderlake.c | 1 -
drivers/pinctrl/intel/pinctrl-broxton.c | 1 -
drivers/pinctrl/intel/pinctrl-cannonlake.c | 1 -
drivers/pinctrl/intel/pinctrl-cedarfork.c | 1 -
drivers/pinctrl/intel/pinctrl-denverton.c | 1 -
drivers/pinctrl/intel/pinctrl-elkhartlake.c | 1 -
drivers/pinctrl/intel/pinctrl-emmitsburg.c | 1 -
drivers/pinctrl/intel/pinctrl-geminilake.c | 1 -
.../pinctrl/intel/pinctrl-intel-platform.c | 1 -
drivers/pinctrl/intel/pinctrl-jasperlake.c | 1 -
drivers/pinctrl/intel/pinctrl-lakefield.c | 1 -
drivers/pinctrl/intel/pinctrl-lewisburg.c | 1 -
drivers/pinctrl/intel/pinctrl-merrifield.c | 1 -
drivers/pinctrl/intel/pinctrl-meteorlake.c | 1 -
drivers/pinctrl/intel/pinctrl-meteorpoint.c | 1 -
drivers/pinctrl/intel/pinctrl-moorefield.c | 1 -
drivers/pinctrl/intel/pinctrl-sunrisepoint.c | 1 -
drivers/pinctrl/intel/pinctrl-tigerlake.c | 1 -
.../pinctrl/microchip/pinctrl-mpfs-iomux0.c | 1 -
.../pinctrl/microchip/pinctrl-mpfs-mssio.c | 1 -
.../pinctrl/microchip/pinctrl-pic64gx-gpio2.c | 1 -
drivers/pinctrl/nuvoton/pinctrl-ma35d1.c | 1 -
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 1 -
drivers/pinctrl/nuvoton/pinctrl-npcm8xx.c | 1 -
drivers/pinctrl/nuvoton/pinctrl-wpcm450.c | 1 -
drivers/pinctrl/pinctrl-as3722.c | 1 -
drivers/pinctrl/pinctrl-cy8c95x0.c | 1 -
drivers/pinctrl/pinctrl-da850-pupd.c | 1 -
drivers/pinctrl/pinctrl-digicolor.c | 1 -
drivers/pinctrl/pinctrl-eic7700.c | 1 -
drivers/pinctrl/pinctrl-eyeq5.c | 1 -
drivers/pinctrl/pinctrl-ingenic.c | 1 -
drivers/pinctrl/pinctrl-loongson2.c | 1 -
drivers/pinctrl/pinctrl-lpc18xx.c | 1 -
drivers/pinctrl/pinctrl-max77620.c | 1 -
drivers/pinctrl/pinctrl-mcp23s08.c | 1 -
drivers/pinctrl/pinctrl-mcp23s08_i2c.c | 1 -
drivers/pinctrl/pinctrl-mcp23s08_spi.c | 1 -
drivers/pinctrl/pinctrl-microchip-sgpio.c | 1 -
drivers/pinctrl/pinctrl-mlxbf3.c | 1 -
drivers/pinctrl/pinctrl-pistachio.c | 1 -
drivers/pinctrl/pinctrl-scmi.c | 1 -
drivers/pinctrl/pinctrl-th1520.c | 1 -
drivers/pinctrl/pinctrl-tps6594.c | 1 -
drivers/pinctrl/qcom/pinctrl-ipq5018.c | 1 -
drivers/pinctrl/spear/pinctrl-spear1310.c | 1 -
drivers/pinctrl/spear/pinctrl-spear1340.c | 1 -
drivers/pinctrl/spear/pinctrl-spear300.c | 1 -
drivers/pinctrl/spear/pinctrl-spear310.c | 1 -
drivers/pinctrl/spear/pinctrl-spear320.c | 1 -
drivers/pinctrl/sprd/pinctrl-sprd-sc9860.c | 1 -
.../starfive/pinctrl-starfive-jh7100.c | 1 -
.../starfive/pinctrl-starfive-jh7110-aon.c | 1 -
.../starfive/pinctrl-starfive-jh7110-sys.c | 1 -
.../starfive/pinctrl-starfive-jh7110.c | 1 -
drivers/pinctrl/tegra/pinctrl-tegra234.c | 1 -
drivers/pinctrl/tegra/pinctrl-tegra238.c | 1 -
drivers/pinctrl/tegra/pinctrl-tegra264.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-ld11.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-ld20.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-ld4.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-ld6b.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-nx1.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-pro4.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-pro5.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 1 -
.../pinctrl/uniphier/pinctrl-uniphier-sld8.c | 1 -
drivers/platform/chrome/cros_ec_chardev.c | 1 -
drivers/platform/chrome/cros_ec_debugfs.c | 1 -
drivers/platform/chrome/cros_ec_lightbar.c | 1 -
drivers/platform/chrome/cros_ec_sensorhub.c | 1 -
drivers/platform/chrome/cros_ec_sysfs.c | 1 -
drivers/platform/chrome/cros_ec_vbc.c | 1 -
.../platform/chrome/cros_kbd_led_backlight.c | 1 -
drivers/platform/chrome/cros_usbpd_logger.c | 1 -
drivers/platform/chrome/cros_usbpd_notify.c | 1 -
drivers/platform/chrome/wilco_ec/core.c | 1 -
drivers/platform/chrome/wilco_ec/debugfs.c | 1 -
drivers/platform/chrome/wilco_ec/telemetry.c | 1 -
drivers/platform/goldfish/goldfish_pipe.c | 1 -
drivers/platform/x86/asus-tf103c-dock.c | 1 -
drivers/platform/x86/intel/atomisp2/led.c | 1 -
drivers/platform/x86/intel/atomisp2/pm.c | 1 -
drivers/platform/x86/intel/bxtwc_tmu.c | 1 -
drivers/platform/x86/intel/ehl_pse_io.c | 1 -
drivers/platform/x86/intel/plr_tpmi.c | 1 -
drivers/platform/x86/intel/punit_ipc.c | 1 -
drivers/platform/x86/intel_scu_pltdrv.c | 1 -
drivers/platform/x86/msi-ec.c | 1 +
.../platform/x86/nvidia-wmi-ec-backlight.c | 1 -
drivers/platform/x86/quickstart.c | 1 -
drivers/platform/x86/uniwill/uniwill-wmi.c | 1 -
.../platform/x86/x86-android-tablets/dmi.c | 1 -
.../x86-android-tablets/x86-android-tablets.h | 1 +
drivers/pmdomain/actions/owl-sps.c | 1 -
drivers/pmdomain/imx/imx93-pd.c | 1 -
.../marvell/pxa1908-power-controller.c | 1 -
drivers/pnp/pnpacpi/core.c | 1 -
drivers/power/reset/brcm-kona-reset.c | 1 -
drivers/power/reset/ep93xx-restart.c | 1 -
drivers/power/reset/gpio-poweroff.c | 1 -
drivers/power/reset/ltc2952-poweroff.c | 1 -
drivers/power/reset/macsmc-reboot.c | 1 -
drivers/power/reset/ocelot-reset.c | 1 -
drivers/power/reset/pwr-mlxbf.c | 1 -
drivers/power/reset/qemu-virt-ctrl.c | 1 -
drivers/power/reset/sc27xx-poweroff.c | 1 -
drivers/power/reset/spacemit-p1-reboot.c | 1 -
drivers/power/reset/tdx-ec-poweroff.c | 1 -
drivers/power/reset/tps65086-restart.c | 1 -
drivers/power/sequencing/pwrseq-pcie-m2.c | 1 -
drivers/power/sequencing/pwrseq-qcom-wcn.c | 1 -
drivers/power/supply/adp5061.c | 1 -
drivers/power/supply/bd71828-power.c | 1 -
drivers/power/supply/bd99954-charger.c | 1 -
drivers/power/supply/bq24190_charger.c | 1 -
drivers/power/supply/chagall-battery.c | 1 -
drivers/power/supply/cpcap-charger.c | 1 -
drivers/power/supply/cros_charge-control.c | 1 -
.../power/supply/cros_peripheral_charger.c | 1 -
drivers/power/supply/cros_usbpd-charger.c | 1 -
drivers/power/supply/lego_ev3_battery.c | 1 -
.../power/supply/max14656_charger_detector.c | 1 -
drivers/power/supply/max17042_battery.c | 1 -
drivers/power/supply/max77759_charger.c | 1 -
drivers/power/supply/max8971_charger.c | 1 -
drivers/power/supply/max8998_charger.c | 1 -
drivers/power/supply/mp2629_charger.c | 1 -
drivers/power/supply/olpc_battery.c | 1 -
drivers/power/supply/pm8916_bms_vm.c | 1 -
drivers/power/supply/pm8916_lbc.c | 1 -
drivers/power/supply/rt5033_charger.c | 1 -
drivers/power/supply/rt9467-charger.c | 1 -
drivers/power/supply/rt9471.c | 1 -
drivers/power/supply/rt9756.c | 1 -
drivers/power/supply/s2mu005-battery.c | 1 -
drivers/power/supply/ug3105_battery.c | 1 -
drivers/pps/clients/pps-gpio.c | 1 -
drivers/pps/generators/pps_gen_tio.c | 1 -
drivers/ptp/ptp_dte.c | 1 -
drivers/pwm/pwm-adp5585.c | 1 -
drivers/pwm/pwm-airoha.c | 1 -
drivers/pwm/pwm-apple.c | 1 -
drivers/pwm/pwm-berlin.c | 1 -
drivers/pwm/pwm-ep93xx.c | 1 -
drivers/pwm/pwm-gpio.c | 1 -
drivers/pwm/pwm-intel-lgm.c | 1 -
drivers/pwm/pwm-keembay.c | 1 -
drivers/pwm/pwm-lpc18xx-sct.c | 1 -
drivers/pwm/pwm-lpss-platform.c | 1 -
drivers/pwm/pwm-max7360.c | 1 -
drivers/pwm/pwm-pxa.c | 1 -
drivers/pwm/pwm-sifive.c | 1 -
drivers/pwm/pwm-sl28cpld.c | 1 -
drivers/pwm/pwm-sprd.c | 1 -
drivers/pwm/pwm-sunplus.c | 1 -
drivers/pwm/pwm-vt8500.c | 1 -
drivers/regulator/adp5055-regulator.c | 1 -
drivers/regulator/bd71828-regulator.c | 1 -
drivers/regulator/max77541-regulator.c | 1 -
drivers/regulator/max77675-regulator.c | 1 -
drivers/regulator/mt6370-regulator.c | 1 -
drivers/regulator/pv88080-regulator.c | 1 -
drivers/regulator/rt4803.c | 1 -
drivers/regulator/rt5739.c | 1 -
drivers/regulator/rt6190-regulator.c | 1 -
drivers/regulator/rt8092.c | 1 -
drivers/regulator/rtq2208-regulator.c | 1 -
drivers/regulator/tps6287x-regulator.c | 1 -
drivers/regulator/tps65218-regulator.c | 1 -
drivers/regulator/tps65912-regulator.c | 1 -
drivers/regulator/vexpress-regulator.c | 1 -
drivers/reset/reset-ath79.c | 1 -
drivers/reset/reset-axs10x.c | 1 -
drivers/reset/reset-bcm6345.c | 1 -
drivers/reset/reset-eyeq.c | 1 -
drivers/reset/reset-gpio.c | 1 -
drivers/reset/reset-sunplus.c | 1 -
drivers/reset/reset-tn48m.c | 1 -
.../reset/starfive/reset-starfive-jh7100.c | 1 -
drivers/rtc/rtc-88pm886.c | 1 -
drivers/rtc/rtc-cpcap.c | 1 -
drivers/rtc/rtc-cros-ec.c | 1 -
drivers/rtc/rtc-ds1307.c | 1 -
drivers/rtc/rtc-ep93xx.c | 1 -
drivers/rtc/rtc-fsl-ftm-alarm.c | 1 -
drivers/rtc/rtc-ftrtc010.c | 1 -
drivers/rtc/rtc-lpc24xx.c | 1 -
drivers/rtc/rtc-m48t86.c | 1 -
drivers/rtc/rtc-mc13xxx.c | 1 -
drivers/rtc/rtc-moxart.c | 1 -
drivers/rtc/rtc-msc313.c | 1 -
drivers/rtc/rtc-mt6397.c | 1 -
drivers/rtc/rtc-mt7622.c | 1 -
drivers/rtc/rtc-mxc_v2.c | 1 -
drivers/rtc/rtc-r7301.c | 1 -
drivers/rtc/rtc-rzn1.c | 1 -
drivers/rtc/rtc-sh.c | 1 -
drivers/rtc/rtc-ssd202d.c | 1 -
drivers/rtc/rtc-tegra.c | 1 -
drivers/rtc/rtc-ti-k3.c | 1 -
drivers/rtc/rtc-tps6594.c | 1 -
drivers/s390/crypto/ap_bus.c | 2 +-
drivers/s390/crypto/vfio_ap_drv.c | 2 +-
drivers/s390/crypto/zcrypt_cex4.c | 2 +-
drivers/siox/siox-bus-gpio.c | 1 -
drivers/soc/fsl/qe/qe.c | 1 -
drivers/soc/qcom/qcom_pd_mapper.c | 1 -
drivers/soc/renesas/rzn1_irqmux.c | 1 -
drivers/soc/sophgo/sg2044-topsys.c | 2 +-
drivers/soc/tegra/fuse/fuse-tegra.c | 1 -
drivers/soc/tegra/fuse/tegra-apbmisc.c | 1 -
drivers/soc/ti/smartreflex.c | 2 +-
drivers/soundwire/bus.c | 1 -
drivers/soundwire/bus_type.c | 1 -
drivers/soundwire/cadence_master.c | 1 -
drivers/soundwire/debugfs.c | 1 -
.../soundwire/generic_bandwidth_allocation.c | 1 -
drivers/soundwire/mipi_disco.c | 1 -
drivers/soundwire/stream.c | 1 -
drivers/soundwire/sysfs_slave.c | 1 -
drivers/soundwire/sysfs_slave_dpn.c | 1 -
drivers/spi/spi-atcspi200.c | 1 -
drivers/spi/spi-cs42l43.c | 1 -
drivers/spi/spi-gpio.c | 1 -
drivers/spi/spi-hisi-sfc-v3xx.c | 1 -
drivers/spi/spi-loongson-pci.c | 1 -
drivers/spi/spi-loongson-plat.c | 1 -
drivers/spi/spi-loopback-test.c | 1 -
...spi-offload-trigger-adi-util-sigma-delta.c | 1 -
drivers/spi/spi-offload-trigger-pwm.c | 1 -
drivers/spi/spi-pxa2xx-platform.c | 1 -
drivers/spi/spi-realtek-rtl-snand.c | 1 -
drivers/spi/spi-realtek-rtl.c | 1 -
drivers/spi/spi-sc18is602.c | 1 -
drivers/spi/spi-wpcm-fiu.c | 1 -
drivers/spi/spi.c | 1 -
drivers/spi/spidev.c | 1 -
drivers/spmi/spmi-apple-controller.c | 1 -
drivers/staging/greybus/arche-apb-ctrl.c | 1 -
drivers/thermal/loongson2_thermal.c | 1 -
drivers/thermal/renesas/rzg2l_thermal.c | 1 -
drivers/tty/goldfish.c | 1 -
drivers/tty/serial/8250/8250_dfl.c | 1 -
drivers/tty/serial/8250/8250_dw.c | 1 -
drivers/tty/serial/8250/8250_em.c | 1 -
drivers/tty/serial/8250/8250_keba.c | 1 -
drivers/tty/serial/8250/8250_loongson.c | 1 -
drivers/tty/serial/8250/8250_ni.c | 1 -
drivers/tty/serial/max3100.c | 1 -
drivers/tty/serial/max310x.c | 1 -
drivers/tty/serial/sc16is7xx.c | 1 -
drivers/tty/serial/sc16is7xx_i2c.c | 1 -
drivers/tty/serial/sc16is7xx_spi.c | 1 -
drivers/tty/serial/sccnxp.c | 1 -
drivers/tty/serial/tegra-utc.c | 1 -
drivers/uio/uio_pdrv_genirq.c | 1 -
drivers/usb/dwc2/core.h | 1 +
drivers/usb/gadget/udc/renesas_usbf.c | 1 -
drivers/usb/misc/usb-ljca.c | 1 -
drivers/usb/typec/mux/tusb1046.c | 1 -
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 1 -
.../typec/tcpm/qcom/qcom_pmic_typec_pdphy.c | 1 -
.../tcpm/qcom/qcom_pmic_typec_pdphy_stub.c | 1 -
.../typec/tcpm/qcom/qcom_pmic_typec_port.c | 1 -
drivers/usb/typec/tcpm/tcpci_mt6370.c | 1 -
drivers/usb/typec/tcpm/tcpci_rt1711h.c | 1 -
drivers/usb/typec/ucsi/cros_ec_ucsi.c | 1 -
drivers/vdpa/vdpa.c | 1 -
drivers/vdpa/vdpa_user/vduse_dev.c | 1 -
drivers/video/backlight/apple_dwi_bl.c | 1 -
drivers/video/backlight/da9052_bl.c | 1 -
drivers/video/backlight/hx8357.c | 1 -
drivers/video/backlight/ktd2801-backlight.c | 1 -
drivers/video/backlight/mp3309c.c | 1 -
drivers/video/backlight/mt6370-backlight.c | 1 -
drivers/video/backlight/rave-sp-backlight.c | 1 -
drivers/video/backlight/rt4831-backlight.c | 1 -
.../omap2/omapfb/displays/encoder-opa362.c | 1 -
.../omap2/omapfb/displays/encoder-tfp410.c | 1 -
.../omap2/omapfb/displays/encoder-tpd12s015.c | 1 -
.../omap2/omapfb/displays/panel-dsi-cm.c | 1 -
.../virt/coco/arm-cca-guest/arm-cca-guest.c | 2 +-
drivers/virt/coco/tdx-guest/tdx-guest.c | 1 -
drivers/virt/coco/tdx-host/tdx-host.c | 1 -
drivers/w1/masters/amd_axi_w1.c | 1 -
drivers/w1/masters/ds2490.c | 1 -
drivers/w1/masters/mxc_w1.c | 1 -
drivers/w1/masters/sgi_w1.c | 1 -
drivers/w1/masters/w1-gpio.c | 1 -
drivers/watchdog/at91rm9200_wdt.c | 1 -
drivers/watchdog/cros_ec_wdt.c | 1 -
drivers/watchdog/davinci_wdt.c | 1 -
drivers/watchdog/ftwdt010_wdt.c | 1 -
drivers/watchdog/gpio_wdt.c | 1 -
drivers/watchdog/gunyah_wdt.c | 1 -
drivers/watchdog/imgpdc_wdt.c | 1 -
drivers/watchdog/keembay_wdt.c | 1 -
drivers/watchdog/max63xx_wdt.c | 1 -
drivers/watchdog/max77620_wdt.c | 1 -
drivers/watchdog/meson_wdt.c | 1 -
drivers/watchdog/moxart_wdt.c | 1 -
drivers/watchdog/msc313e_wdt.c | 1 -
drivers/watchdog/mt7621_wdt.c | 1 -
drivers/watchdog/nic7018_wdt.c | 1 -
drivers/watchdog/omap_wdt.c | 1 -
drivers/watchdog/pseries-wdt.c | 1 -
drivers/watchdog/realtek_otto_wdt.c | 1 -
drivers/watchdog/rt2880_wdt.c | 1 -
drivers/watchdog/rti_wdt.c | 1 -
drivers/watchdog/sbsa_gwdt.c | 1 -
drivers/watchdog/sl28cpld_wdt.c | 1 -
drivers/watchdog/sunplus_wdt.c | 1 -
drivers/watchdog/ts72xx_wdt.c | 1 -
drivers/watchdog/twl4030_wdt.c | 1 -
drivers/watchdog/xilinx_wwdt.c | 1 -
include/linux/acpi.h | 2 +-
include/linux/amba/bus.h | 2 +-
include/linux/auxiliary_bus.h | 2 +-
include/linux/bcma/bcma.h | 2 +-
include/linux/cdx/cdx_bus.h | 2 +-
include/linux/device/driver.h | 2 +
include/linux/dfl.h | 2 +-
include/linux/dmi.h | 2 +-
include/linux/eisa.h | 2 +-
include/linux/firewire.h | 3 +-
include/linux/fsl/mc.h | 2 +-
include/linux/hid.h | 2 +-
include/linux/hyperv.h | 2 +-
include/linux/i2c.h | 2 +-
include/linux/i3c/device.h | 2 +-
include/linux/input.h | 2 +-
include/linux/intel-ish-client-if.h | 2 +-
include/linux/ipack.h | 2 +-
include/linux/isapnp.h | 2 +-
include/linux/mcb.h | 2 +-
include/linux/mei_cl_bus.h | 2 +-
include/linux/mhi.h | 1 +
include/linux/mmc/sdio_func.h | 2 +-
include/linux/mod_device_id/acpi.h | 31 +
include/linux/mod_device_id/amba.h | 18 +
include/linux/mod_device_id/ap.h | 19 +
include/linux/mod_device_id/apr.h | 20 +
include/linux/mod_device_id/auxiliary.h | 16 +
include/linux/mod_device_id/bcma.h | 24 +
include/linux/mod_device_id/ccw.h | 26 +
include/linux/mod_device_id/cdx.h | 39 +
include/linux/mod_device_id/coreboot.h | 19 +
include/linux/mod_device_id/css.h | 16 +
include/linux/mod_device_id/dfl.h | 33 +
include/linux/mod_device_id/dmi.h | 57 +
include/linux/mod_device_id/eisa.h | 20 +
include/linux/mod_device_id/fsl_mc.h | 21 +
include/linux/mod_device_id/hda.h | 16 +
include/linux/mod_device_id/hid.h | 21 +
include/linux/mod_device_id/hv_vmbus.h | 17 +
include/linux/mod_device_id/i2c.h | 18 +
include/linux/mod_device_id/i3c.h | 25 +
include/linux/mod_device_id/ieee1394.h | 26 +
include/linux/mod_device_id/input.h | 61 +
include/linux/mod_device_id/ipack.h | 16 +
include/linux/mod_device_id/isapnp.h | 15 +
include/linux/mod_device_id/ishtp.h | 23 +
include/linux/mod_device_id/mcb.h | 14 +
include/linux/mod_device_id/mdio.h | 34 +
include/linux/mod_device_id/mei_cl.h | 30 +
include/linux/mod_device_id/mhi.h | 23 +
include/linux/mod_device_id/mips_cdmm.h | 16 +
include/linux/mod_device_id/of.h | 14 +
include/linux/mod_device_id/parisc.h | 20 +
include/linux/mod_device_id/pci.h | 53 +
include/linux/mod_device_id/pcmcia.h | 47 +
include/linux/mod_device_id/platform.h | 16 +
include/linux/mod_device_id/pnp.h | 25 +
include/linux/mod_device_id/rio.h | 27 +
include/linux/mod_device_id/rpmsg.h | 18 +
include/linux/mod_device_id/sdio.h | 20 +
include/linux/mod_device_id/sdw.h | 17 +
include/linux/mod_device_id/serio.h | 17 +
include/linux/mod_device_id/slim.h | 22 +
include/linux/mod_device_id/spi.h | 18 +
include/linux/mod_device_id/spmi.h | 16 +
include/linux/mod_device_id/ssam.h | 27 +
include/linux/mod_device_id/ssb.h | 23 +
include/linux/mod_device_id/tb.h | 36 +
include/linux/mod_device_id/tee_client.h | 17 +
include/linux/mod_device_id/typec.h | 25 +
include/linux/mod_device_id/ulpi.h | 15 +
include/linux/mod_device_id/usb.h | 110 ++
include/linux/mod_device_id/vchiq.h | 8 +
include/linux/mod_device_id/vio.h | 10 +
include/linux/mod_device_id/virtio.h | 15 +
include/linux/mod_device_id/wmi.h | 18 +
include/linux/mod_device_id/x86_cpu.h | 43 +
include/linux/mod_device_id/zorro.h | 18 +
include/linux/mod_devicetable.h | 1014 +----------------
include/linux/of.h | 2 +-
include/linux/of_platform.h | 4 +-
include/linux/pci-epf.h | 2 +-
include/linux/pci.h | 2 +-
include/linux/phy.h | 2 +-
include/linux/platform_data/x86/int3472.h | 2 +-
include/linux/platform_data/x86/soc.h | 2 +-
include/linux/platform_device.h | 2 +-
include/linux/pnp.h | 2 +-
include/linux/raspberrypi/vchiq_bus.h | 2 +-
include/linux/rio.h | 2 +-
include/linux/rpmsg.h | 2 +-
include/linux/serio.h | 2 +-
include/linux/slimbus.h | 2 +-
include/linux/soc/qcom/apr.h | 2 +-
include/linux/soundwire/sdw.h | 2 +-
include/linux/spi/spi.h | 4 +-
include/linux/ssb/ssb.h | 2 +-
include/linux/surface_aggregator/device.h | 2 +-
include/linux/tee_drv.h | 2 +-
include/linux/thunderbolt.h | 2 +-
include/linux/ulpi/driver.h | 2 +-
include/linux/usb.h | 2 +-
include/linux/usb/serial.h | 1 +
include/linux/usb/typec_altmode.h | 2 +-
include/linux/virtio.h | 2 +-
include/linux/wmi.h | 2 +-
include/linux/zorro.h | 2 +-
include/pcmcia/ds.h | 2 +-
include/sound/hda_codec.h | 2 +-
include/sound/hdaudio.h | 1 +
net/qrtr/mhi.c | 1 -
net/rfkill/rfkill-gpio.c | 1 -
sound/atmel/ac97c.c | 1 -
sound/firewire/isight.c | 1 -
.../hda/codecs/side-codecs/cs35l41_hda_i2c.c | 1 -
.../hda/codecs/side-codecs/cs35l41_hda_spi.c | 1 -
.../hda/codecs/side-codecs/tas2781_hda_i2c.c | 1 -
.../hda/codecs/side-codecs/tas2781_hda_spi.c | 1 -
sound/hda/core/hda_bus_type.c | 2 +-
sound/soc/atmel/sam9x5_wm8731.c | 1 -
sound/soc/codecs/adau1372-i2c.c | 1 -
sound/soc/codecs/adau1372-spi.c | 1 -
sound/soc/codecs/adau1372.c | 1 -
sound/soc/codecs/adau1761-i2c.c | 1 -
sound/soc/codecs/adau1761-spi.c | 1 -
sound/soc/codecs/adau1781-i2c.c | 1 -
sound/soc/codecs/adau1781-spi.c | 1 -
sound/soc/codecs/adau1977-i2c.c | 1 -
sound/soc/codecs/adau1977-spi.c | 1 -
sound/soc/codecs/adau7118-hw.c | 1 -
sound/soc/codecs/ak4104.c | 1 -
sound/soc/codecs/audio-iio-aux.c | 1 -
sound/soc/codecs/cs4234.c | 1 -
sound/soc/codecs/cs4270.c | 1 -
sound/soc/codecs/cs42l42-sdw.c | 1 -
sound/soc/codecs/cs42l43.c | 1 -
sound/soc/codecs/cs42xx8-i2c.c | 1 -
sound/soc/codecs/cs42xx8-spi.c | 1 -
sound/soc/codecs/cs4349.c | 1 -
sound/soc/codecs/es8316.c | 1 -
sound/soc/codecs/es8323.c | 1 -
sound/soc/codecs/es9356.c | 1 -
sound/soc/codecs/max98357a.c | 1 -
sound/soc/codecs/max98373-i2c.c | 1 -
sound/soc/codecs/max98373-sdw.c | 1 -
sound/soc/codecs/max98388.c | 1 -
sound/soc/codecs/mt6351.c | 1 -
sound/soc/codecs/mt6358.c | 1 -
sound/soc/codecs/pcm3168a-i2c.c | 1 -
sound/soc/codecs/rt1017-sdca-sdw.c | 1 -
sound/soc/codecs/rt1308-sdw.c | 1 -
sound/soc/codecs/rt1316-sdw.c | 1 -
sound/soc/codecs/rt1318-sdw.c | 1 -
sound/soc/codecs/rt1320-sdw.c | 1 -
sound/soc/codecs/rt700-sdw.c | 1 -
sound/soc/codecs/rt711-sdca-sdw.c | 1 -
sound/soc/codecs/rt711-sdw.c | 1 -
sound/soc/codecs/rt712-sdca-dmic.c | 1 -
sound/soc/codecs/rt712-sdca-sdw.c | 1 -
sound/soc/codecs/rt715-sdca-sdw.c | 1 -
sound/soc/codecs/rt715-sdw.c | 1 -
sound/soc/codecs/rt721-sdca-sdw.c | 1 -
sound/soc/codecs/rt722-sdca-sdw.c | 1 -
sound/soc/codecs/rt9123.c | 1 -
sound/soc/codecs/rt9123p.c | 1 -
sound/soc/codecs/rtq9124.c | 1 -
sound/soc/codecs/rtq9128.c | 1 -
sound/soc/codecs/sdw-mockup.c | 1 -
sound/soc/codecs/simple-amplifier.c | 1 -
sound/soc/codecs/sma1303.c | 1 -
sound/soc/codecs/src4xxx-i2c.c | 1 -
sound/soc/codecs/uda1334.c | 1 -
sound/soc/codecs/wm8510.c | 1 -
sound/soc/codecs/wm8523.c | 1 -
sound/soc/codecs/wm8524.c | 1 -
sound/soc/codecs/wm8580.c | 1 -
sound/soc/codecs/wm8711.c | 1 -
sound/soc/codecs/wm8728.c | 1 -
sound/soc/codecs/wm8731-i2c.c | 1 -
sound/soc/codecs/wm8731-spi.c | 1 -
sound/soc/codecs/wm8737.c | 1 -
sound/soc/codecs/wm8753.c | 1 -
sound/soc/codecs/wm8770.c | 1 -
sound/soc/codecs/wm8776.c | 1 -
sound/soc/fsl/fsl_aud2htx.c | 1 -
sound/soc/fsl/mpc5200_psc_ac97.c | 1 -
.../generic/audio-graph-card2-custom-sample.c | 1 -
sound/soc/jz4740/jz4740-i2s.c | 1 -
sound/soc/mediatek/mt8365/mt8365-mt6357.c | 1 -
sound/soc/qcom/apq8096.c | 1 -
sound/soc/qcom/sc7280.c | 1 -
sound/soc/qcom/storm.c | 1 -
sound/soc/rockchip/rockchip_sai.c | 1 +
sound/soc/sdca/sdca_class.c | 1 -
sound/soc/sof/sof-client-ipc-flood-test.c | 1 -
.../soc/sof/sof-client-ipc-kernel-injector.c | 1 -
sound/soc/sof/sof-client-ipc-msg-injector.c | 1 -
sound/soc/sunxi/sun50i-codec-analog.c | 1 -
sound/soc/sunxi/sun50i-dmic.c | 1 -
sound/soc/tegra/tegra186_asrc.c | 1 -
sound/soc/tegra/tegra186_dspk.c | 1 -
sound/soc/tegra/tegra20_spdif.c | 1 -
sound/soc/tegra/tegra210_adx.c | 1 -
sound/soc/tegra/tegra210_amx.c | 1 -
sound/soc/tegra/tegra210_dmic.c | 1 -
sound/soc/tegra/tegra210_i2s.c | 1 -
sound/soc/tegra/tegra210_mixer.c | 1 -
sound/soc/tegra/tegra210_mvc.c | 1 -
sound/soc/tegra/tegra210_ope.c | 1 -
sound/soc/ti/omap-dmic.c | 1 -
sound/soc/ti/omap-mcpdm.c | 1 -
tools/testing/cxl/test/mem.c | 1 -
1633 files changed, 1576 insertions(+), 2527 deletions(-)
create mode 100644 include/linux/mod_device_id/acpi.h
create mode 100644 include/linux/mod_device_id/amba.h
create mode 100644 include/linux/mod_device_id/ap.h
create mode 100644 include/linux/mod_device_id/apr.h
create mode 100644 include/linux/mod_device_id/auxiliary.h
create mode 100644 include/linux/mod_device_id/bcma.h
create mode 100644 include/linux/mod_device_id/ccw.h
create mode 100644 include/linux/mod_device_id/cdx.h
create mode 100644 include/linux/mod_device_id/coreboot.h
create mode 100644 include/linux/mod_device_id/css.h
create mode 100644 include/linux/mod_device_id/dfl.h
create mode 100644 include/linux/mod_device_id/dmi.h
create mode 100644 include/linux/mod_device_id/eisa.h
create mode 100644 include/linux/mod_device_id/fsl_mc.h
create mode 100644 include/linux/mod_device_id/hda.h
create mode 100644 include/linux/mod_device_id/hid.h
create mode 100644 include/linux/mod_device_id/hv_vmbus.h
create mode 100644 include/linux/mod_device_id/i2c.h
create mode 100644 include/linux/mod_device_id/i3c.h
create mode 100644 include/linux/mod_device_id/ieee1394.h
create mode 100644 include/linux/mod_device_id/input.h
create mode 100644 include/linux/mod_device_id/ipack.h
create mode 100644 include/linux/mod_device_id/isapnp.h
create mode 100644 include/linux/mod_device_id/ishtp.h
create mode 100644 include/linux/mod_device_id/mcb.h
create mode 100644 include/linux/mod_device_id/mdio.h
create mode 100644 include/linux/mod_device_id/mei_cl.h
create mode 100644 include/linux/mod_device_id/mhi.h
create mode 100644 include/linux/mod_device_id/mips_cdmm.h
create mode 100644 include/linux/mod_device_id/of.h
create mode 100644 include/linux/mod_device_id/parisc.h
create mode 100644 include/linux/mod_device_id/pci.h
create mode 100644 include/linux/mod_device_id/pcmcia.h
create mode 100644 include/linux/mod_device_id/platform.h
create mode 100644 include/linux/mod_device_id/pnp.h
create mode 100644 include/linux/mod_device_id/rio.h
create mode 100644 include/linux/mod_device_id/rpmsg.h
create mode 100644 include/linux/mod_device_id/sdio.h
create mode 100644 include/linux/mod_device_id/sdw.h
create mode 100644 include/linux/mod_device_id/serio.h
create mode 100644 include/linux/mod_device_id/slim.h
create mode 100644 include/linux/mod_device_id/spi.h
create mode 100644 include/linux/mod_device_id/spmi.h
create mode 100644 include/linux/mod_device_id/ssam.h
create mode 100644 include/linux/mod_device_id/ssb.h
create mode 100644 include/linux/mod_device_id/tb.h
create mode 100644 include/linux/mod_device_id/tee_client.h
create mode 100644 include/linux/mod_device_id/typec.h
create mode 100644 include/linux/mod_device_id/ulpi.h
create mode 100644 include/linux/mod_device_id/usb.h
create mode 100644 include/linux/mod_device_id/vchiq.h
create mode 100644 include/linux/mod_device_id/vio.h
create mode 100644 include/linux/mod_device_id/virtio.h
create mode 100644 include/linux/mod_device_id/wmi.h
create mode 100644 include/linux/mod_device_id/x86_cpu.h
create mode 100644 include/linux/mod_device_id/zorro.h
base-commit: ef0c9f75a19532d7675384708fc8621e10850104
--
2.47.3
^ permalink raw reply
* [PATCH 4/4] clk: implement sync_state support
From: Brian Masney @ 2026-06-26 16:32 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Ulf Hansson, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Russell King, Neil Armstrong, Xuyang Dong, Jens Glathe,
Hans de Goede, Maxime Ripard, Saravana Kannan, Abel Vesa
Cc: driver-core, linux-kernel, linux-pm, linux-arm-msm, linux-clk,
Brian Masney
In-Reply-To: <20260626-clk-sync-state-v1-0-4156d8196dc8@redhat.com>
The existing support for disabling unused clks runs in the late initcall
stage, and it has been known for a long time that this is broken since
it runs too early in the boot up process. It doesn't work for kernel
modules, and it also doesn't work if all of the consumers haven't fully
probed yet. Folks have long recommended to boot certain platforms with
clk_ignore_unused to work around issues with disabling unused clks.
Let's go ahead and add a framework-level sync_state callback for the clk
subsystem. If a driver doesn't have a sync_state callback configured,
which is the 99+% use case today, then let's set it up to use the
clk_sync_state() introduced in this commit so that no driver changes
are needed.
At the time of this writing, there are currently only 7 clk drivers that
implement sync_state, and all are Qualcomm SoCs where they interact with
the interconnect framework via icc_sync_state(). A shared helper has
been created for this platform that calls clk_sync_state(). It is
expected that any new clk drivers that want to implement their own
sync_state will also need to call clk_sync_state() at the end of their
custom sync_state callback.
There will be several stages of disabling unused clks:
- The first phase will be executed at late_initcall and it will only
disable unused clks that do not have a struct dev.
- The sync_state callback will be invoked for each clk driver once all
consumers have probed.
This is based on previous attempts by Saravana Kannan and Abel Vesa
that are linked below.
This change was tested on a Thinkpad x13s laptop.
[ 0.366737] clk: Disabling unused clocks not associated with a device
[ 0.367232] PM: genpd: Disabling unused power domains
[ 7.791413] qcom-qmp-pcie-phy 1c24000.phy: clk: Disabling unused clocks
[ 7.799702] qcom_aoss_qmp c300000.power-management: clk: Disabling unused clocks
[ 8.548820] qcom-qmp-pcie-phy 1c14000.phy: clk: Disabling unused clocks
[ 9.121849] qcom-qmp-usb-phy 88f1000.phy: clk: Disabling unused clocks
[ 9.121985] qcom-qmp-usb-phy 88ef000.phy: clk: Disabling unused clocks
[ 9.122691] qcom-edp-phy aec5a00.phy: clk: Disabling unused clocks
[ 9.122760] disp_cc-sc8280xp af00000.clock-controller: clk: Disabling unused clocks
[ 9.142121] qcom-qmp-combo-phy 88eb000.phy: clk: Disabling unused clocks
[ 9.169149] qcom-qmp-combo-phy 8903000.phy: clk: Disabling unused clocks
[ 16.057997] qcom-cpufreq-hw 18591000.cpufreq: clk: Disabling unused clocks
[ 16.058149] clk-rpmh 18200000.rsc:clock-controller: clk: Disabling unused clocks
[ 16.334879] qcom-qmp-pcie-phy 1c06000.phy: clk: Disabling unused clocks
[ 16.706113] camcc-sc8280xp ad00000.clock-controller: clk: Disabling unused clocks
[ 21.565731] q6prm-lpass-clock 3000000.remoteproc:glink-edge:gpr:service@2:clock-controller: clk: Disabling unused clocks
[ 21.597069] va_macro 3370000.codec: clk: Disabling unused clocks
[ 21.605039] rx_macro 3200000.rxmacro: clk: Disabling unused clocks
[ 21.630313] wsa_macro 3240000.codec: clk: Disabling unused clocks
[ 21.635069] tx_macro 3220000.txmacro: clk: Disabling unused clocks
Tested-by: Jens Glathe <jens.glathe@oldschoolsolutions.biz>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on AML-S905X-CC, AML-S805X-CC, BPI-M2S, BPI-M5
Tested-by: Xuyang Dong <dongxuyang@eswincomputing.com> # hfp550
Signed-off-by: Brian Masney <bmasney@redhat.com>
Link: https://www.youtube.com/watch?v=tXYzM8yLIQA
Link: https://lore.kernel.org/all/20210407034456.516204-1-saravanak@google.com/
Link: https://lore.kernel.org/all/20221227204528.1899863-1-abel.vesa@linaro.org/
---
drivers/clk/clk.c | 78 ++++++++++++++++++++++++++++++++++++++++++++---------
include/linux/clk.h | 14 ++++++++++
2 files changed, 79 insertions(+), 13 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 048adfa86a5d..2b6fae54702a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1442,14 +1442,39 @@ static void clk_core_disable_unprepare(struct clk_core *core)
clk_core_unprepare_lock(core);
}
-static void __init clk_unprepare_unused_subtree(struct clk_core *core)
+/*
+ * Returns true if @core should be skipped during an unused-clock sweep for
+ * @dev. When @dev is NULL the sweep is the global late_initcall pass; when
+ * @dev is non-NULL the sweep is a per-device sync_state pass.
+ */
+static bool clk_core_skip_unused(struct clk_core *core, struct device *dev)
+{
+ /*
+ * At late_initcall, skip clocks that belong to a device — they will be
+ * handled at sync_state time.
+ */
+ if (!dev && core->dev)
+ return true;
+
+ /* When called from sync_state, only process clocks for this device. */
+ if (dev && core->dev != dev)
+ return true;
+
+ return false;
+}
+
+static void clk_unprepare_unused_subtree(struct clk_core *core,
+ struct device *dev)
{
struct clk_core *child;
lockdep_assert_held(&prepare_lock);
hlist_for_each_entry(child, &core->children, child_node)
- clk_unprepare_unused_subtree(child);
+ clk_unprepare_unused_subtree(child, dev);
+
+ if (clk_core_skip_unused(core, dev))
+ return;
if (core->prepare_count)
return;
@@ -1467,7 +1492,8 @@ static void __init clk_unprepare_unused_subtree(struct clk_core *core)
}
}
-static void __init clk_disable_unused_subtree(struct clk_core *core)
+static void clk_disable_unused_subtree(struct clk_core *core,
+ struct device *dev)
{
struct clk_core *child;
unsigned long flags;
@@ -1475,7 +1501,10 @@ static void __init clk_disable_unused_subtree(struct clk_core *core)
lockdep_assert_held(&prepare_lock);
hlist_for_each_entry(child, &core->children, child_node)
- clk_disable_unused_subtree(child);
+ clk_disable_unused_subtree(child, dev);
+
+ if (clk_core_skip_unused(core, dev))
+ return;
if (core->flags & CLK_OPS_PARENT_ENABLE)
clk_core_prepare_enable(core->parent);
@@ -1508,7 +1537,7 @@ static void __init clk_disable_unused_subtree(struct clk_core *core)
clk_core_disable_unprepare(core->parent);
}
-static bool clk_ignore_unused __initdata;
+static bool clk_ignore_unused;
static int __init clk_ignore_unused_setup(char *__unused)
{
clk_ignore_unused = true;
@@ -1516,17 +1545,27 @@ static int __init clk_ignore_unused_setup(char *__unused)
}
__setup("clk_ignore_unused", clk_ignore_unused_setup);
-static int __init clk_disable_unused(void)
+static int __clk_disable_unused(struct device *dev)
{
struct clk_core *core;
int ret;
if (clk_ignore_unused) {
- pr_warn("clk: Not disabling unused clocks\n");
+ /*
+ * Only show this message once for the providers that are not
+ * associated with a device, which is the first pass of
+ * disabling unused clocks. Otherwise it'll show up for each
+ * clk provider as well.
+ */
+ if (!dev)
+ pr_warn("clk: Not disabling unused clocks\n");
return 0;
}
- pr_info("clk: Disabling unused clocks\n");
+ if (dev)
+ dev_info(dev, "clk: Disabling unused clocks\n");
+ else
+ pr_info("clk: Disabling unused clocks not associated with a device\n");
ret = clk_pm_runtime_get_all();
if (ret)
@@ -1538,16 +1577,16 @@ static int __init clk_disable_unused(void)
clk_prepare_lock();
hlist_for_each_entry(core, &clk_root_list, child_node)
- clk_disable_unused_subtree(core);
+ clk_disable_unused_subtree(core, dev);
hlist_for_each_entry(core, &clk_orphan_list, child_node)
- clk_disable_unused_subtree(core);
+ clk_disable_unused_subtree(core, dev);
hlist_for_each_entry(core, &clk_root_list, child_node)
- clk_unprepare_unused_subtree(core);
+ clk_unprepare_unused_subtree(core, dev);
hlist_for_each_entry(core, &clk_orphan_list, child_node)
- clk_unprepare_unused_subtree(core);
+ clk_unprepare_unused_subtree(core, dev);
clk_prepare_unlock();
@@ -1555,8 +1594,19 @@ static int __init clk_disable_unused(void)
return 0;
}
+
+static int __init clk_disable_unused(void)
+{
+ return __clk_disable_unused(NULL);
+}
late_initcall_sync(clk_disable_unused);
+void clk_sync_state(struct device *dev)
+{
+ __clk_disable_unused(dev);
+}
+EXPORT_SYMBOL_GPL(clk_sync_state);
+
static int clk_core_determine_round_nolock(struct clk_core *core,
struct clk_rate_request *req)
{
@@ -4339,8 +4389,10 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
core->dev = dev;
clk_pm_runtime_init(core);
core->of_node = np;
- if (dev && dev->driver)
+ if (dev && dev->driver) {
core->owner = dev->driver->owner;
+ dev_add_sync_state(dev, clk_sync_state);
+ }
core->hw = hw;
core->flags = init->flags;
core->num_parents = init->num_parents;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 998ba3f261da..31a0c9224c46 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -846,6 +846,20 @@ void devm_clk_put(struct device *dev, struct clk *clk);
*/
+/*
+ * clk_sync_state - sync_state callback to disable unused clocks
+ * @dev: the clock provider device whose unused clocks should be disabled
+ *
+ * It is called by the driver core once all consumers of @dev have probed,
+ * and disables any clocks belonging to @dev that are unused at that point.
+ *
+ * If a clock provider doesn't have a sync_state callback, then the framework
+ * will set up clk_sync_state() on your drivers behalf. If your driver needs
+ * a sync_state callback, then that callback also needs to call
+ * clk_sync_state().
+ */
+void clk_sync_state(struct device *dev);
+
/**
* clk_round_rate - adjust a rate to the exact rate a clock can provide
* @clk: clock source
--
2.54.0
^ permalink raw reply related
* [PATCH 2/4] pmdomain: core: migrate to dev_add_sync_state()
From: Brian Masney @ 2026-06-26 16:32 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Ulf Hansson, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Russell King, Neil Armstrong, Xuyang Dong, Jens Glathe,
Hans de Goede, Maxime Ripard, Saravana Kannan, Abel Vesa
Cc: driver-core, linux-kernel, linux-pm, linux-arm-msm, linux-clk,
Brian Masney
In-Reply-To: <20260626-clk-sync-state-v1-0-4156d8196dc8@redhat.com>
We have cases where a device node represents a provider for multiple
types of resources, like clocks, power-domains, resets, etc. Having just
a single sync_state on the device is not sufficient since other
frameworks will want to add their own sync_state callback.
Migrate the pmdomain core code from dev_set_drv_sync_state() to
dev_add_sync_state() so that this works nicely with other frameworks
that want to add their own sync_state callback.
Signed-off-by: Brian Masney <bmasney@redhat.com>
Assisted-by: Claude:claude-opus-4-6
---
drivers/pmdomain/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
index 842c4169e290..22791353249c 100644
--- a/drivers/pmdomain/core.c
+++ b/drivers/pmdomain/core.c
@@ -2697,7 +2697,7 @@ int of_genpd_add_provider_simple(struct device_node *np,
genpd->sync_state = GENPD_SYNC_STATE_SIMPLE;
device_set_node(&genpd->dev, fwnode);
} else {
- dev_set_drv_sync_state(dev, genpd_sync_state);
+ dev_add_sync_state(dev, genpd_sync_state);
}
put_device(dev);
@@ -2771,7 +2771,7 @@ int of_genpd_add_provider_onecell(struct device_node *np,
if (!dev)
sync_state = true;
else
- dev_set_drv_sync_state(dev, genpd_sync_state);
+ dev_add_sync_state(dev, genpd_sync_state);
put_device(dev);
--
2.54.0
^ permalink raw reply related
* [PATCH 3/4] driver: core: remove dev_set_drv_sync_state()
From: Brian Masney @ 2026-06-26 16:32 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Ulf Hansson, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Russell King, Neil Armstrong, Xuyang Dong, Jens Glathe,
Hans de Goede, Maxime Ripard, Saravana Kannan, Abel Vesa
Cc: driver-core, linux-kernel, linux-pm, linux-arm-msm, linux-clk,
Brian Masney
In-Reply-To: <20260626-clk-sync-state-v1-0-4156d8196dc8@redhat.com>
dev_set_drv_sync_state() is no longer used since all users have been
migrated to dev_add_sync_state(), so let's go ahead and remove it.
Signed-off-by: Brian Masney <bmasney@redhat.com>
Assisted-by: Claude:claude-opus-4-6
---
include/linux/device.h | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/include/linux/device.h b/include/linux/device.h
index b7a3dd4b56ed..7f71217ecd48 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1128,18 +1128,6 @@ static inline void device_lock_assert(struct device *dev)
lockdep_assert_held(&dev->mutex);
}
-static inline int dev_set_drv_sync_state(struct device *dev,
- void (*fn)(struct device *dev))
-{
- if (!dev || !dev->driver)
- return 0;
- if (dev->driver->sync_state && dev->driver->sync_state != fn)
- return -EBUSY;
- if (!dev->driver->sync_state)
- dev->driver->sync_state = fn;
- return 0;
-}
-
struct sync_state_entry {
struct list_head node;
void (*fn)(struct device *dev);
--
2.54.0
^ permalink raw reply related
* [PATCH 1/4] driver: core: introduce dev_add_sync_state()
From: Brian Masney @ 2026-06-26 16:32 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Ulf Hansson, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Russell King, Neil Armstrong, Xuyang Dong, Jens Glathe,
Hans de Goede, Maxime Ripard, Saravana Kannan, Abel Vesa
Cc: driver-core, linux-kernel, linux-pm, linux-arm-msm, linux-clk,
Brian Masney
In-Reply-To: <20260626-clk-sync-state-v1-0-4156d8196dc8@redhat.com>
We have cases where a device node represents a provider for multiple
types of resources, like clocks, power-domains, resets, etc. We
currently have dev_set_drv_sync_state() where a framework or driver
can set the sync_state callback for a device node, however it currently
only supports a single sync_state callback.
The pmdomain subsystem currently sets up a sync_state callback in the
core framework, and the clk subsystem will setup it's own separate
sync_state callback in the core framework. These can collide with each
other on some types of devices that have multiple types of resources.
Additionally, some clk drivers already have their own separate
sync_state callback already defined.
Let's introduce support for allowing drivers and frameworks to add their
own sync_state callback via a new function dev_add_sync_state() so that
multiple sync_state callbacks can coexist.
Link: https://lore.kernel.org/linux-clk/CAPx+jO9JiV16ePLk59hTQzEMnA96Va6Ns4jqJbwyZ6oTT0AjXA@mail.gmail.com/
Signed-off-by: Brian Masney <bmasney@redhat.com>
Assisted-by: Claude:claude-opus-4-6
---
drivers/base/base.h | 7 +++++++
drivers/base/core.c | 29 +++++++++++++++++++++++++++++
include/linux/device.h | 11 +++++++++++
3 files changed, 47 insertions(+)
diff --git a/drivers/base/base.h b/drivers/base/base.h
index a5b7abc10ff0..339db4afbeb4 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -178,6 +178,8 @@ static inline bool dev_has_sync_state(struct device *dev)
if (!dev)
return false;
+ if (!list_empty(&dev->sync_state_list))
+ return true;
drv = READ_ONCE(dev->driver);
if (drv && drv->sync_state)
return true;
@@ -188,10 +190,15 @@ static inline bool dev_has_sync_state(struct device *dev)
static inline void dev_sync_state(struct device *dev)
{
+ struct sync_state_entry *entry;
+
if (dev->bus->sync_state)
dev->bus->sync_state(dev);
else if (dev->driver && dev->driver->sync_state)
dev->driver->sync_state(dev);
+
+ list_for_each_entry(entry, &dev->sync_state_list, node)
+ entry->fn(dev);
}
int driver_add_groups(const struct device_driver *drv,
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4d026682944f..acc12f402dd3 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2612,6 +2612,7 @@ EXPORT_SYMBOL_GPL(device_show_string);
static void device_release(struct kobject *kobj)
{
struct device *dev = kobj_to_dev(kobj);
+ struct sync_state_entry *entry, *tmp;
struct device_private *p = dev->p;
/*
@@ -2625,6 +2626,11 @@ static void device_release(struct kobject *kobj)
*/
devres_release_all(dev);
+ list_for_each_entry_safe(entry, tmp, &dev->sync_state_list, node) {
+ list_del(&entry->node);
+ kfree(entry);
+ }
+
kfree(dev->dma_range_map);
kfree(dev->driver_override.name);
@@ -3239,12 +3245,35 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->links.consumers);
INIT_LIST_HEAD(&dev->links.suppliers);
INIT_LIST_HEAD(&dev->links.defer_sync);
+ INIT_LIST_HEAD(&dev->sync_state_list);
dev->links.status = DL_DEV_NO_DRIVER;
dev_assign_dma_coherent(dev, dma_default_coherent);
swiotlb_dev_init(dev);
}
EXPORT_SYMBOL_GPL(device_initialize);
+int dev_add_sync_state(struct device *dev,
+ void (*fn)(struct device *dev))
+{
+ struct sync_state_entry *entry;
+
+ if (!dev || !dev->driver)
+ return 0;
+
+ list_for_each_entry(entry, &dev->sync_state_list, node)
+ if (entry->fn == fn)
+ return 0;
+
+ entry = kmalloc_obj(*entry);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->fn = fn;
+ list_add_tail(&entry->node, &dev->sync_state_list);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_add_sync_state);
+
struct kobject *virtual_device_parent(void)
{
static struct kobject *virtual_dir = NULL;
diff --git a/include/linux/device.h b/include/linux/device.h
index 7b2baffdd2f5..b7a3dd4b56ed 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -642,6 +642,8 @@ enum struct_device_flags {
* @driver_override: Driver name to force a match. Do not touch directly; use
* device_set_driver_override() instead.
* @links: Links to suppliers and consumers of this device.
+ * @sync_state_list: List of sync_state callbacks added by subsystem
+ * frameworks (e.g. clk, genpd) via dev_add_sync_state().
* @power: For device power management.
* See Documentation/driver-api/pm/devices.rst for details.
* @pm_domain: Provide callbacks that are executed during system suspend,
@@ -723,6 +725,7 @@ struct device {
*/
struct dev_links_info links;
+ struct list_head sync_state_list;
struct dev_pm_info power;
struct dev_pm_domain *pm_domain;
@@ -1137,6 +1140,14 @@ static inline int dev_set_drv_sync_state(struct device *dev,
return 0;
}
+struct sync_state_entry {
+ struct list_head node;
+ void (*fn)(struct device *dev);
+};
+
+int dev_add_sync_state(struct device *dev,
+ void (*fn)(struct device *dev));
+
static inline void dev_set_removable(struct device *dev,
enum device_removable removable)
{
--
2.54.0
^ permalink raw reply related
* [PATCH 0/4] clk: implement sync_state support
From: Brian Masney @ 2026-06-26 16:32 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Ulf Hansson, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Russell King, Neil Armstrong, Xuyang Dong, Jens Glathe,
Hans de Goede, Maxime Ripard, Saravana Kannan, Abel Vesa
Cc: driver-core, linux-kernel, linux-pm, linux-arm-msm, linux-clk,
Brian Masney
The existing support for disabling unused clks runs in the late initcall
stage, and it has been known for a long time that this is broken since
it runs too early in the boot up process. It doesn't work for kernel
modules, and it also doesn't work if all of the consumers haven't fully
probed yet. Folks have long recommended to boot certain platforms with
clk_ignore_unused to work around issues with disabling unused clks.
This series fixes this by adding support for sync_state to the clk
subsystem.
Changes in v3:
- Allow multiple sync_state callbacks in the driver core via a new
helper dev_add_sync_state(). This allows dropping changes to the QC
drivers that already have a sync_state callback since everything can
coexist without changes. This also makes it so that this can coexist
with the pmdomain subsystem.
- Only show "clk: Not disabling unused clocks" message once.
- Add Tested-by from Neil and Xuyang
- Link to v2: https://lore.kernel.org/linux-clk/20260616-clk-sync-state-v2-0-15f82c64d95c@redhat.com/
Changes in v2:
- Split out clk-cbf-8996.c into it's own patch, and don't call
qcom_cc_sync_state().
- Clarify comment above call to dev_set_drv_sync_state() about
the -EBUSY.
- Added Tested-by from Jens
- Link to v1: https://lore.kernel.org/r/20260603-clk-sync-state-v1-0-457120eed200@redhat.com
Signed-off-by: Brian Masney <bmasney@redhat.com>
---
Brian Masney (4):
driver: core: introduce dev_add_sync_state()
pmdomain: core: migrate to dev_add_sync_state()
driver: core: remove dev_set_drv_sync_state()
clk: implement sync_state support
drivers/base/base.h | 7 +++++
drivers/base/core.c | 29 ++++++++++++++++++
drivers/clk/clk.c | 78 ++++++++++++++++++++++++++++++++++++++++---------
drivers/pmdomain/core.c | 4 +--
include/linux/clk.h | 14 +++++++++
include/linux/device.h | 21 +++++++------
6 files changed, 127 insertions(+), 26 deletions(-)
---
base-commit: 6c94b38b83a04c43ea49004275f0391404051093
change-id: 20260626-clk-sync-state-ad008829a689
Best regards,
--
Brian Masney <bmasney@redhat.com>
^ permalink raw reply
* [PATCH v5 20/20] rust: io: implement `IoSysMap`
From: Gary Guo @ 2026-06-26 14:45 UTC (permalink / raw)
To: Alice Ryhl, Daniel Almeida, Greg Kroah-Hartman, Rafael J. Wysocki,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Tamir Duberstein,
Onur Özkan, Bjorn Helgaas, Krzysztof Wilczyński,
Abdiel Janulgue, Robin Murphy, Alexandre Courbot, David Airlie,
Simona Vetter, Michal Wilczynski, Uwe Kleine-König
Cc: Danilo Krummrich, driver-core, rust-for-linux, linux-kernel,
linux-pci, nova-gpu, dri-devel, linux-pwm
In-Reply-To: <20260626-io_projection-v5-0-d0961471ae50@garyguo.net>
Add an enum as sum type for `Mmio` and `SysMem`. This serves similar
purpose of `iosys_map`. Thanks to Rust's type system, all of projection and
struct read/write can be handled by the generic I/O projection mechanism
(i.e. `io_project!`, `io_read!, `io_write!`) for free, and there is no need
to provide things like `iosys_map_rd_field` or `iosys_map_wr_field`. An
enum type also makes it very easy to construct or destruct.
This could be made more generic by implementing on a general purpose sum
type like `Either`; however this is kept specific unless a need arises that
warrants this to be generic over other I/O backends.
Signed-off-by: Gary Guo <gary@garyguo.net>
---
rust/kernel/io.rs | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 137 insertions(+)
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index b5ac3ac86bbd..0c5f53dd0939 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -1446,6 +1446,143 @@ fn as_view(self) -> <Self::Backend as IoBackend>::View<'a, Self::Target> {
}
}
+/// I/O Backend for [`IoSysMap`].
+pub struct IoSysMapBackend;
+
+/// Either [`Mmio`] or [`SysMem`].
+///
+/// This can be used when a piece of logic may wish to handle both MMIO or system memory but does
+/// not want or cannot be generic over I/O backends. This serves a similar purpose to
+/// [`include/linux/iosys-map.h`] in C.
+///
+/// This type can be used like any other types that implements [`Io`]; this also include
+/// [`io_project!`], [`io_read!`], [`io_write!`].
+///
+/// [`include/linux/iosys-map.h`](srctree/include/linux/iosys-map.h)
+pub enum IoSysMap<'a, T: ?Sized> {
+ /// The view is I/O memory.
+ Io(Mmio<'a, T>),
+ /// The view is system memory.
+ Sys(SysMem<'a, T>),
+}
+
+impl<T: ?Sized> Copy for IoSysMap<'_, T> {}
+impl<T: ?Sized> Clone for IoSysMap<'_, T> {
+ #[inline]
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'a, T: ?Sized> From<Mmio<'a, T>> for IoSysMap<'a, T> {
+ #[inline]
+ fn from(value: Mmio<'a, T>) -> Self {
+ IoSysMap::Io(value)
+ }
+}
+
+impl<'a, T: ?Sized> From<SysMem<'a, T>> for IoSysMap<'a, T> {
+ #[inline]
+ fn from(value: SysMem<'a, T>) -> Self {
+ IoSysMap::Sys(value)
+ }
+}
+
+impl IoBackend for IoSysMapBackend {
+ type View<'a, T: ?Sized + KnownSize> = IoSysMap<'a, T>;
+
+ #[inline]
+ fn as_ptr<'a, T: ?Sized + KnownSize>(view: Self::View<'a, T>) -> *mut T {
+ match view {
+ IoSysMap::Io(l) => MmioBackend::as_ptr(l),
+ IoSysMap::Sys(r) => SysMemBackend::as_ptr(r),
+ }
+ }
+
+ #[inline]
+ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
+ view: Self::View<'a, T>,
+ ptr: *mut U,
+ ) -> Self::View<'a, U> {
+ match view {
+ // SAFETY: Per safety requirement.
+ IoSysMap::Io(l) => IoSysMap::Io(unsafe { MmioBackend::project_view(l, ptr) }),
+ // SAFETY: Per safety requirement.
+ IoSysMap::Sys(r) => IoSysMap::Sys(unsafe { SysMemBackend::project_view(r, ptr) }),
+ }
+ }
+}
+
+impl<T> IoCapable<T> for IoSysMapBackend
+where
+ MmioBackend: IoCapable<T>,
+ SysMemBackend: IoCapable<T>,
+{
+ #[inline]
+ fn io_read(view: Self::View<'_, T>) -> T {
+ match view {
+ IoSysMap::Io(l) => MmioBackend::io_read(l),
+ IoSysMap::Sys(r) => SysMemBackend::io_read(r),
+ }
+ }
+
+ #[inline]
+ fn io_write<'a>(view: Self::View<'a, T>, value: T) {
+ match view {
+ IoSysMap::Io(l) => MmioBackend::io_write(l, value),
+ IoSysMap::Sys(r) => SysMemBackend::io_write(r, value),
+ }
+ }
+}
+
+impl IoCopyable for IoSysMapBackend {
+ #[inline]
+ unsafe fn copy_from_io(view: Self::View<'_, [u8]>, buffer: *mut u8) {
+ match view {
+ // SAFETY: Per safety requirement.
+ IoSysMap::Io(l) => unsafe { MmioBackend::copy_from_io(l, buffer) },
+ // SAFETY: Per safety requirement.
+ IoSysMap::Sys(r) => unsafe { SysMemBackend::copy_from_io(r, buffer) },
+ }
+ }
+
+ #[inline]
+ unsafe fn copy_to_io(view: Self::View<'_, [u8]>, buffer: *const u8) {
+ match view {
+ // SAFETY: Per safety requirement.
+ IoSysMap::Io(l) => unsafe { MmioBackend::copy_to_io(l, buffer) },
+ // SAFETY: Per safety requirement.
+ IoSysMap::Sys(r) => unsafe { SysMemBackend::copy_to_io(r, buffer) },
+ }
+ }
+
+ #[inline]
+ fn copy_read<T: FromBytes>(view: Self::View<'_, T>) -> T {
+ match view {
+ IoSysMap::Io(l) => MmioBackend::copy_read(l),
+ IoSysMap::Sys(r) => SysMemBackend::copy_read(r),
+ }
+ }
+
+ #[inline]
+ fn copy_write<T: IntoBytes>(view: Self::View<'_, T>, value: T) {
+ match view {
+ IoSysMap::Io(l) => MmioBackend::copy_write(l, value),
+ IoSysMap::Sys(r) => SysMemBackend::copy_write(r, value),
+ }
+ }
+}
+
+impl<'a, T: ?Sized + KnownSize> IoBase<'a> for IoSysMap<'a, T> {
+ type Backend = IoSysMapBackend;
+ type Target = T;
+
+ #[inline]
+ fn as_view(self) -> IoSysMap<'a, T> {
+ self
+ }
+}
+
// This helper turns associated functions to methods so it can be invoked in macro.
// Used by `io_project!()` only.
#[doc(hidden)]
--
2.54.0
^ permalink raw reply related
* [PATCH v5 18/20] rust: dma: drop `dma_read!` and `dma_write!` API
From: Gary Guo @ 2026-06-26 14:45 UTC (permalink / raw)
To: Alice Ryhl, Daniel Almeida, Greg Kroah-Hartman, Rafael J. Wysocki,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Tamir Duberstein,
Onur Özkan, Bjorn Helgaas, Krzysztof Wilczyński,
Abdiel Janulgue, Robin Murphy, Alexandre Courbot, David Airlie,
Simona Vetter, Michal Wilczynski, Uwe Kleine-König
Cc: Danilo Krummrich, driver-core, rust-for-linux, linux-kernel,
linux-pci, nova-gpu, dri-devel, linux-pwm
In-Reply-To: <20260626-io_projection-v5-0-d0961471ae50@garyguo.net>
The primitive read/write use case is covered by the `io_read!` and
`io_write!` macro. The non-primitive use case was finicky; they should
either be achieved using `CoherentBox` or `as_ref()/as_mut()` to assert the
lack of concurrent access, or should be using memcpy-like APIs to express
the non-atomic and tearable nature.
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
rust/kernel/dma.rs | 128 -----------------------------------------------
samples/rust/rust_dma.rs | 13 ++---
2 files changed, 7 insertions(+), 134 deletions(-)
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index ab6504910e4f..0ff4cce8e809 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -661,52 +661,6 @@ pub unsafe fn as_mut(&self) -> &mut T {
// SAFETY: per safety requirement.
unsafe { &mut *self.as_mut_ptr() }
}
-
- /// Reads the value of `field` and ensures that its type is [`FromBytes`].
- ///
- /// # Safety
- ///
- /// This must be called from the [`dma_read`] macro which ensures that the `field` pointer is
- /// validated beforehand.
- ///
- /// Public but hidden since it should only be used from [`dma_read`] macro.
- #[doc(hidden)]
- pub unsafe fn field_read<F: FromBytes>(&self, field: *const F) -> F {
- // SAFETY:
- // - By the safety requirements field is valid.
- // - Using read_volatile() here is not sound as per the usual rules, the usage here is
- // a special exception with the following notes in place. When dealing with a potential
- // race from a hardware or code outside kernel (e.g. user-space program), we need that
- // read on a valid memory is not UB. Currently read_volatile() is used for this, and the
- // rationale behind is that it should generate the same code as READ_ONCE() which the
- // kernel already relies on to avoid UB on data races. Note that the usage of
- // read_volatile() is limited to this particular case, it cannot be used to prevent
- // the UB caused by racing between two kernel functions nor do they provide atomicity.
- unsafe { field.read_volatile() }
- }
-
- /// Writes a value to `field` and ensures that its type is [`AsBytes`].
- ///
- /// # Safety
- ///
- /// This must be called from the [`dma_write`] macro which ensures that the `field` pointer is
- /// validated beforehand.
- ///
- /// Public but hidden since it should only be used from [`dma_write`] macro.
- #[doc(hidden)]
- pub unsafe fn field_write<F: AsBytes>(&self, field: *mut F, val: F) {
- // SAFETY:
- // - By the safety requirements field is valid.
- // - Using write_volatile() here is not sound as per the usual rules, the usage here is
- // a special exception with the following notes in place. When dealing with a potential
- // race from a hardware or code outside kernel (e.g. user-space program), we need that
- // write on a valid memory is not UB. Currently write_volatile() is used for this, and the
- // rationale behind is that it should generate the same code as WRITE_ONCE() which the
- // kernel already relies on to avoid UB on data races. Note that the usage of
- // write_volatile() is limited to this particular case, it cannot be used to prevent
- // the UB caused by racing between two kernel functions nor do they provide atomicity.
- unsafe { field.write_volatile(val) }
- }
}
impl<T: AsBytes + FromBytes> Coherent<T> {
@@ -1265,85 +1219,3 @@ fn as_view(self) -> CoherentView<'a, Self::Target> {
}
}
}
-
-/// Reads a field of an item from an allocated region of structs.
-///
-/// The syntax is of the form `kernel::dma_read!(dma, proj)` where `dma` is an expression evaluating
-/// to a [`Coherent`] and `proj` is a [projection specification](kernel::ptr::project!).
-///
-/// # Examples
-///
-/// ```
-/// use kernel::device::Device;
-/// use kernel::dma::{attrs::*, Coherent};
-///
-/// struct MyStruct { field: u32, }
-///
-/// // SAFETY: All bit patterns are acceptable values for `MyStruct`.
-/// unsafe impl kernel::transmute::FromBytes for MyStruct{};
-/// // SAFETY: Instances of `MyStruct` have no uninitialized portions.
-/// unsafe impl kernel::transmute::AsBytes for MyStruct{};
-///
-/// # fn test(alloc: &kernel::dma::Coherent<[MyStruct]>) -> Result {
-/// let whole = kernel::dma_read!(alloc, [try: 2]);
-/// let field = kernel::dma_read!(alloc, [panic: 1].field);
-/// # Ok::<(), Error>(()) }
-/// ```
-#[macro_export]
-macro_rules! dma_read {
- ($dma:expr, $($proj:tt)*) => {{
- let dma = &$dma;
- let ptr = $crate::ptr::project!(
- $crate::dma::Coherent::as_ptr(dma), $($proj)*
- );
- // SAFETY: The pointer created by the projection is within the DMA region.
- unsafe { $crate::dma::Coherent::field_read(dma, ptr) }
- }};
-}
-
-/// Writes to a field of an item from an allocated region of structs.
-///
-/// The syntax is of the form `kernel::dma_write!(dma, proj, val)` where `dma` is an expression
-/// evaluating to a [`Coherent`], `proj` is a
-/// [projection specification](kernel::ptr::project!), and `val` is the value to be written to the
-/// projected location.
-///
-/// # Examples
-///
-/// ```
-/// use kernel::device::Device;
-/// use kernel::dma::{attrs::*, Coherent};
-///
-/// struct MyStruct { member: u32, }
-///
-/// // SAFETY: All bit patterns are acceptable values for `MyStruct`.
-/// unsafe impl kernel::transmute::FromBytes for MyStruct{};
-/// // SAFETY: Instances of `MyStruct` have no uninitialized portions.
-/// unsafe impl kernel::transmute::AsBytes for MyStruct{};
-///
-/// # fn test(alloc: &kernel::dma::Coherent<[MyStruct]>) -> Result {
-/// kernel::dma_write!(alloc, [try: 2].member, 0xf);
-/// kernel::dma_write!(alloc, [panic: 1], MyStruct { member: 0xf });
-/// # Ok::<(), Error>(()) }
-/// ```
-#[macro_export]
-macro_rules! dma_write {
- (@parse [$dma:expr] [$($proj:tt)*] [, $val:expr]) => {{
- let dma = &$dma;
- let ptr = $crate::ptr::project!(
- mut $crate::dma::Coherent::as_mut_ptr(dma), $($proj)*
- );
- let val = $val;
- // SAFETY: The pointer created by the projection is within the DMA region.
- unsafe { $crate::dma::Coherent::field_write(dma, ptr, val) }
- }};
- (@parse [$dma:expr] [$($proj:tt)*] [.$field:tt $($rest:tt)*]) => {
- $crate::dma_write!(@parse [$dma] [$($proj)* .$field] [$($rest)*])
- };
- (@parse [$dma:expr] [$($proj:tt)*] [[$flavor:ident: $index:expr] $($rest:tt)*]) => {
- $crate::dma_write!(@parse [$dma] [$($proj)* [$flavor: $index]] [$($rest)*])
- };
- ($dma:expr, $($rest:tt)*) => {
- $crate::dma_write!(@parse [$dma] [] [$($rest)*])
- };
-}
diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs
index 5046b4628d0e..6727c441658a 100644
--- a/samples/rust/rust_dma.rs
+++ b/samples/rust/rust_dma.rs
@@ -12,6 +12,7 @@
Device,
DmaMask, //
},
+ io::io_read,
page, pci,
prelude::*,
scatterlist::{Owned, SGTable},
@@ -73,11 +74,11 @@ fn probe<'bound>(
// SAFETY: There are no concurrent calls to DMA allocation and mapping primitives.
unsafe { pdev.dma_set_mask_and_coherent(mask)? };
- let ca: Coherent<[MyStruct]> =
- Coherent::zeroed_slice(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
+ let mut ca: CoherentBox<[MyStruct]> =
+ CoherentBox::zeroed_slice(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
for (i, value) in TEST_VALUES.into_iter().enumerate() {
- kernel::dma_write!(ca, [try: i], MyStruct::new(value.0, value.1));
+ ca.init_at(i, MyStruct::new(value.0, value.1))?;
}
let size = 4 * page::PAGE_SIZE;
@@ -87,7 +88,7 @@ fn probe<'bound>(
Ok(try_pin_init!(Self {
pdev: pdev.into(),
- ca,
+ ca: ca.into(),
sgt <- sgt,
}))
})
@@ -97,8 +98,8 @@ fn probe<'bound>(
impl DmaSampleDriver {
fn check_dma(&self) {
for (i, value) in TEST_VALUES.into_iter().enumerate() {
- let val0 = kernel::dma_read!(self.ca, [panic: i].h);
- let val1 = kernel::dma_read!(self.ca, [panic: i].b);
+ let val0 = io_read!(self.ca, [panic: i].h);
+ let val1 = io_read!(self.ca, [panic: i].b);
assert_eq!(val0, value.0);
assert_eq!(val1, value.1);
--
2.54.0
^ permalink raw reply related
page: next (older)
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox