diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/component.c | 6 | ||||
-rw-r--r-- | drivers/base/devres.c | 36 | ||||
-rw-r--r-- | drivers/base/devtmpfs.c | 2 | ||||
-rw-r--r-- | drivers/base/platform-msi.c | 14 |
4 files changed, 46 insertions, 12 deletions
diff --git a/drivers/base/component.c b/drivers/base/component.c index 8946dfee4768..e8d676fad0c9 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -536,9 +536,9 @@ int component_bind_all(struct device *master_dev, void *data) } if (ret != 0) { - for (; i--; ) - if (!master->match->compare[i].duplicate) { - c = master->match->compare[i].component; + for (; i > 0; i--) + if (!master->match->compare[i - 1].duplicate) { + c = master->match->compare[i - 1].component; component_unbind(c, master, data); } } diff --git a/drivers/base/devres.c b/drivers/base/devres.c index f98a097e73f2..4aaf00d2098b 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -11,6 +11,8 @@ #include <linux/slab.h> #include <linux/percpu.h> +#include <asm/sections.h> + #include "base.h" struct devres_node { @@ -823,6 +825,28 @@ char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) EXPORT_SYMBOL_GPL(devm_kstrdup); /** + * devm_kstrdup_const - resource managed conditional string duplication + * @dev: device for which to duplicate the string + * @s: the string to duplicate + * @gfp: the GFP mask used in the kmalloc() call when allocating memory + * + * Strings allocated by devm_kstrdup_const will be automatically freed when + * the associated device is detached. + * + * RETURNS: + * Source string if it is in .rodata section otherwise it falls back to + * devm_kstrdup. + */ +const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp) +{ + if (is_kernel_rodata((unsigned long)s)) + return s; + + return devm_kstrdup(dev, s, gfp); +} +EXPORT_SYMBOL_GPL(devm_kstrdup_const); + +/** * devm_kvasprintf - Allocate resource managed space and format a string * into that. * @dev: Device to allocate memory for @@ -885,11 +909,19 @@ EXPORT_SYMBOL_GPL(devm_kasprintf); * * Free memory allocated with devm_kmalloc(). */ -void devm_kfree(struct device *dev, void *p) +void devm_kfree(struct device *dev, const void *p) { int rc; - rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, p); + /* + * Special case: pointer to a string in .rodata returned by + * devm_kstrdup_const(). + */ + if (unlikely(is_kernel_rodata((unsigned long)p))) + return; + + rc = devres_destroy(dev, devm_kmalloc_release, + devm_kmalloc_match, (void *)p); WARN_ON(rc); } EXPORT_SYMBOL_GPL(devm_kfree); diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index f7768077e817..b93fc862d365 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -252,7 +252,7 @@ static int dev_rmdir(const char *name) static int delete_path(const char *nodepath) { - const char *path; + char *path; int err = 0; path = kstrdup(nodepath, GFP_KERNEL); diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 60d6cc618f1c..f39a920496fb 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -321,11 +321,12 @@ void *platform_msi_get_host_data(struct irq_domain *domain) * Returns an irqdomain for @nvec interrupts */ struct irq_domain * -platform_msi_create_device_domain(struct device *dev, - unsigned int nvec, - irq_write_msi_msg_t write_msi_msg, - const struct irq_domain_ops *ops, - void *host_data) +__platform_msi_create_device_domain(struct device *dev, + unsigned int nvec, + bool is_tree, + irq_write_msi_msg_t write_msi_msg, + const struct irq_domain_ops *ops, + void *host_data) { struct platform_msi_priv_data *data; struct irq_domain *domain; @@ -336,7 +337,8 @@ platform_msi_create_device_domain(struct device *dev, return NULL; data->host_data = host_data; - domain = irq_domain_create_hierarchy(dev->msi_domain, 0, nvec, + domain = irq_domain_create_hierarchy(dev->msi_domain, 0, + is_tree ? 0 : nvec, dev->fwnode, ops, data); if (!domain) goto free_priv; |