summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/arm64/apmt.c2
-rw-r--r--drivers/acpi/arm64/iort.c2
-rw-r--r--drivers/acpi/bus.c6
-rw-r--r--drivers/base/Kconfig9
-rw-r--r--drivers/base/arch_numa.c4
-rw-r--r--drivers/base/attribute_container.c7
-rw-r--r--drivers/base/core.c8
-rw-r--r--drivers/base/dd.c4
-rw-r--r--drivers/base/firmware_loader/builtin/Makefile32
-rw-r--r--drivers/base/firmware_loader/builtin/main.c2
-rw-r--r--drivers/base/firmware_loader/fallback.c10
-rw-r--r--drivers/base/isa.c16
-rw-r--r--drivers/base/module.c2
-rw-r--r--drivers/base/platform.c90
-rw-r--r--drivers/base/property.c41
-rw-r--r--drivers/base/soc.c15
-rw-r--r--drivers/base/swnode.c2
-rw-r--r--drivers/base/test/Kconfig1
-rw-r--r--drivers/base/test/platform-device-test.c180
-rw-r--r--drivers/base/test/property-entry-test.c137
-rw-r--r--drivers/base/transport_class.c5
-rw-r--r--drivers/cpufreq/rcpufreq_dt.rs1
-rw-r--r--drivers/gpu/drm/nova/driver.rs1
-rw-r--r--drivers/gpu/drm/tyr/driver.rs1
-rw-r--r--drivers/gpu/drm/xe/xe_i2c.c22
-rw-r--r--drivers/gpu/drm/xe/xe_i2c.h1
-rw-r--r--drivers/gpu/nova-core/driver.rs7
-rw-r--r--drivers/gpu/nova-core/gpu.rs6
-rw-r--r--drivers/gpu/nova-core/gsp.rs53
-rw-r--r--drivers/gpu/nova-core/gsp/cmdq.rs66
-rw-r--r--drivers/gpu/nova-core/gsp/fw.rs82
-rw-r--r--drivers/i2c/busses/i2c-pxa-pci.c3
-rw-r--r--drivers/iommu/fsl_pamu.c16
-rw-r--r--drivers/mfd/tps6586x.c2
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c3
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c2
-rw-r--r--drivers/of/kobj.c3
-rw-r--r--drivers/of/platform.c2
-rw-r--r--drivers/platform/surface/surface_gpe.c38
-rw-r--r--drivers/pmdomain/imx/gpc.c3
-rw-r--r--drivers/pwm/pwm_th1520.rs13
-rw-r--r--drivers/reset/reset-rzg2l-usbphy-ctrl.c2
-rw-r--r--drivers/slimbus/qcom-ngd-ctrl.c2
-rw-r--r--drivers/tty/serdev/Kconfig7
-rw-r--r--drivers/usb/chipidea/core.c2
-rw-r--r--drivers/usb/musb/jz4740.c2
46 files changed, 645 insertions, 270 deletions
diff --git a/drivers/acpi/arm64/apmt.c b/drivers/acpi/arm64/apmt.c
index 91fcdd289..8ad049f81 100644
--- a/drivers/acpi/arm64/apmt.c
+++ b/drivers/acpi/arm64/apmt.c
@@ -101,7 +101,7 @@ static int __init apmt_add_platform_device(struct acpi_apmt_node *node,
if (ret)
goto dev_put;
- pdev->dev.fwnode = fwnode;
+ platform_device_set_fwnode(pdev, fwnode);
ret = platform_device_add(pdev);
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 34412cd69..1020ac953 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -1992,7 +1992,7 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node,
goto dev_put;
}
- pdev->dev.fwnode = fwnode;
+ platform_device_set_fwnode(pdev, fwnode);
if (ops->dev_dma_configure)
ops->dev_dma_configure(&pdev->dev, node);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c1876f145..beb51151a 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -871,9 +871,9 @@ const struct acpi_device *acpi_companion_match(const struct device *dev)
* identifiers and a _DSD object with the "compatible" property, use that
* property to match against the given list of identifiers.
*/
-bool acpi_of_match_device(const struct acpi_device *adev,
- const struct of_device_id *of_match_table,
- const struct of_device_id **of_id)
+static bool acpi_of_match_device(const struct acpi_device *adev,
+ const struct of_device_id *of_match_table,
+ const struct of_device_id **of_id)
{
const union acpi_object *of_compatible, *obj;
int i, nval;
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index f7d385cbd..43f20ca95 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -222,15 +222,6 @@ config DMA_SHARED_BUFFER
APIs extension; the file's descriptor can then be passed on to other
driver.
-config DMA_FENCE_TRACE
- bool "Enable verbose DMA_FENCE_TRACE messages"
- depends on DMA_SHARED_BUFFER
- help
- Enable the DMA_FENCE_TRACE printks. This will add extra
- spam to the console log, but will make it easier to diagnose
- lockup related problems for dma-buffers shared across multiple
- devices.
-
config GENERIC_ARCH_TOPOLOGY
bool
help
diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c
index d4e426aa5..6476227b7 100644
--- a/drivers/base/arch_numa.c
+++ b/drivers/base/arch_numa.c
@@ -228,10 +228,6 @@ static int __init numa_init(int (*init_func)(void))
{
int ret;
- nodes_clear(numa_nodes_parsed);
- nodes_clear(node_possible_map);
- nodes_clear(node_online_map);
-
ret = numa_memblks_init(init_func, /* memblock_force_top_down */ false);
if (ret < 0)
goto out_free_distance;
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 4ad26b8dd..3c4563742 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -425,7 +425,12 @@ attribute_container_add_class_device(struct device *classdev)
if (error)
return error;
- return attribute_container_add_attrs(classdev);
+
+ error = attribute_container_add_attrs(classdev);
+ if (error)
+ device_del(classdev);
+
+ return error;
}
/**
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4d0266829..4c0c37399 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -127,7 +127,13 @@ static void __fwnode_link_cycle(struct fwnode_link *link)
{
pr_debug("%pfwf: cycle: depends on %pfwf\n",
link->consumer, link->supplier);
+
+ if (link->flags & FWLINK_FLAG_CYCLE)
+ return;
+
link->flags |= FWLINK_FLAG_CYCLE;
+ pr_info("%pfwf: Fixed dependency cycle(s) with %pfwf\n",
+ link->consumer, link->supplier);
}
/**
@@ -2206,8 +2212,6 @@ static int fw_devlink_create_devlink(struct device *con,
if (__fw_devlink_relax_cycles(link->consumer, sup_handle)) {
__fwnode_link_cycle(link);
pr_debug("----- cycle: end -----\n");
- pr_info("%pfwf: Fixed dependency cycle(s) with %pfwf\n",
- link->consumer, sup_handle);
}
device_links_write_unlock();
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 60c005223..f6525a7ee 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -790,8 +790,8 @@ static int really_probe_debug(struct device *dev, const struct device_driver *dr
* CONFIG_DYNAMIC_DEBUG and we want a simple 'initcall_debug' on the
* kernel commandline to print this all the time at the debug level.
*/
- printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n",
- dev_name(dev), ret, ktime_us_delta(rettime, calltime));
+ printk(KERN_DEBUG "probe of %s with driver %s returned %d after %lld usecs\n",
+ dev_name(dev), drv->name, ret, ktime_us_delta(rettime, calltime));
return ret;
}
diff --git a/drivers/base/firmware_loader/builtin/Makefile b/drivers/base/firmware_loader/builtin/Makefile
index 6c067dedc..c0264b15d 100644
--- a/drivers/base/firmware_loader/builtin/Makefile
+++ b/drivers/base/firmware_loader/builtin/Makefile
@@ -16,20 +16,24 @@ ASM_ALIGN = $(if $(CONFIG_64BIT),3,2)
PROGBITS = $(if $(CONFIG_ARM),%,@)progbits
filechk_fwbin = \
- echo "/* Generated by $(src)/Makefile */" ;\
- echo " .section .rodata" ;\
- echo " .p2align 4" ;\
- echo "_fw_$(FWSTR)_bin:" ;\
- echo " .incbin \"$(fwdir)/$(FWNAME)\"" ;\
- echo "_fw_end:" ;\
- echo " .section .rodata.str,\"aMS\",$(PROGBITS),1" ;\
- echo " .p2align $(ASM_ALIGN)" ;\
- echo "_fw_$(FWSTR)_name:" ;\
- echo " .string \"$(FWNAME)\"" ;\
- echo " .section .builtin_fw,\"a\",$(PROGBITS)" ;\
- echo " .p2align $(ASM_ALIGN)" ;\
- echo " $(ASM_WORD) _fw_$(FWSTR)_name" ;\
- echo " $(ASM_WORD) _fw_$(FWSTR)_bin" ;\
+ if [ ! -s "$(fwdir)/$(FWNAME)" ]; then \
+ echo "error: empty firmware: $(fwdir)/$(FWNAME)" >&2 ;\
+ exit 1 ;\
+ fi ;\
+ echo "/* Generated by $(src)/Makefile */" ;\
+ echo " .section .rodata" ;\
+ echo " .p2align 4" ;\
+ echo "_fw_$(FWSTR)_bin:" ;\
+ echo " .incbin \"$(fwdir)/$(FWNAME)\"" ;\
+ echo "_fw_end:" ;\
+ echo " .section .rodata.str,\"aMS\",$(PROGBITS),1" ;\
+ echo " .p2align $(ASM_ALIGN)" ;\
+ echo "_fw_$(FWSTR)_name:" ;\
+ echo " .string \"$(FWNAME)\"" ;\
+ echo " .section .builtin_fw,\"a\",$(PROGBITS)" ;\
+ echo " .p2align $(ASM_ALIGN)" ;\
+ echo " $(ASM_WORD) _fw_$(FWSTR)_name" ;\
+ echo " $(ASM_WORD) _fw_$(FWSTR)_bin" ;\
echo " $(ASM_WORD) _fw_end - _fw_$(FWSTR)_bin"
$(obj)/%.gen.S: FORCE
diff --git a/drivers/base/firmware_loader/builtin/main.c b/drivers/base/firmware_loader/builtin/main.c
index d36befebb..1dcebe8e7 100644
--- a/drivers/base/firmware_loader/builtin/main.c
+++ b/drivers/base/firmware_loader/builtin/main.c
@@ -53,6 +53,8 @@ bool firmware_request_builtin(struct firmware *fw, const char *name)
for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
if (strcmp(name, b_fw->name) == 0) {
+ if (b_fw->size == 0)
+ return false;
fw->size = b_fw->size;
fw->data = b_fw->data;
return true;
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 3ef0b312a..00d6b6e59 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -95,6 +95,16 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout)
retval = -EINTR;
goto out;
}
+
+ /*
+ * device_add() exposes the loading interface before pending_list is
+ * linked into pending_fw_head, so fw_state_done() may run first.
+ */
+ if (fw_state_is_done(fw_priv)) {
+ mutex_unlock(&fw_lock);
+ goto out;
+ }
+
list_add(&fw_priv->pending_list, &pending_fw_head);
mutex_unlock(&fw_lock);
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
index 5887e4211..4e9f68080 100644
--- a/drivers/base/isa.c
+++ b/drivers/base/isa.c
@@ -166,14 +166,16 @@ static int __init isa_bus_init(void)
int error;
error = bus_register(&isa_bus_type);
- if (!error) {
- isa_bus = root_device_register("isa");
- if (IS_ERR(isa_bus)) {
- error = PTR_ERR(isa_bus);
- bus_unregister(&isa_bus_type);
- }
+ if (error)
+ return error;
+
+ isa_bus = root_device_register("isa");
+ if (IS_ERR(isa_bus)) {
+ bus_unregister(&isa_bus_type);
+ return PTR_ERR(isa_bus);
}
- return error;
+
+ return 0;
}
postcore_initcall(isa_bus_init);
diff --git a/drivers/base/module.c b/drivers/base/module.c
index 218aaa096..6789dca48 100644
--- a/drivers/base/module.c
+++ b/drivers/base/module.c
@@ -42,7 +42,7 @@ int module_add_driver(struct module *mod, const struct device_driver *drv)
if (mod)
mk = &mod->mkobj;
else if (drv->mod_name) {
- /* Lookup or create built-in module entry in /sys/modules */
+ /* Lookup or create built-in module entry in /sys/module */
mk = lookup_or_create_module_kobject(drv->mod_name);
if (mk) {
/* remember our module structure */
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index fb9120b0b..66f9ec73d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -599,19 +599,19 @@ static void platform_device_release(struct device *dev)
struct platform_object *pa = container_of(dev, struct platform_object,
pdev.dev);
- of_node_put(pa->pdev.dev.of_node);
+ device_remove_software_node(dev);
+ /*
+ * If the primary firmware node is a software node, its reference count
+ * was already decreased by the call to device_remove_software_node().
+ */
+ if (!is_software_node(dev_fwnode(dev)))
+ fwnode_handle_put(pa->pdev.dev.fwnode);
kfree(pa->pdev.dev.platform_data);
kfree(pa->pdev.mfd_cell);
kfree(pa->pdev.resource);
kfree(pa);
}
-static void platform_device_release_full(struct device *dev)
-{
- device_remove_software_node(dev);
- platform_device_release(dev);
-}
-
/**
* platform_device_alloc - create a platform device
* @name: base name of the device we're adding
@@ -619,6 +619,13 @@ static void platform_device_release_full(struct device *dev)
*
* Create a platform device object which can have other objects attached
* to it, and which will have attached objects freed when it is released.
+ *
+ * The following fields of the dynamically allocated platform device must not
+ * be modified manually: resource, num_resources, dev.platform_data,
+ * dev.of_node and dev.fwnode. Users wishing to do the split platform device
+ * registration with platform_device_alloc() + platform_device_add() are
+ * required to use dedicated helpers for adding resources, platform data or
+ * assigning firmware nodes.
*/
struct platform_device *platform_device_alloc(const char *name, int id)
{
@@ -694,6 +701,70 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
EXPORT_SYMBOL_GPL(platform_device_add_data);
/**
+ * platform_device_set_of_node - assign an OF node to device
+ * @pdev: platform device to add the node for
+ * @np: new device node
+ *
+ * Assign an OF node to this platform device. Internally keep track of the
+ * reference count. Devices created with platform_device_alloc() must use this
+ * function instead of assigning the node manually. This function must not be
+ * called for a platform device that already has a software node as its primary
+ * firmware node assigned.
+ */
+void platform_device_set_of_node(struct platform_device *pdev,
+ struct device_node *np)
+{
+ platform_device_set_fwnode(pdev, of_fwnode_handle(np));
+}
+EXPORT_SYMBOL_GPL(platform_device_set_of_node);
+
+/**
+ * platform_device_set_fwnode - assign a firmware node to device
+ * @pdev: platform device to set the node for
+ * @fwnode: new firmware node
+ *
+ * Assign a firmware node to this platform device. Internally keep track of the
+ * reference count. Devices created with platform_device_alloc() must use this
+ * function instead of assigning the node manually. This function must not be
+ * called for a platform device that already has a software node as its primary
+ * firmware node assigned.
+ */
+void platform_device_set_fwnode(struct platform_device *pdev,
+ struct fwnode_handle *fwnode)
+{
+ /*
+ * If we call this function for a platform device whose primary
+ * firmware node is a software node, we'll never end up calling the
+ * symmetric software_node_notify_remove(). There are no users for this
+ * right now in the tree so just disallow it.
+ */
+ WARN_ON(is_software_node(dev_fwnode(&pdev->dev)));
+ fwnode_handle_put(pdev->dev.fwnode);
+ device_set_node(&pdev->dev, fwnode_handle_get(fwnode));
+}
+EXPORT_SYMBOL_GPL(platform_device_set_fwnode);
+
+/**
+ * platform_device_set_of_node_from_dev - reuse OF node of another device
+ * @pdev: platform device to set the node for
+ * @dev2: device whose OF node to reuse
+ *
+ * Reuses the OF node of another device in this platform device while
+ * internally keeping track of reference counting. This function must not be
+ * called for a platform device that already has a software node as its primary
+ * firmware node assigned.
+ */
+void platform_device_set_of_node_from_dev(struct platform_device *pdev,
+ const struct device *dev2)
+{
+ /* See platform_device_set_fwnode(). */
+ WARN_ON(is_software_node(dev_fwnode(&pdev->dev)));
+ device_set_of_node_from_dev(&pdev->dev, dev2);
+ pdev->dev.fwnode = of_fwnode_handle(pdev->dev.of_node);
+}
+EXPORT_SYMBOL_GPL(platform_device_set_of_node_from_dev);
+
+/**
* platform_device_add - add a platform device to device hierarchy
* @pdev: platform device we're adding
*
@@ -868,8 +939,7 @@ struct platform_device *platform_device_register_full(const struct platform_devi
return ERR_PTR(-ENOMEM);
pdev->dev.parent = pdevinfo->parent;
- pdev->dev.fwnode = pdevinfo->fwnode;
- pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
+ device_set_node(&pdev->dev, fwnode_handle_get(pdevinfo->fwnode));
dev_assign_of_node_reused(&pdev->dev, pdevinfo->of_node_reused);
if (pdevinfo->dma_mask) {
@@ -890,8 +960,6 @@ struct platform_device *platform_device_register_full(const struct platform_devi
ret = device_add_software_node(&pdev->dev, pdevinfo->swnode);
if (ret)
goto err;
-
- pdev->dev.release = platform_device_release_full;
} else if (pdevinfo->properties) {
ret = device_create_managed_software_node(&pdev->dev,
pdevinfo->properties, NULL);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index e08eadd66..b136c339d 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -7,10 +7,10 @@
* Mika Westerberg <mika.westerberg@linux.intel.com>
*/
+#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
-#include <linux/kconfig.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/phy.h>
@@ -517,7 +517,6 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string);
int fwnode_property_match_string(const struct fwnode_handle *fwnode,
const char *propname, const char *string)
{
- const char **values;
int nval, ret;
nval = fwnode_property_string_array_count(fwnode, propname);
@@ -527,20 +526,18 @@ int fwnode_property_match_string(const struct fwnode_handle *fwnode,
if (nval == 0)
return -ENODATA;
- values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
+ const char **values __free(kfree) = kcalloc(nval, sizeof(*values), GFP_KERNEL);
if (!values)
return -ENOMEM;
ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
if (ret < 0)
- goto out_free;
+ return ret;
ret = match_string(values, nval, string);
if (ret < 0)
- ret = -ENODATA;
+ return -ENODATA;
-out_free:
- kfree(values);
return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_match_string);
@@ -807,18 +804,31 @@ struct fwnode_handle *
fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
+ const struct fwnode_handle *parent;
+ struct fwnode_handle *child_parent __free(fwnode_handle) = NULL;
struct fwnode_handle *next;
- if (IS_ERR_OR_NULL(fwnode))
+ /*
+ * If this function is in a loop and the previous iteration returned
+ * an child from fwnode->secondary, then we need to use the secondary
+ * as parent rather than @fwnode.
+ */
+ if (child) {
+ child_parent = fwnode_get_parent(child);
+ parent = child_parent;
+ } else {
+ parent = fwnode;
+ }
+ if (IS_ERR_OR_NULL(parent))
return NULL;
/* Try to find a child in primary fwnode */
- next = fwnode_call_ptr_op(fwnode, get_next_child_node, child);
+ next = fwnode_call_ptr_op(parent, get_next_child_node, child);
if (next)
return next;
/* When no more children in primary, continue with secondary */
- return fwnode_call_ptr_op(fwnode->secondary, get_next_child_node, child);
+ return fwnode_get_next_child_node(parent->secondary, NULL);
}
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
@@ -1115,8 +1125,9 @@ struct fwnode_handle *
fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_handle *prev)
{
- struct fwnode_handle *ep, *port_parent = NULL;
const struct fwnode_handle *parent;
+ struct fwnode_handle *port_parent __free(fwnode_handle) = NULL;
+ struct fwnode_handle *ep;
/*
* If this function is in a loop and the previous iteration returned
@@ -1134,13 +1145,9 @@ fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
if (ep)
- goto out_put_port_parent;
-
- ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
+ return ep;
-out_put_port_parent:
- fwnode_handle_put(port_parent);
- return ep;
+ return fwnode_graph_get_next_endpoint(parent->secondary, NULL);
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
index 65ce72d49..af7d71393 100644
--- a/drivers/base/soc.c
+++ b/drivers/base/soc.c
@@ -191,6 +191,7 @@ EXPORT_SYMBOL_GPL(soc_device_unregister);
static int __init soc_bus_register(void)
{
+ struct soc_device *soc_dev;
int ret;
ret = bus_register(&soc_bus_type);
@@ -198,10 +199,20 @@ static int __init soc_bus_register(void)
return ret;
soc_bus_registered = true;
- if (early_soc_dev_attr)
- return PTR_ERR(soc_device_register(early_soc_dev_attr));
+ if (early_soc_dev_attr) {
+ soc_dev = soc_device_register(early_soc_dev_attr);
+ if (IS_ERR(soc_dev)) {
+ ret = PTR_ERR(soc_dev);
+ goto err_unregister_bus;
+ }
+ }
return 0;
+
+err_unregister_bus:
+ soc_bus_registered = false;
+ bus_unregister(&soc_bus_type);
+ return ret;
}
core_initcall(soc_bus_register);
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 1f2315858..84a77ffa3 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;
ref_array = prop->pointer;
diff --git a/drivers/base/test/Kconfig b/drivers/base/test/Kconfig
index 1ecf07912..542ce0753 100644
--- a/drivers/base/test/Kconfig
+++ b/drivers/base/test/Kconfig
@@ -17,6 +17,7 @@ config DM_KUNIT_TEST
config DRIVER_PE_KUNIT_TEST
tristate "KUnit Tests for property entry API" if !KUNIT_ALL_TESTS
depends on KUNIT
+ select OF
default KUNIT_ALL_TESTS
config DRIVER_SWNODE_KUNIT_TEST
diff --git a/drivers/base/test/platform-device-test.c b/drivers/base/test/platform-device-test.c
index 6355a2231..9ce563f76 100644
--- a/drivers/base/test/platform-device-test.c
+++ b/drivers/base/test/platform-device-test.c
@@ -1,12 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
+#include <kunit/fwnode.h>
#include <kunit/platform_device.h>
#include <kunit/resource.h>
#include <linux/device.h>
#include <linux/device/bus.h>
+#include <linux/fwnode.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#define DEVICE_NAME "test"
@@ -253,9 +256,186 @@ static struct kunit_suite platform_device_match_test_suite = {
.test_cases = platform_device_match_tests,
};
+static int platform_device_swnode_test_probe(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver platform_swnode_test_driver = {
+ .probe = platform_device_swnode_test_probe,
+ .driver = {
+ .name = DEVICE_NAME,
+ },
+};
+
+static const struct software_node platform_device_test_swnode = { };
+
+/*
+ * Check that reusing a software node works correctly. If the call to
+ * platform_device_register_full() fails after adding the secondary firmware
+ * node, the software node must be unregistered in the device's release()
+ * callback or the subsequent call to platform_device_register_full() will fail
+ * with -EBUSY due to the software node already having been registered.
+ */
+static void platform_device_swnode_add_twice(struct kunit *test)
+{
+ struct platform_device_info pdevinfo;
+ struct platform_device *pdev;
+ struct fwnode_handle *fwnode;
+ bool bound = false;
+ int ret;
+
+ fwnode = kunit_kzalloc(test, sizeof(*fwnode), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+ ret = kunit_platform_driver_register(test, &platform_swnode_test_driver);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ fwnode_init(fwnode, NULL);
+ pdevinfo = (struct platform_device_info){
+ .name = DEVICE_NAME,
+ .id = PLATFORM_DEVID_NONE,
+ .fwnode = fwnode,
+ .swnode = &platform_device_test_swnode,
+ };
+
+ pdev = platform_device_register_full(&pdevinfo);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+
+ wait_for_device_probe();
+ scoped_guard(device, &pdev->dev)
+ bound = device_is_bound(&pdev->dev);
+
+ KUNIT_ASSERT_TRUE(test, bound);
+
+ platform_device_unregister(pdev);
+
+ pdev = platform_device_register_full(&pdevinfo);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+
+ wait_for_device_probe();
+ scoped_guard(device, &pdev->dev)
+ bound = device_is_bound(&pdev->dev);
+
+ KUNIT_ASSERT_TRUE(test, bound);
+
+ platform_device_unregister(pdev);
+}
+
+/*
+ * Check that passing a software node as the primary firmware node of the
+ * platform device does not result in it being unregistered by the call to
+ * device_remove_software_node() in its release path.
+ */
+static void platform_device_swnode_as_primary(struct kunit *test)
+{
+ struct platform_device_info pdevinfo;
+ struct platform_device *pdev;
+ struct fwnode_handle *fwnode;
+ bool bound = false;
+ int ret;
+
+ ret = kunit_platform_driver_register(test, &platform_swnode_test_driver);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ fwnode = kunit_software_node_register(test, &platform_device_test_swnode);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+ pdevinfo = (struct platform_device_info){
+ .name = DEVICE_NAME,
+ .id = PLATFORM_DEVID_NONE,
+ .fwnode = fwnode,
+ };
+
+ pdev = platform_device_register_full(&pdevinfo);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
+
+ wait_for_device_probe();
+ scoped_guard(device, &pdev->dev)
+ bound = device_is_bound(&pdev->dev);
+
+ KUNIT_ASSERT_TRUE(test, bound);
+
+ platform_device_unregister(pdev);
+
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, software_node_fwnode(&platform_device_test_swnode));
+}
+
+/*
+ * Check that passing two software nodes to platform_device_register_full()
+ * fails.
+ */
+static void platform_device_two_swnodes(struct kunit *test)
+{
+ static const struct property_entry properties[] = {
+ PROPERTY_ENTRY_U32("foo", 42),
+ { }
+ };
+
+ struct platform_device_info pdevinfo;
+ struct platform_device *pdev;
+ struct fwnode_handle *fwnode;
+ int ret;
+
+ ret = kunit_platform_driver_register(test, &platform_swnode_test_driver);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+
+ fwnode = kunit_software_node_register(test, &platform_device_test_swnode);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode);
+
+ pdevinfo = (struct platform_device_info){
+ .name = DEVICE_NAME,
+ .id = PLATFORM_DEVID_NONE,
+ .fwnode = fwnode,
+ .swnode = &platform_device_test_swnode,
+ };
+
+ pdev = platform_device_register_full(&pdevinfo);
+ KUNIT_ASSERT_TRUE(test, IS_ERR(pdev));
+ KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL,
+ "Expected errno == -EINVAL, got: %pe", pdev);
+
+ pdevinfo = (struct platform_device_info){
+ .name = DEVICE_NAME,
+ .id = PLATFORM_DEVID_NONE,
+ .swnode = &platform_device_test_swnode,
+ .properties = properties,
+ };
+
+ pdev = platform_device_register_full(&pdevinfo);
+ KUNIT_ASSERT_TRUE(test, IS_ERR(pdev));
+ KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL,
+ "Expected errno == -EINVAL, got: %pe", pdev);
+
+ pdevinfo = (struct platform_device_info){
+ .name = DEVICE_NAME,
+ .id = PLATFORM_DEVID_NONE,
+ .fwnode = fwnode,
+ .properties = properties,
+ };
+
+ pdev = platform_device_register_full(&pdevinfo);
+ KUNIT_ASSERT_TRUE(test, IS_ERR(pdev));
+ KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL,
+ "Expected errno == -EINVAL, got: %pe", pdev);
+}
+
+static struct kunit_case platform_device_swnode_tests[] = {
+ KUNIT_CASE(platform_device_swnode_add_twice),
+ KUNIT_CASE(platform_device_swnode_as_primary),
+ KUNIT_CASE(platform_device_two_swnodes),
+ {}
+};
+
+static struct kunit_suite platform_device_swnode_test_suite = {
+ .name = "platform-device-swnode",
+ .test_cases = platform_device_swnode_tests,
+};
+
kunit_test_suites(
&platform_device_devm_test_suite,
&platform_device_match_test_suite,
+ &platform_device_swnode_test_suite,
);
MODULE_DESCRIPTION("Test module for platform devices");
diff --git a/drivers/base/test/property-entry-test.c b/drivers/base/test/property-entry-test.c
index a8657eb06..855e73b9b 100644
--- a/drivers/base/test/property-entry-test.c
+++ b/drivers/base/test/property-entry-test.c
@@ -4,6 +4,8 @@
// Copyright 2019 Google LLC.
#include <kunit/test.h>
+
+#include <linux/of.h>
#include <linux/property.h>
#include <linux/types.h>
@@ -489,6 +491,139 @@ static void pe_test_reference(struct kunit *test)
software_node_unregister_node_group(group);
}
+static struct fwnode_handle *create_device_node(struct kunit *test,
+ const char *name,
+ const char *full_name,
+ struct device_node *parent)
+{
+ struct device_node *node;
+
+ node = kunit_kzalloc(test, sizeof(*node), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node);
+
+ node->name = kunit_kstrdup(test, name, GFP_KERNEL);
+ node->full_name = kunit_kstrdup(test, full_name, GFP_KERNEL);
+
+ if (parent) {
+ node->sibling = parent->child;
+ /* set the node as the first child of the parent */
+ parent->child = node;
+ node->parent = parent;
+ }
+
+ of_node_init(node);
+ return of_fwnode_handle(node);
+}
+
+/* Verifies that fwnode_for_each_child_node() can output correct children */
+static void pe_test_child_iteration(struct kunit *test)
+{
+ struct fwnode_handle *of_node, *of_node1;
+ struct fwnode_handle *sw_node, *sw_node1;
+ struct fwnode_handle *child;
+ int error, i, num;
+
+ static const struct software_node node = { .name = "sw" };
+ static const struct software_node node1 = { .name = "sw-1", .parent = &node};
+ static const struct software_node node2 = { .name = "sw-2", .parent = &node};
+ static const struct software_node node3 = { .name = "sw-3", .parent = &node};
+ static const struct software_node *group[] = { &node, &node1, &node2, &node3, NULL };
+
+ static const char * const of_child_array[] = { "of-1", "of-2", "of-3" };
+ static const char * const sw_child_array[] = { "sw-1", "sw-2", "sw-3" };
+ static const char * const of_sw_child_array[] = { "of-1", "of-2", "of-3",
+ "sw-1", "sw-2", "sw-3" };
+ static const char * const sw_of_child_array[] = { "sw-1", "sw-2", "sw-3",
+ "of-1", "of-2", "of-3" };
+
+ /* 1. Test OF node child iteration */
+
+ of_node = create_device_node(test, "of", "of", NULL);
+ create_device_node(test, "of", "of-3", to_of_node(of_node));
+ create_device_node(test, "of", "of-2", to_of_node(of_node));
+ of_node1 = create_device_node(test, "of", "of-1", to_of_node(of_node));
+
+ i = 0;
+ num = ARRAY_SIZE(of_child_array);
+ fwnode_for_each_child_node(of_node, child) {
+ KUNIT_ASSERT_LT(test, i, num);
+ KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child));
+ }
+ KUNIT_EXPECT_PTR_EQ(test, child, NULL);
+
+ /* 2. Test SW node child iteration */
+
+ error = software_node_register_node_group(group);
+ KUNIT_ASSERT_EQ(test, error, 0);
+
+ sw_node = software_node_fwnode(&node);
+
+ i = 0;
+ num = ARRAY_SIZE(sw_child_array);
+ fwnode_for_each_child_node(sw_node, child) {
+ KUNIT_ASSERT_LT(test, i, num);
+ KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child));
+ }
+ KUNIT_EXPECT_PTR_EQ(test, child, NULL);
+
+ /* 3. Test OF (primary) + SW (secondary) node child iteration */
+
+ of_node->secondary = sw_node;
+ sw_node->secondary = ERR_PTR(-ENODEV);
+
+ i = 0;
+ num = ARRAY_SIZE(of_sw_child_array);
+ fwnode_for_each_child_node(of_node, child) {
+ KUNIT_ASSERT_LT(test, i, num);
+ KUNIT_EXPECT_STREQ(test, of_sw_child_array[i++], fwnode_get_name(child));
+ }
+ KUNIT_EXPECT_PTR_EQ(test, child, NULL);
+
+ /* 4. Test SW (primary) + OF (secondary) node child iteration */
+
+ sw_node->secondary = of_node;
+ of_node->secondary = ERR_PTR(-ENODEV);
+
+ i = 0;
+ num = ARRAY_SIZE(sw_of_child_array);
+ fwnode_for_each_child_node(sw_node, child) {
+ KUNIT_ASSERT_LT(test, i, num);
+ KUNIT_EXPECT_STREQ(test, sw_of_child_array[i++], fwnode_get_name(child));
+ }
+ KUNIT_EXPECT_PTR_EQ(test, child, NULL);
+
+ /* 5. Test OF (primary) + SW (secondary, but no children) node child iteration */
+
+ sw_node1 = software_node_fwnode(&node1);
+ of_node->secondary = sw_node1;
+ sw_node->secondary = ERR_PTR(-ENODEV);
+
+ i = 0;
+ num = ARRAY_SIZE(of_child_array);
+ fwnode_for_each_child_node(of_node, child) {
+ KUNIT_ASSERT_LT(test, i, num);
+ KUNIT_EXPECT_STREQ(test, of_child_array[i++], fwnode_get_name(child));
+ }
+ KUNIT_EXPECT_PTR_EQ(test, child, NULL);
+
+ /* 6. Test SW (primary) + OF (secondary, but no children) node child iteration */
+
+ sw_node->secondary = of_node1;
+ of_node->secondary = ERR_PTR(-ENODEV);
+
+ i = 0;
+ num = ARRAY_SIZE(sw_child_array);
+ fwnode_for_each_child_node(sw_node, child) {
+ KUNIT_ASSERT_LT(test, i, num);
+ KUNIT_EXPECT_STREQ(test, sw_child_array[i++], fwnode_get_name(child));
+ }
+ KUNIT_EXPECT_PTR_EQ(test, child, NULL);
+
+ of_node->secondary = NULL;
+ sw_node->secondary = NULL;
+ software_node_unregister_node_group(group);
+}
+
static struct kunit_case property_entry_test_cases[] = {
KUNIT_CASE(pe_test_uints),
KUNIT_CASE(pe_test_uint_arrays),
@@ -497,6 +632,7 @@ static struct kunit_case property_entry_test_cases[] = {
KUNIT_CASE(pe_test_move_inline_u8),
KUNIT_CASE(pe_test_move_inline_str),
KUNIT_CASE(pe_test_reference),
+ KUNIT_CASE(pe_test_child_iteration),
{ }
};
@@ -509,4 +645,5 @@ kunit_test_suite(property_entry_test_suite);
MODULE_DESCRIPTION("Test module for the property entry API");
MODULE_AUTHOR("Dmitry Torokhov <dtor@chromium.org>");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
MODULE_LICENSE("GPL");
diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c
index 416e9f819..351c3d3ce 100644
--- a/drivers/base/transport_class.c
+++ b/drivers/base/transport_class.c
@@ -168,11 +168,14 @@ static int transport_add_class_device(struct attribute_container *cont,
if (tcont->encryption) {
error = sysfs_create_group(&classdev->kobj, tcont->encryption);
if (error)
- goto err_del;
+ goto err_del_statistics;
}
return 0;
+err_del_statistics:
+ if (tcont->statistics)
+ sysfs_remove_group(&classdev->kobj, tcont->statistics);
err_del:
attribute_container_class_device_del(classdev);
err_remove:
diff --git a/drivers/cpufreq/rcpufreq_dt.rs b/drivers/cpufreq/rcpufreq_dt.rs
index 5d2785726..d7ead60bf 100644
--- a/drivers/cpufreq/rcpufreq_dt.rs
+++ b/drivers/cpufreq/rcpufreq_dt.rs
@@ -201,7 +201,6 @@ impl cpufreq::Driver for CPUFreqDTDriver {
kernel::of_device_table!(
OF_TABLE,
- MODULE_OF_TABLE,
<CPUFreqDTDriver as platform::Driver>::IdInfo,
[(of::DeviceId::new(c"operating-points-v2"), ())]
);
diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs
index 48933d86d..43f15cdfe 100644
--- a/drivers/gpu/drm/nova/driver.rs
+++ b/drivers/gpu/drm/nova/driver.rs
@@ -43,7 +43,6 @@ const AUXILIARY_NAME: &CStr = c"nova-drm";
kernel::auxiliary_device_table!(
AUX_TABLE,
- MODULE_AUX_TABLE,
<NovaDriver as auxiliary::Driver>::IdInfo,
[(
auxiliary::DeviceId::new(NOVA_CORE_MODULE_NAME, AUXILIARY_NAME),
diff --git a/drivers/gpu/drm/tyr/driver.rs b/drivers/gpu/drm/tyr/driver.rs
index d063bc664..218e9af89 100644
--- a/drivers/gpu/drm/tyr/driver.rs
+++ b/drivers/gpu/drm/tyr/driver.rs
@@ -87,7 +87,6 @@ fn issue_soft_reset(dev: &Device, iomem: &IoMem<'_>) -> Result {
kernel::of_device_table!(
OF_TABLE,
- MODULE_OF_TABLE,
<TyrPlatformDriver as platform::Driver>::IdInfo,
[
(of::DeviceId::new(c"rockchip,rk3588-mali"), ()),
diff --git a/drivers/gpu/drm/xe/xe_i2c.c b/drivers/gpu/drm/xe/xe_i2c.c
index f05f23221..c61d5db07 100644
--- a/drivers/gpu/drm/xe/xe_i2c.c
+++ b/drivers/gpu/drm/xe/xe_i2c.c
@@ -93,14 +93,9 @@ static int xe_i2c_register_adapter(struct xe_i2c *i2c)
{
struct pci_dev *pci = to_pci_dev(i2c->drm_dev);
struct platform_device *pdev;
- struct fwnode_handle *fwnode;
int ret;
u32 id;
- fwnode = fwnode_create_software_node(xe_i2c_adapter_properties, NULL);
- if (IS_ERR(fwnode))
- return PTR_ERR(fwnode);
-
id = (pci_domain_nr(pci->bus) << 16) | pci_dev_id(pci);
/*
@@ -110,10 +105,14 @@ static int xe_i2c_register_adapter(struct xe_i2c *i2c)
* platform_device_register_full() is done.
*/
pdev = platform_device_alloc(adapter_name, id);
- if (!pdev) {
- ret = -ENOMEM;
- goto err_fwnode_remove;
- }
+ if (!pdev)
+ return -ENOMEM;
+
+ ret = device_create_managed_software_node(&pdev->dev,
+ xe_i2c_adapter_properties,
+ NULL);
+ if (ret)
+ goto err_pdev_put;
if (i2c->adapter_irq) {
struct resource res;
@@ -126,8 +125,6 @@ static int xe_i2c_register_adapter(struct xe_i2c *i2c)
}
pdev->dev.parent = i2c->drm_dev;
- pdev->dev.fwnode = fwnode;
- i2c->adapter_node = fwnode;
i2c->pdev = pdev;
ret = platform_device_add(pdev);
@@ -138,8 +135,6 @@ static int xe_i2c_register_adapter(struct xe_i2c *i2c)
err_pdev_put:
platform_device_put(pdev);
-err_fwnode_remove:
- fwnode_remove_software_node(fwnode);
return ret;
}
@@ -147,7 +142,6 @@ err_fwnode_remove:
static void xe_i2c_unregister_adapter(struct xe_i2c *i2c)
{
platform_device_unregister(i2c->pdev);
- fwnode_remove_software_node(i2c->adapter_node);
}
/**
diff --git a/drivers/gpu/drm/xe/xe_i2c.h b/drivers/gpu/drm/xe/xe_i2c.h
index 425d81608..b28229f05 100644
--- a/drivers/gpu/drm/xe/xe_i2c.h
+++ b/drivers/gpu/drm/xe/xe_i2c.h
@@ -30,7 +30,6 @@ struct xe_i2c_endpoint {
};
struct xe_i2c {
- struct fwnode_handle *adapter_node;
struct platform_device *pdev;
struct i2c_adapter *adapter;
struct i2c_client *client[XE_I2C_MAX_CLIENTS];
diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs
index 5738d4ac5..bbd93959e 100644
--- a/drivers/gpu/nova-core/driver.rs
+++ b/drivers/gpu/nova-core/driver.rs
@@ -15,7 +15,7 @@ use kernel::{
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;
@@ -40,7 +40,6 @@ pub(crate) type Bar0<'a> = &'a pci::Bar<'a, BAR0_SIZE>;
kernel::pci_device_table!(
PCI_TABLE,
- MODULE_PCI_TABLE,
<NovaCoreDriver as pci::Driver>::IdInfo,
[
// Modern NVIDIA GPUs will show up as either VGA or 3D controllers.
@@ -70,7 +69,7 @@ impl pci::Driver for NovaCoreDriver {
fn probe<'bound>(
pdev: &'bound pci::Device<Core<'_>>,
- _info: &'bound Self::IdInfo,
+ _info: Option<&'bound Self::IdInfo>,
) -> impl PinInit<Self::Data<'bound>, Error> + 'bound {
pin_init::pin_init_scope(move || {
dev_dbg!(pdev, "Probe Nova Core GPU driver.\n");
diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs
index b3c91731d..b603b0bd2 100644
--- a/drivers/gpu/nova-core/gpu.rs
+++ b/drivers/gpu/nova-core/gpu.rs
@@ -285,10 +285,10 @@ pub(crate) struct Gpu<'gpu> {
}
impl<'gpu> Gpu<'gpu> {
- pub(crate) fn new(
- pdev: &'gpu pci::Device<device::Core<'_>>,
+ pub(crate) fn new<'a>(
+ pdev: &'gpu pci::Device<device::Core<'a>>,
bar: Bar0<'gpu>,
- ) -> impl PinInit<Self, Error> + 'gpu {
+ ) -> impl PinInit<Self, Error> + use<'gpu, 'a> {
try_pin_init!(Self {
device: pdev.as_ref(),
spec: Spec::new(pdev.as_ref(), bar).inspect(|spec| {
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 69175ca33..cfa7553cd 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -9,14 +9,16 @@ use kernel::{
dma::{
Coherent,
CoherentBox,
+ CoherentView,
DmaAddress, //
},
+ io::{
+ io_project,
+ io_write,
+ Io, //
+ },
pci,
- prelude::*,
- transmute::{
- AsBytes,
- FromBytes, //
- }, //
+ prelude::*, //
};
pub(crate) mod cmdq;
@@ -48,21 +50,21 @@ const LOG_BUFFER_SIZE: usize = RM_LOG_BUFFER_NUM_PAGES * GSP_PAGE_SIZE;
/// Array of page table entries, as understood by the GSP bootloader.
#[repr(C)]
+#[derive(FromBytes, IntoBytes)]
struct PteArray<const NUM_ENTRIES: usize>([u64; NUM_ENTRIES]);
-/// SAFETY: arrays of `u64` implement `FromBytes` and we are but a wrapper around one.
-unsafe impl<const NUM_ENTRIES: usize> FromBytes for PteArray<NUM_ENTRIES> {}
-
-/// SAFETY: arrays of `u64` implement `AsBytes` and we are but a wrapper around one.
-unsafe impl<const NUM_ENTRIES: usize> AsBytes for PteArray<NUM_ENTRIES> {}
-
impl<const NUM_PAGES: usize> PteArray<NUM_PAGES> {
- /// Returns the page table entry for `index`, for a mapping starting at `start`.
- // TODO: Replace with `IoView` projection once available.
- fn entry(start: DmaAddress, index: usize) -> Result<u64> {
- start
- .checked_add(num::usize_as_u64(index) << GSP_PAGE_SHIFT)
- .ok_or(EOVERFLOW)
+ /// Initialize a new page table array mapping `NUM_PAGES` GSP pages starting at address `start`.
+ fn init(view: CoherentView<'_, Self>, start: DmaAddress) -> Result<()> {
+ for i in 0..NUM_PAGES {
+ io_write!(view, .0[build: i],
+ start
+ .checked_add(num::usize_as_u64(i) << GSP_PAGE_SHIFT)
+ .ok_or(EOVERFLOW)?
+ );
+ }
+
+ Ok(())
}
}
@@ -89,17 +91,12 @@ impl LogBuffer {
let start_addr = obj.0.dma_handle();
- // SAFETY: `obj` has just been created and we are its sole user.
- let pte_region = unsafe {
- &mut obj.0.as_mut()[size_of::<u64>()..][..RM_LOG_BUFFER_NUM_PAGES * size_of::<u64>()]
- };
-
- // Write values one by one to avoid an on-stack instance of `PteArray`.
- for (i, chunk) in pte_region.chunks_exact_mut(size_of::<u64>()).enumerate() {
- let pte_value = PteArray::<0>::entry(start_addr, i)?;
-
- chunk.copy_from_slice(&pte_value.to_ne_bytes());
- }
+ let pte_view = io_project!(
+ obj.0,
+ [build: size_of::<u64>()..][build: ..RM_LOG_BUFFER_NUM_PAGES * size_of::<u64>()]
+ )
+ .try_cast::<PteArray<RM_LOG_BUFFER_NUM_PAGES>>()?;
+ PteArray::init(pte_view, start_addr)?;
Ok(obj)
}
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 3c68a6677..9349717b9 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -2,16 +2,23 @@
mod continuation;
-use core::mem;
+use core::{
+ mem,
+ sync::atomic::{
+ fence,
+ Ordering, //
+ },
+};
use kernel::{
device,
dma::{
Coherent,
+ CoherentBox,
DmaAddress, //
},
- dma_write,
io::{
+ io_project,
poll::read_poll_timeout,
Io, //
},
@@ -171,20 +178,18 @@ static_assert!(align_of::<MsgqData>() == GSP_PAGE_SIZE);
#[repr(C)]
// There is no struct defined for this in the open-gpu-kernel-source headers.
// Instead it is defined by code in `GspMsgQueuesInit()`.
-// TODO: Revert to private once `IoView` projections replace the `gsp_mem` module.
-pub(super) struct Msgq {
+struct Msgq {
/// Header for sending messages, including the write pointer.
- pub(super) tx: MsgqTxHeader,
+ tx: MsgqTxHeader,
/// Header for receiving messages, including the read pointer.
- pub(super) rx: MsgqRxHeader,
+ rx: MsgqRxHeader,
/// The message queue proper.
msgq: MsgqData,
}
/// Structure shared between the driver and the GSP and containing the command and message queues.
#[repr(C)]
-// TODO: Revert to private once `IoView` projections replace the `gsp_mem` module.
-pub(super) struct GspMem {
+struct GspMem {
/// Self-mapping page table entries.
ptes: PteArray<{ Self::PTE_ARRAY_SIZE }>,
/// CPU queue: the driver writes commands here, and the GSP reads them. It also contains the
@@ -192,13 +197,13 @@ pub(super) struct GspMem {
/// index into the GSP queue.
///
/// This member is read-only for the GSP.
- pub(super) cpuq: Msgq,
+ cpuq: Msgq,
/// GSP queue: the GSP writes messages here, and the driver reads them. It also contains the
/// write and read pointers that the GSP updates. This means that the read pointer here is an
/// index into the CPU queue.
///
/// This member is read-only for the driver.
- pub(super) gspq: Msgq,
+ gspq: Msgq,
}
impl GspMem {
@@ -232,20 +237,12 @@ impl DmaGspMem {
const MSGQ_SIZE: u32 = num::usize_into_u32::<{ size_of::<Msgq>() }>();
const RX_HDR_OFF: u32 = num::usize_into_u32::<{ mem::offset_of!(Msgq, rx) }>();
- let gsp_mem = Coherent::<GspMem>::zeroed(dev, GFP_KERNEL)?;
-
- let start = gsp_mem.dma_handle();
- // Write values one by one to avoid an on-stack instance of `PteArray`.
- for i in 0..GspMem::PTE_ARRAY_SIZE {
- dma_write!(gsp_mem, .ptes.0[build: i], PteArray::<0>::entry(start, i)?);
- }
+ let mut gsp_mem = CoherentBox::<GspMem>::zeroed(dev, GFP_KERNEL)?;
+ gsp_mem.cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES);
+ gsp_mem.cpuq.rx = MsgqRxHeader::new();
- dma_write!(
- gsp_mem,
- .cpuq.tx,
- MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES)
- );
- dma_write!(gsp_mem, .cpuq.rx, MsgqRxHeader::new());
+ let gsp_mem: Coherent<_> = gsp_mem.into();
+ PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_handle())?;
Ok(Self(gsp_mem))
}
@@ -406,7 +403,7 @@ impl DmaGspMem {
//
// - The returned value is within `0..MSGQ_NUM_PAGES`.
fn gsp_write_ptr(&self) -> u32 {
- super::fw::gsp_mem::gsp_write_ptr(&self.0)
+ MsgqTxHeader::write_ptr(io_project!(self.0, .gspq.tx)) % MSGQ_NUM_PAGES
}
// Returns the index of the memory page the GSP will read the next command from.
@@ -415,7 +412,7 @@ impl DmaGspMem {
//
// - The returned value is within `0..MSGQ_NUM_PAGES`.
fn gsp_read_ptr(&self) -> u32 {
- super::fw::gsp_mem::gsp_read_ptr(&self.0)
+ MsgqRxHeader::read_ptr(io_project!(self.0, .gspq.rx)) % MSGQ_NUM_PAGES
}
// Returns the index of the memory page the CPU can read the next message from.
@@ -424,12 +421,18 @@ impl DmaGspMem {
//
// - The returned value is within `0..MSGQ_NUM_PAGES`.
fn cpu_read_ptr(&self) -> u32 {
- super::fw::gsp_mem::cpu_read_ptr(&self.0)
+ MsgqRxHeader::read_ptr(io_project!(self.0, .cpuq.rx)) % MSGQ_NUM_PAGES
}
// Informs the GSP that it can send `elem_count` new pages into the message queue.
fn advance_cpu_read_ptr(&mut self, elem_count: u32) {
- super::fw::gsp_mem::advance_cpu_read_ptr(&self.0, elem_count)
+ let rx = io_project!(self.0, .cpuq.rx);
+ let rptr = MsgqRxHeader::read_ptr(rx).wrapping_add(elem_count) % MSGQ_NUM_PAGES;
+
+ // Ensure read pointer is properly ordered.
+ fence(Ordering::SeqCst);
+
+ MsgqRxHeader::set_read_ptr(rx, rptr)
}
// Returns the index of the memory page the CPU can write the next command to.
@@ -438,12 +441,17 @@ impl DmaGspMem {
//
// - The returned value is within `0..MSGQ_NUM_PAGES`.
fn cpu_write_ptr(&self) -> u32 {
- super::fw::gsp_mem::cpu_write_ptr(&self.0)
+ MsgqTxHeader::write_ptr(io_project!(self.0, .cpuq.tx)) % MSGQ_NUM_PAGES
}
// Informs the GSP that it can process `elem_count` new pages from the command queue.
fn advance_cpu_write_ptr(&mut self, elem_count: u32) {
- super::fw::gsp_mem::advance_cpu_write_ptr(&self.0, elem_count)
+ let tx = io_project!(self.0, .cpuq.tx);
+ let wptr = MsgqTxHeader::write_ptr(tx).wrapping_add(elem_count) % MSGQ_NUM_PAGES;
+ MsgqTxHeader::set_write_ptr(tx, wptr);
+
+ // Ensure all command data is visible before triggering the GSP read.
+ fence(Ordering::SeqCst);
}
}
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 4db0cfa4d..b0e7de328 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -10,7 +10,14 @@ use r570_144 as bindings;
use core::ops::Range;
use kernel::{
- dma::Coherent,
+ dma::{
+ Coherent,
+ CoherentView, //
+ },
+ io::{
+ io_read,
+ io_write, //
+ },
prelude::*,
ptr::{
Alignable,
@@ -44,59 +51,6 @@ use crate::{
},
};
-// TODO: Replace with `IoView` projections once available.
-pub(super) mod gsp_mem {
- use core::sync::atomic::{
- fence,
- Ordering, //
- };
-
- use kernel::{
- dma::Coherent,
- dma_read,
- dma_write, //
- };
-
- use crate::gsp::cmdq::{
- GspMem,
- MSGQ_NUM_PAGES, //
- };
-
- pub(in crate::gsp) fn gsp_write_ptr(qs: &Coherent<GspMem>) -> u32 {
- dma_read!(qs, .gspq.tx.0.writePtr) % MSGQ_NUM_PAGES
- }
-
- pub(in crate::gsp) fn gsp_read_ptr(qs: &Coherent<GspMem>) -> u32 {
- dma_read!(qs, .gspq.rx.0.readPtr) % MSGQ_NUM_PAGES
- }
-
- pub(in crate::gsp) fn cpu_read_ptr(qs: &Coherent<GspMem>) -> u32 {
- dma_read!(qs, .cpuq.rx.0.readPtr) % MSGQ_NUM_PAGES
- }
-
- pub(in crate::gsp) fn advance_cpu_read_ptr(qs: &Coherent<GspMem>, count: u32) {
- let rptr = cpu_read_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES;
-
- // Ensure read pointer is properly ordered.
- fence(Ordering::SeqCst);
-
- dma_write!(qs, .cpuq.rx.0.readPtr, rptr);
- }
-
- pub(in crate::gsp) fn cpu_write_ptr(qs: &Coherent<GspMem>) -> u32 {
- dma_read!(qs, .cpuq.tx.0.writePtr) % MSGQ_NUM_PAGES
- }
-
- pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &Coherent<GspMem>, count: u32) {
- let wptr = cpu_write_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES;
-
- dma_write!(qs, .cpuq.tx.0.writePtr, wptr);
-
- // Ensure all command data is visible before triggering the GSP read.
- fence(Ordering::SeqCst);
- }
-}
-
/// Maximum size of a single GSP message queue element in bytes.
pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize =
num::u32_as_usize(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX);
@@ -720,6 +674,16 @@ impl MsgqTxHeader {
entryOff: num::usize_into_u32::<GSP_PAGE_SIZE>(),
})
}
+
+ /// Returns the value of the write pointer for this queue.
+ pub(crate) fn write_ptr(this: CoherentView<'_, Self>) -> u32 {
+ io_read!(this, .0.writePtr)
+ }
+
+ /// Sets the value of the write pointer for this queue.
+ pub(crate) fn set_write_ptr(this: CoherentView<'_, Self>, val: u32) {
+ io_write!(this, .0.writePtr, val)
+ }
}
// SAFETY: Padding is explicit and does not contain uninitialized data.
@@ -735,6 +699,16 @@ impl MsgqRxHeader {
pub(crate) fn new() -> Self {
Self(Default::default())
}
+
+ /// Returns the value of the read pointer for this queue.
+ pub(crate) fn read_ptr(this: CoherentView<'_, Self>) -> u32 {
+ io_read!(this, .0.readPtr)
+ }
+
+ /// Sets the value of the read pointer for this queue.
+ pub(crate) fn set_read_ptr(this: CoherentView<'_, Self>, val: u32) {
+ io_write!(this, .0.readPtr, val)
+ }
}
// SAFETY: Padding is explicit and does not contain uninitialized data.
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
index dbd542300..92a0647f0 100644
--- a/drivers/i2c/busses/i2c-pxa-pci.c
+++ b/drivers/i2c/busses/i2c-pxa-pci.c
@@ -76,7 +76,8 @@ static struct platform_device *add_i2c_device(struct pci_dev *dev, int bar)
goto out;
}
pdev->dev.parent = &dev->dev;
- pdev->dev.of_node = child;
+
+ platform_device_set_of_node(pdev, child);
ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
if (ret)
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index 25aa477a9..c83bbc3fa 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -8,6 +8,7 @@
#include "fsl_pamu.h"
+#include <linux/cleanup.h>
#include <linux/fsl/guts.h>
#include <linux/interrupt.h>
#include <linux/genalloc.h>
@@ -933,7 +934,6 @@ static struct platform_driver fsl_of_pamu_driver = {
static __init int fsl_pamu_init(void)
{
struct platform_device *pdev = NULL;
- struct device_node *np;
int ret;
/*
@@ -955,7 +955,8 @@ static __init int fsl_pamu_init(void)
* PAMU node would require significant changes to a lot of code.
*/
- np = of_find_compatible_node(NULL, NULL, "fsl,pamu");
+ struct device_node *np __free(device_node) =
+ of_find_compatible_node(NULL, NULL, "fsl,pamu");
if (!np) {
pr_err("could not find a PAMU node\n");
return -ENODEV;
@@ -964,7 +965,7 @@ static __init int fsl_pamu_init(void)
ret = platform_driver_register(&fsl_of_pamu_driver);
if (ret) {
pr_err("could not register driver (err=%i)\n", ret);
- goto error_driver_register;
+ return ret;
}
pdev = platform_device_alloc("fsl-of-pamu", 0);
@@ -973,7 +974,8 @@ static __init int fsl_pamu_init(void)
ret = -ENOMEM;
goto error_device_alloc;
}
- pdev->dev.of_node = of_node_get(np);
+
+ platform_device_set_of_node(pdev, np);
ret = pamu_domain_init();
if (ret)
@@ -988,17 +990,11 @@ static __init int fsl_pamu_init(void)
return 0;
error_device_add:
- of_node_put(pdev->dev.of_node);
- pdev->dev.of_node = NULL;
-
platform_device_put(pdev);
error_device_alloc:
platform_driver_unregister(&fsl_of_pamu_driver);
-error_driver_register:
- of_node_put(np);
-
return ret;
}
arch_initcall(fsl_pamu_init);
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index f5f805446..3cfd2f02b 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -397,7 +397,7 @@ static int tps6586x_add_subdevs(struct tps6586x *tps6586x,
pdev->dev.parent = tps6586x->dev;
pdev->dev.platform_data = subdev->platform_data;
- pdev->dev.of_node = of_node_get(subdev->of_node);
+ platform_device_set_of_node(pdev, subdev->of_node);
ret = platform_device_add(pdev);
if (ret) {
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index a4e0d5a68..0f0dbabfa 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -490,8 +490,9 @@ static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
/* Retain this platform_device pointer for later cleanup */
priv->mii_pdev = ppdev;
ppdev->dev.parent = &pdev->dev;
+
if (dn)
- ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
+ platform_device_set_of_node(ppdev, bcmgenet_mii_of_find_mdio(priv));
else
ppd.phy_mask = ~0;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 1881583be..9caa1e47c 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2780,7 +2780,7 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
goto put_err;
}
ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- ppdev->dev.of_node = of_node_get(pnp);
+ platform_device_set_of_node(ppdev, pnp);
ret = platform_device_add_resources(ppdev, &res, 1);
if (ret)
diff --git a/drivers/of/kobj.c b/drivers/of/kobj.c
index 1bb61a2c3..9f17305f1 100644
--- a/drivers/of/kobj.c
+++ b/drivers/of/kobj.c
@@ -2,6 +2,8 @@
#include <linux/of.h>
#include <linux/slab.h>
+#include <kunit/visibility.h>
+
#include "of_private.h"
/* true when node is initialized */
@@ -27,6 +29,7 @@ static void of_node_release(struct kobject *kobj)
const struct kobj_type of_node_ktype = {
.release = of_node_release,
};
+EXPORT_SYMBOL_IF_KUNIT(of_node_ktype);
static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
const struct bin_attribute *bin_attr, char *buf,
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 53bca8c6f..8b1e76407 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -126,7 +126,7 @@ struct platform_device *of_device_alloc(struct device_node *np,
}
/* setup generic device info */
- device_set_node(&dev->dev, of_fwnode_handle(of_node_get(np)));
+ platform_device_set_of_node(dev, np);
dev->dev.parent = parent ? : &platform_bus;
if (bus_id)
diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c
index b35941390..29b264f2a 100644
--- a/drivers/platform/surface/surface_gpe.c
+++ b/drivers/platform/surface/surface_gpe.c
@@ -11,6 +11,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
+#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -290,9 +291,9 @@ static struct platform_device *surface_gpe_device;
static int __init surface_gpe_init(void)
{
+ struct platform_device_info pdevinfo;
const struct dmi_system_id *match;
struct platform_device *pdev;
- struct fwnode_handle *fwnode;
int status;
match = dmi_first_match(dmi_lid_device_table);
@@ -305,44 +306,27 @@ static int __init surface_gpe_init(void)
if (status)
return status;
- fwnode = fwnode_create_software_node(match->driver_data, NULL);
- if (IS_ERR(fwnode)) {
- status = PTR_ERR(fwnode);
- goto err_node;
- }
+ pdevinfo = (struct platform_device_info){
+ .name = "surface_gpe",
+ .id = PLATFORM_DEVID_NONE,
+ .properties = match->driver_data,
+ };
- pdev = platform_device_alloc("surface_gpe", PLATFORM_DEVID_NONE);
- if (!pdev) {
- status = -ENOMEM;
- goto err_alloc;
+ pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(pdev)) {
+ platform_driver_unregister(&surface_gpe_driver);
+ return PTR_ERR(pdev);
}
- pdev->dev.fwnode = fwnode;
-
- status = platform_device_add(pdev);
- if (status)
- goto err_add;
-
surface_gpe_device = pdev;
return 0;
-
-err_add:
- platform_device_put(pdev);
-err_alloc:
- fwnode_remove_software_node(fwnode);
-err_node:
- platform_driver_unregister(&surface_gpe_driver);
- return status;
}
module_init(surface_gpe_init);
static void __exit surface_gpe_exit(void)
{
- struct fwnode_handle *fwnode = surface_gpe_device->dev.fwnode;
-
platform_device_unregister(surface_gpe_device);
platform_driver_unregister(&surface_gpe_driver);
- fwnode_remove_software_node(fwnode);
}
module_exit(surface_gpe_exit);
diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c
index 42e50c9b4..abca5f449 100644
--- a/drivers/pmdomain/imx/gpc.c
+++ b/drivers/pmdomain/imx/gpc.c
@@ -487,8 +487,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
domain->ipg_rate_mhz = ipg_rate_mhz;
pd_pdev->dev.parent = &pdev->dev;
- pd_pdev->dev.of_node = of_node_get(np);
- pd_pdev->dev.fwnode = of_fwnode_handle(np);
+ platform_device_set_of_node(pd_pdev, np);
ret = platform_device_add(pd_pdev);
if (ret) {
diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs
index 543bd8dea..728993998 100644
--- a/drivers/pwm/pwm_th1520.rs
+++ b/drivers/pwm/pwm_th1520.rs
@@ -20,7 +20,6 @@
//! this method is not used in this driver.
//!
-use core::ops::Deref;
use kernel::{
clk::Clk,
device::{
@@ -28,9 +27,8 @@ use kernel::{
Core,
Device, //
},
- devres,
io::{
- mem::IoMem,
+ mem::DevresIoMem,
Io, //
},
of,
@@ -92,7 +90,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,
}
@@ -219,8 +217,7 @@ impl pwm::PwmOps for Th1520PwmDriverData {
) -> Result<Self::WfHw> {
let data = chip.drvdata();
let hwpwm = pwm.hwpwm();
- let iomem_accessor = data.iomem.access(parent_dev)?;
- let iomap = iomem_accessor.deref();
+ let iomap = data.iomem.access(parent_dev)?;
let ctrl = iomap.try_read32(th1520_pwm_ctrl(hwpwm))?;
let period_cycles = iomap.try_read32(th1520_pwm_per(hwpwm))?;
@@ -254,8 +251,7 @@ impl pwm::PwmOps for Th1520PwmDriverData {
) -> Result {
let data = chip.drvdata();
let hwpwm = pwm.hwpwm();
- let iomem_accessor = data.iomem.access(parent_dev)?;
- let iomap = iomem_accessor.deref();
+ let iomap = data.iomem.access(parent_dev)?;
let duty_cycles = iomap.try_read32(th1520_pwm_fp(hwpwm))?;
let was_enabled = duty_cycles != 0;
@@ -309,7 +305,6 @@ struct Th1520PwmPlatformDriver;
kernel::of_device_table!(
OF_TABLE,
- MODULE_OF_TABLE,
<Th1520PwmPlatformDriver as platform::Driver>::IdInfo,
[(of::DeviceId::new(c"thead,th1520-pwm"), ())]
);
diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
index fd75d9601..f003b3606 100644
--- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c
+++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c
@@ -249,7 +249,7 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev)
vdev->dev.parent = dev;
priv->vdev = vdev;
- device_set_of_node_from_dev(&vdev->dev, dev);
+ platform_device_set_of_node_from_dev(vdev, dev);
error = platform_device_add(vdev);
if (error)
goto err_device_put;
diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c
index 3071e46d0..6e8941571 100644
--- a/drivers/slimbus/qcom-ngd-ctrl.c
+++ b/drivers/slimbus/qcom-ngd-ctrl.c
@@ -1539,7 +1539,7 @@ static int of_qcom_slim_ngd_register(struct device *parent,
kfree(ngd);
return ret;
}
- ngd->pdev->dev.of_node = of_node_get(node);
+ platform_device_set_of_node(ngd->pdev, node);
ctrl->ngd = ngd;
ret = platform_device_add(ngd->pdev);
diff --git a/drivers/tty/serdev/Kconfig b/drivers/tty/serdev/Kconfig
index 46ae732bf..e6dfe949a 100644
--- a/drivers/tty/serdev/Kconfig
+++ b/drivers/tty/serdev/Kconfig
@@ -9,6 +9,13 @@ menuconfig SERIAL_DEV_BUS
Note that you typically also want to enable TTY port controller support.
+config RUST_SERIAL_DEV_BUS_ABSTRACTIONS
+ bool "Rust Serial device bus abstractions"
+ depends on RUST
+ select SERIAL_DEV_BUS
+ help
+ This enables the Rust abstraction for the serial device bus API.
+
if SERIAL_DEV_BUS
config SERIAL_DEV_CTRL_TTYPORT
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index b53672f3e..3461dd763 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -879,7 +879,7 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,
}
pdev->dev.parent = dev;
- device_set_of_node_from_dev(&pdev->dev, dev);
+ platform_device_set_of_node_from_dev(pdev, dev);
ret = platform_device_add_resources(pdev, res, nres);
if (ret)
diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c
index df56c9729..c770ba576 100644
--- a/drivers/usb/musb/jz4740.c
+++ b/drivers/usb/musb/jz4740.c
@@ -273,7 +273,7 @@ static int jz4740_probe(struct platform_device *pdev)
musb->dev.parent = dev;
musb->dev.dma_mask = &musb->dev.coherent_dma_mask;
musb->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- device_set_of_node_from_dev(&musb->dev, dev);
+ platform_device_set_of_node_from_dev(musb, dev);
glue->pdev = musb;
glue->clk = clk;