From 0a50f61c4fbd7840cdaf783c312e42b8ccde9ab3 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Wed, 20 Jun 2018 17:35:56 -0700 Subject: drivers: base: initcall_debug logs for driver probe times Add initcall_debug logs for each driver device probe call, for example: probe of a3800000.ramoops returned 1 after 3007 usecs This replaces the previous code added to report times for deferred probes. It also reports OF platform bus device creates that were formerly lumped together in a single entry for function of_platform_default_populate_init, as well as helping to annotate other initcalls that involve device probing. Remove restriction on printing probe times only during initcalls, since initcall_debug now continues to show driver timing info past the boot phase. Signed-off-by: Todd Poynor Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 50 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1435d7281c66..6ea9c5cece71 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -53,7 +53,6 @@ static DEFINE_MUTEX(deferred_probe_mutex); static LIST_HEAD(deferred_probe_pending_list); static LIST_HEAD(deferred_probe_active_list); static atomic_t deferred_trigger_count = ATOMIC_INIT(0); -static bool initcalls_done; /* * In some cases, like suspend to RAM or hibernation, It might be reasonable @@ -62,26 +61,6 @@ static bool initcalls_done; */ static bool defer_all_probes; -/* - * For initcall_debug, show the deferred probes executed in late_initcall - * processing. - */ -static void deferred_probe_debug(struct device *dev) -{ - ktime_t calltime, delta, rettime; - unsigned long long duration; - - printk(KERN_DEBUG "deferred probe %s @ %i\n", dev_name(dev), - task_pid_nr(current)); - calltime = ktime_get(); - bus_probe_device(dev); - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - duration = (unsigned long long) ktime_to_ns(delta) >> 10; - printk(KERN_DEBUG "deferred probe %s returned after %lld usecs\n", - dev_name(dev), duration); -} - /* * deferred_probe_work_func() - Retry probing devices in the active list. */ @@ -125,11 +104,7 @@ static void deferred_probe_work_func(struct work_struct *work) device_pm_move_to_tail(dev); dev_dbg(dev, "Retrying from deferred list\n"); - if (initcall_debug && !initcalls_done) - deferred_probe_debug(dev); - else - bus_probe_device(dev); - + bus_probe_device(dev); mutex_lock(&deferred_probe_mutex); put_device(dev); @@ -237,7 +212,6 @@ static int deferred_probe_initcall(void) driver_deferred_probe_trigger(); /* Sort as many dependencies as possible before exiting initcalls */ flush_work(&deferred_probe_work); - initcalls_done = true; return 0; } late_initcall(deferred_probe_initcall); @@ -527,6 +501,23 @@ done: return ret; } +/* + * For initcall_debug, show the driver probe time. + */ +static int really_probe_debug(struct device *dev, struct device_driver *drv) +{ + ktime_t calltime, delta, rettime; + int ret; + + calltime = ktime_get(); + ret = really_probe(dev, drv); + rettime = ktime_get(); + delta = ktime_sub(rettime, calltime); + printk(KERN_DEBUG "probe of %s returned %d after %lld usecs\n", + dev_name(dev), ret, (s64) ktime_to_us(delta)); + return ret; +} + /** * driver_probe_done * Determine if the probe sequence is finished or not. @@ -585,7 +576,10 @@ int driver_probe_device(struct device_driver *drv, struct device *dev) pm_runtime_get_sync(dev->parent); pm_runtime_barrier(dev); - ret = really_probe(dev, drv); + if (initcall_debug) + ret = really_probe_debug(dev, drv); + else + ret = really_probe(dev, drv); pm_request_idle(dev); if (dev->parent) -- cgit v1.2.3 From 663336ee2628096df0ce2b546b148cb74b5249fe Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 9 May 2018 08:15:46 -0700 Subject: device: Add #define dev_fmt similar to #define pr_fmt Add a prefixing macro to dev_ uses similar to the pr_fmt prefixing macro used in pr_ calls. This can help avoid some string duplication in dev_ uses. The default, like pr_fmt, is an empty #define dev_fmt(fmt) fmt Rename the existing dev_ functions to _dev_ and introduce #define dev_ _dev_ macros that use the new #define dev_fmt Miscellanea: o Consistently use #defines with fmt, ... and ##__VA_ARGS__ o Remove unnecessary externs Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 12 +++--- include/linux/device.h | 103 ++++++++++++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 51 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index df3e1a44707a..ceb8ce90aebb 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3002,12 +3002,12 @@ void func(const struct device *dev, const char *fmt, ...) \ } \ EXPORT_SYMBOL(func); -define_dev_printk_level(dev_emerg, KERN_EMERG); -define_dev_printk_level(dev_alert, KERN_ALERT); -define_dev_printk_level(dev_crit, KERN_CRIT); -define_dev_printk_level(dev_err, KERN_ERR); -define_dev_printk_level(dev_warn, KERN_WARNING); -define_dev_printk_level(dev_notice, KERN_NOTICE); +define_dev_printk_level(_dev_emerg, KERN_EMERG); +define_dev_printk_level(_dev_alert, KERN_ALERT); +define_dev_printk_level(_dev_crit, KERN_CRIT); +define_dev_printk_level(_dev_err, KERN_ERR); +define_dev_printk_level(_dev_warn, KERN_WARNING); +define_dev_printk_level(_dev_notice, KERN_NOTICE); define_dev_printk_level(_dev_info, KERN_INFO); #endif diff --git a/include/linux/device.h b/include/linux/device.h index 055a69dbcd18..2eaa9ea13c09 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1317,30 +1317,34 @@ struct device_link *device_link_add(struct device *consumer, struct device *supplier, u32 flags); void device_link_del(struct device_link *link); +#ifndef dev_fmt +#define dev_fmt(fmt) fmt +#endif + #ifdef CONFIG_PRINTK -extern __printf(3, 0) +__printf(3, 0) int dev_vprintk_emit(int level, const struct device *dev, const char *fmt, va_list args); -extern __printf(3, 4) +__printf(3, 4) int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...); -extern __printf(3, 4) +__printf(3, 4) void dev_printk(const char *level, const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_emerg(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_alert(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_crit(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_err(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_warn(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_notice(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) +__printf(2, 3) +void _dev_emerg(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_alert(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_crit(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_err(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_warn(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_notice(const struct device *dev, const char *fmt, ...); +__printf(2, 3) void _dev_info(const struct device *dev, const char *fmt, ...); #else @@ -1358,26 +1362,26 @@ static inline void __dev_printk(const char *level, const struct device *dev, {} static inline __printf(3, 4) void dev_printk(const char *level, const struct device *dev, - const char *fmt, ...) + const char *fmt, ...) {} static inline __printf(2, 3) -void dev_emerg(const struct device *dev, const char *fmt, ...) +void _dev_emerg(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_crit(const struct device *dev, const char *fmt, ...) +void _dev_crit(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_alert(const struct device *dev, const char *fmt, ...) +void _dev_alert(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_err(const struct device *dev, const char *fmt, ...) +void _dev_err(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_warn(const struct device *dev, const char *fmt, ...) +void _dev_warn(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_notice(const struct device *dev, const char *fmt, ...) +void _dev_notice(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) void _dev_info(const struct device *dev, const char *fmt, ...) @@ -1386,27 +1390,36 @@ void _dev_info(const struct device *dev, const char *fmt, ...) #endif /* - * Stupid hackaround for existing uses of non-printk uses dev_info - * - * Note that the definition of dev_info below is actually _dev_info - * and a macro is used to avoid redefining dev_info + * #defines for all the dev_ macros to prefix with whatever + * possible use of #define dev_fmt(fmt) ... */ -#define dev_info(dev, fmt, arg...) _dev_info(dev, fmt, ##arg) +#define dev_emerg(dev, fmt, ...) \ + _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_crit(dev, fmt, ...) \ + _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_alert(dev, fmt, ...) \ + _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_err(dev, fmt, ...) \ + _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_warn(dev, fmt, ...) \ + _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_notice(dev, fmt, ...) \ + _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_info(dev, fmt, ...) \ + _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__) #if defined(CONFIG_DYNAMIC_DEBUG) -#define dev_dbg(dev, format, ...) \ -do { \ - dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ -} while (0) +#define dev_dbg(dev, fmt, ...) \ + dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) #elif defined(DEBUG) -#define dev_dbg(dev, format, arg...) \ - dev_printk(KERN_DEBUG, dev, format, ##arg) +#define dev_dbg(dev, fmt, ...) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) #else -#define dev_dbg(dev, format, arg...) \ -({ \ - if (0) \ - dev_printk(KERN_DEBUG, dev, format, ##arg); \ +#define dev_dbg(dev, fmt, ...) \ +({ \ + if (0) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ }) #endif @@ -1478,7 +1491,7 @@ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ __ratelimit(&_rs)) \ - __dynamic_dev_dbg(&descriptor, dev, fmt, \ + __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \ ##__VA_ARGS__); \ } while (0) #elif defined(DEBUG) @@ -1488,23 +1501,23 @@ do { \ DEFAULT_RATELIMIT_INTERVAL, \ DEFAULT_RATELIMIT_BURST); \ if (__ratelimit(&_rs)) \ - dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ } while (0) #else #define dev_dbg_ratelimited(dev, fmt, ...) \ do { \ if (0) \ - dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ } while (0) #endif #ifdef VERBOSE_DEBUG #define dev_vdbg dev_dbg #else -#define dev_vdbg(dev, format, arg...) \ -({ \ - if (0) \ - dev_printk(KERN_DEBUG, dev, format, ##arg); \ +#define dev_vdbg(dev, fmt, ...) \ +({ \ + if (0) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ }) #endif -- cgit v1.2.3 From 166126c1e54d927c2e8efa2702d420e0ce301fd9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 1 Jul 2018 13:57:13 -0700 Subject: kernfs: Replace strncpy with memcpy gcc 8.1.0 complains: fs/kernfs/symlink.c:91:3: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length fs/kernfs/symlink.c: In function 'kernfs_iop_get_link': fs/kernfs/symlink.c:88:14: note: length computed here Using strncpy() is indeed less than perfect since the length of data to be copied has already been determined with strlen(). Replace strncpy() with memcpy() to address the warning and optimize the code a little. Signed-off-by: Guenter Roeck Acked-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 08ccabd7047f..5145ae2f0572 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -88,7 +88,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent, int slen = strlen(kn->name); len -= slen; - strncpy(s + len, kn->name, slen); + memcpy(s + len, kn->name, slen); if (len) s[--len] = '/'; -- cgit v1.2.3 From 448a5a552f336bd7b847b1951ffd15eb2e7167a3 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 6 Jul 2018 13:50:31 +0100 Subject: drivers: base: cacheinfo: use OF property_read_u32 instead of get_property,read_number of_property_read_u32 searches for a property in a device node and read a 32-bit value from it. Instead of using of_get_property to get the property and then read 32-bit value using of_read_number, we can simplify it by using of_property_read_u32. Suggested-by: Andy Shevchenko Signed-off-by: Sudeep Holla Signed-off-by: Greg Kroah-Hartman --- drivers/base/cacheinfo.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 2880e2ab01f5..5d5b5988e88b 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -74,52 +74,48 @@ static inline int get_cacheinfo_idx(enum cache_type type) static void cache_size(struct cacheinfo *this_leaf, struct device_node *np) { const char *propname; - const __be32 *cache_size; int ct_idx; ct_idx = get_cacheinfo_idx(this_leaf->type); propname = cache_type_info[ct_idx].size_prop; - cache_size = of_get_property(np, propname, NULL); - if (cache_size) - this_leaf->size = of_read_number(cache_size, 1); + if (of_property_read_u32(np, propname, &this_leaf->size)) + this_leaf->size = 0; } /* not cache_line_size() because that's a macro in include/linux/cache.h */ static void cache_get_line_size(struct cacheinfo *this_leaf, struct device_node *np) { - const __be32 *line_size; int i, lim, ct_idx; ct_idx = get_cacheinfo_idx(this_leaf->type); lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props); for (i = 0; i < lim; i++) { + int ret; + u32 line_size; const char *propname; propname = cache_type_info[ct_idx].line_size_props[i]; - line_size = of_get_property(np, propname, NULL); - if (line_size) + ret = of_property_read_u32(np, propname, &line_size); + if (!ret) { + this_leaf->coherency_line_size = line_size; break; + } } - - if (line_size) - this_leaf->coherency_line_size = of_read_number(line_size, 1); } static void cache_nr_sets(struct cacheinfo *this_leaf, struct device_node *np) { const char *propname; - const __be32 *nr_sets; int ct_idx; ct_idx = get_cacheinfo_idx(this_leaf->type); propname = cache_type_info[ct_idx].nr_sets_prop; - nr_sets = of_get_property(np, propname, NULL); - if (nr_sets) - this_leaf->number_of_sets = of_read_number(nr_sets, 1); + if (of_property_read_u32(np, propname, &this_leaf->number_of_sets)) + this_leaf->number_of_sets = 0; } static void cache_associativity(struct cacheinfo *this_leaf) -- cgit v1.2.3 From 77d2a24b6107bd9b3bf2403a65c1428a9da83dd0 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sun, 1 Jul 2018 13:57:16 -0700 Subject: kobject: Replace strncpy with memcpy gcc 8.1.0 complains: lib/kobject.c:128:3: warning: 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation] lib/kobject.c: In function 'kobject_get_path': lib/kobject.c:125:13: note: length computed here Using strncpy() is indeed less than perfect since the length of data to be copied has already been determined with strlen(). Replace strncpy() with memcpy() to address the warning and optimize the code a little. Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kobject.c b/lib/kobject.c index 18989b5b3b56..e876957743c8 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -125,7 +125,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) int cur = strlen(kobject_name(parent)); /* back up enough to print this name with '/' */ length -= cur; - strncpy(path + length, kobject_name(parent), cur); + memcpy(path + length, kobject_name(parent), cur); *(path + --length) = '/'; } -- cgit v1.2.3 From 8a1ed14ebf8c4e916fac8cb34b1eebbe60624db4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 6 Jun 2018 14:38:47 -0700 Subject: Documentation: update firmware loader fallback reference The firmware loader has a fallback mechanism, and it now has some proper kdoc, but we forgot to update the Documentation to use the new kdoc. Fix that. Signed-off-by: Luis R. Rodriguez Signed-off-by: Greg Kroah-Hartman --- Documentation/driver-api/firmware/fallback-mechanisms.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/driver-api/firmware/fallback-mechanisms.rst b/Documentation/driver-api/firmware/fallback-mechanisms.rst index d35fed65eae9..8b041d0ab426 100644 --- a/Documentation/driver-api/firmware/fallback-mechanisms.rst +++ b/Documentation/driver-api/firmware/fallback-mechanisms.rst @@ -92,7 +92,7 @@ the loading file. The firmware device used to help load firmware using sysfs is only created if direct firmware loading fails and if the fallback mechanism is enabled for your -firmware request, this is set up with fw_load_from_user_helper(). It is +firmware request, this is set up with :c:func:`firmware_fallback_sysfs`. It is important to re-iterate that no device is created if a direct filesystem lookup succeeded. @@ -108,6 +108,11 @@ firmware_data_read() and firmware_loading_show() are just provided for the test_firmware driver for testing, they are not called in normal use or expected to be used regularly by userspace. +firmware_fallback_sysfs +----------------------- +.. kernel-doc:: drivers/base/firmware_loader/fallback.c + :functions: firmware_fallback_sysfs + Firmware kobject uevent fallback mechanism ========================================== -- cgit v1.2.3 From ea614629c69c2c0258ef6414b017c998e3cc61a7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 16 Jun 2018 18:53:57 -0700 Subject: linux/device.h: fix kernel-doc notation warning Fix kernel-doc build warning (missing " *" at beginning of line): ../include/linux/device.h:93: warning: bad line: this bus. Fixes: 07397df29e57c ("dma-mapping: move dma configuration to bus infrastructure") Signed-off-by: Randy Dunlap Cc: Nipun Gupta Cc: Christoph Hellwig Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/device.h b/include/linux/device.h index 2eaa9ea13c09..575c5a35ece5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -90,7 +90,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * @num_vf: Called to find out how many virtual functions a device on this * bus supports. * @dma_configure: Called to setup DMA configuration on a device on - this bus. + * this bus. * @pm: Power management operations of this bus, callback the specific * device driver's pm-ops. * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU -- cgit v1.2.3 From 319b11ef5719a2f0ae65ce5f665f263a5e7a06c3 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 21 Jun 2018 15:37:37 +0200 Subject: base: fix order of OF initialization This fixes: [ 0.010000] cpu cpu0: Error -2 creating of_node link ... which you get for every CPU on all architectures that use CONFIG_GENERIC_CPU_DEVICES. In that case, driver_init() calls cpu_dev_init() before calling of_core_init(). Then we get the callchain: cpu_dev_init() -> cpu_dev_register_generic() -> register_cpu(cpu, i) -> device_register(&cpu->dev) -> device_add(dev) -> device_add_class_symlinks(dev) ... in device_add_class_symlinks, we we dev->of_node, and call sysfs_create_link(), which fails because we haven't called of_core_init() to register the sysfs devicetree directory yet. Signed-off-by: Wesley W. Terpstra [hch: updated the changelog based on review feedback] Signed-off-by: Christoph Hellwig Acked-by: Mark Rutland Acked-by: Frank Rowand Signed-off-by: Greg Kroah-Hartman --- drivers/base/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/init.c b/drivers/base/init.c index dd85b05a6a16..908e6520e804 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c @@ -30,9 +30,9 @@ void __init driver_init(void) /* These are also core pieces, but must come after the * core core pieces. */ + of_core_init(); platform_bus_init(); cpu_dev_init(); memory_dev_init(); container_dev_init(); - of_core_init(); } -- cgit v1.2.3 From c855cf2759d27142f771173d9fd8e7fdf9cf5138 Mon Sep 17 00:00:00 2001 From: Rajat Jain Date: Sat, 16 Jun 2018 10:49:46 -0700 Subject: sysfs: Fix internal_create_group() for named group updates There are a couple of problems with named group updates in the code today: * sysfs_update_group() will always fail for a named group, because internal_create_group() will try to create a new sysfs directory unconditionally, which will ofcourse fail with -EEXIST. * We can leak the kernfs_node for grp->name if some one tries to: - rename a group (change grp->name), or - update a named group, to an unnamed group It appears that the whole purpose of sysfs_update_group() was to allow changing the permissions or visibility of attributes and not the names. So make it clear in the comments, and allow it to update an existing named group. Signed-off-by: Rajat Jain Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 4802ec0e1e3a..38240410f831 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -119,12 +119,22 @@ static int internal_create_group(struct kobject *kobj, int update, return -EINVAL; } if (grp->name) { - kn = kernfs_create_dir(kobj->sd, grp->name, - S_IRWXU | S_IRUGO | S_IXUGO, kobj); - if (IS_ERR(kn)) { - if (PTR_ERR(kn) == -EEXIST) - sysfs_warn_dup(kobj->sd, grp->name); - return PTR_ERR(kn); + if (update) { + kn = kernfs_find_and_get(kobj->sd, grp->name); + if (!kn) { + pr_warn("Can't update unknown attr grp name: %s/%s\n", + kobj->name, grp->name); + return -EINVAL; + } + } else { + kn = kernfs_create_dir(kobj->sd, grp->name, + S_IRWXU | S_IRUGO | S_IXUGO, + kobj); + if (IS_ERR(kn)) { + if (PTR_ERR(kn) == -EEXIST) + sysfs_warn_dup(kobj->sd, grp->name); + return PTR_ERR(kn); + } } } else kn = kobj->sd; @@ -135,6 +145,10 @@ static int internal_create_group(struct kobject *kobj, int update, kernfs_remove(kn); } kernfs_put(kn); + + if (grp->name && update) + kernfs_put(kn); + return error; } @@ -199,7 +213,8 @@ EXPORT_SYMBOL_GPL(sysfs_create_groups); * of the attribute files being created already exist. Furthermore, * if the visibility of the files has changed through the is_visible() * callback, it will update the permissions and add or remove the - * relevant files. + * relevant files. Changing a group's name (subdirectory name under + * kobj's directory in sysfs) is not allowed. * * The primary use for this function is to call it after making a change * that affects group visibility. -- cgit v1.2.3 From 28af109a57d14211e5e8ba1551f00428be2fd508 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 8 Jul 2018 15:34:59 +0200 Subject: driver core: add a debugfs entry to show deferred devices With Device Trees (DT), the dependencies of the devices are defined in the DT, then the drivers parse that information to lookup the needed resources that have as dependencies. Since drivers and devices are registered in a non-deterministic way, it is possible that a device that is a dependency has not been registered yet by the time that is looked up. In this case the driver that requires this dependency cannot probe and has to defer it. So the driver core adds it to a list of deferred devices that is iterated again every time that a new driver is probed successfully. For debugging purposes it may be useful to know what are the devices whose probe function was deferred. Add a debugfs entry showing that information. $ cat /sys/kernel/debug/devices_deferred 48070000.i2c:twl@48:bci musb-hdrc.0.auto omapdrm.0 This information could be obtained partially by enabling debugging, but it means that the kernel log has to be parsed and the probe deferral balanced with the successes. This can be error probe and has to be done in a ad-hoc manner by everyone who needs to debug these kind of issues. Since the information is already known by the kernel, just show it to make it easier to debug. Signed-off-by: Javier Martinez Canillas Reviewed-by: Andy Shevchenko Reviewed-by: Mark Brown Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 6ea9c5cece71..e85705e84407 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -16,6 +16,7 @@ * Copyright (c) 2007-2009 Novell Inc. */ +#include #include #include #include @@ -53,6 +54,7 @@ static DEFINE_MUTEX(deferred_probe_mutex); static LIST_HEAD(deferred_probe_pending_list); static LIST_HEAD(deferred_probe_active_list); static atomic_t deferred_trigger_count = ATOMIC_INIT(0); +static struct dentry *deferred_devices; /* * In some cases, like suspend to RAM or hibernation, It might be reasonable @@ -199,6 +201,24 @@ void device_unblock_probing(void) driver_deferred_probe_trigger(); } +/* + * deferred_devs_show() - Show the devices in the deferred probe pending list. + */ +static int deferred_devs_show(struct seq_file *s, void *data) +{ + struct device_private *curr; + + mutex_lock(&deferred_probe_mutex); + + list_for_each_entry(curr, &deferred_probe_pending_list, deferred_probe) + seq_printf(s, "%s\n", dev_name(curr->device)); + + mutex_unlock(&deferred_probe_mutex); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(deferred_devs); + /** * deferred_probe_initcall() - Enable probing of deferred devices * @@ -208,6 +228,9 @@ void device_unblock_probing(void) */ static int deferred_probe_initcall(void) { + deferred_devices = debugfs_create_file("devices_deferred", 0444, NULL, + NULL, &deferred_devs_fops); + driver_deferred_probe_enable = true; driver_deferred_probe_trigger(); /* Sort as many dependencies as possible before exiting initcalls */ @@ -216,6 +239,12 @@ static int deferred_probe_initcall(void) } late_initcall(deferred_probe_initcall); +static void __exit deferred_probe_exit(void) +{ + debugfs_remove_recursive(deferred_devices); +} +__exitcall(deferred_probe_exit); + /** * device_is_bound() - Check if device is bound to a driver * @dev: device to check -- cgit v1.2.3 From 25b4e70dcce92168eab4d8113817bb4dd130ebd2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Jul 2018 09:41:48 -0600 Subject: driver core: allow stopping deferred probe after init Deferred probe will currently wait forever on dependent devices to probe, but sometimes a driver will never exist. It's also not always critical for a driver to exist. Platforms can rely on default configuration from the bootloader or reset defaults for things such as pinctrl and power domains. This is often the case with initial platform support until various drivers get enabled. There's at least 2 scenarios where deferred probe can render a platform broken. Both involve using a DT which has more devices and dependencies than the kernel supports. The 1st case is a driver may be disabled in the kernel config. The 2nd case is the kernel version may simply not have the dependent driver. This can happen if using a newer DT (provided by firmware perhaps) with a stable kernel version. Deferred probe issues can be difficult to debug especially if the console has dependencies or userspace fails to boot to a shell. There are also cases like IOMMUs where only built-in drivers are supported, so deferring probe after initcalls is not needed. The IOMMU subsystem implemented its own mechanism to handle this using OF_DECLARE linker sections. This commit adds makes ending deferred probe conditional on initcalls being completed or a debug timeout. Subsystems or drivers may opt-in by calling driver_deferred_probe_check_init_done() instead of unconditionally returning -EPROBE_DEFER. They may use additional information from DT or kernel's config to decide whether to continue to defer probe or not. The timeout mechanism is intended for debug purposes and WARNs loudly. The remaining deferred probe pending list will also be dumped after the timeout. Not that this timeout won't work for the console which needs to be enabled before userspace starts. However, if the console's dependencies are resolved, then the kernel log will be printed (as opposed to no output). Cc: Alexander Graf Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/kernel-parameters.txt | 9 ++++ drivers/base/dd.c | 59 +++++++++++++++++++++++++ include/linux/device.h | 2 + 3 files changed, 70 insertions(+) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index efc7aa7a0670..e83ef4648ea4 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -804,6 +804,15 @@ Defaults to the default architecture's huge page size if not specified. + deferred_probe_timeout= + [KNL] Debugging option to set a timeout in seconds for + deferred probe to give up waiting on dependencies to + probe. Only specific dependencies (subsystems or + drivers) that have opted in will be ignored. A timeout of 0 + will timeout at the end of initcalls. This option will also + dump out devices still on the deferred probe list after + retrying. + dhash_entries= [KNL] Set number of hash buckets for dentry cache. diff --git a/drivers/base/dd.c b/drivers/base/dd.c index e85705e84407..fb62f1be40d3 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -55,6 +55,7 @@ static LIST_HEAD(deferred_probe_pending_list); static LIST_HEAD(deferred_probe_active_list); static atomic_t deferred_trigger_count = ATOMIC_INIT(0); static struct dentry *deferred_devices; +static bool initcalls_done; /* * In some cases, like suspend to RAM or hibernation, It might be reasonable @@ -219,6 +220,51 @@ static int deferred_devs_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(deferred_devs); +static int deferred_probe_timeout = -1; +static int __init deferred_probe_timeout_setup(char *str) +{ + deferred_probe_timeout = simple_strtol(str, NULL, 10); + return 1; +} +__setup("deferred_probe_timeout=", deferred_probe_timeout_setup); + +/** + * driver_deferred_probe_check_state() - Check deferred probe state + * @dev: device to check + * + * Returns -ENODEV if init is done and all built-in drivers have had a chance + * to probe (i.e. initcalls are done), -ETIMEDOUT if deferred probe debug + * timeout has expired, or -EPROBE_DEFER if none of those conditions are met. + * + * Drivers or subsystems can opt-in to calling this function instead of directly + * returning -EPROBE_DEFER. + */ +int driver_deferred_probe_check_state(struct device *dev) +{ + if (initcalls_done) { + if (!deferred_probe_timeout) { + dev_WARN(dev, "deferred probe timeout, ignoring dependency"); + return -ETIMEDOUT; + } + dev_warn(dev, "ignoring dependency for device, assuming no driver"); + return -ENODEV; + } + return -EPROBE_DEFER; +} + +static void deferred_probe_timeout_work_func(struct work_struct *work) +{ + struct device_private *private, *p; + + deferred_probe_timeout = 0; + driver_deferred_probe_trigger(); + flush_work(&deferred_probe_work); + + list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe) + dev_info(private->device, "deferred probe pending"); +} +static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); + /** * deferred_probe_initcall() - Enable probing of deferred devices * @@ -235,6 +281,19 @@ static int deferred_probe_initcall(void) driver_deferred_probe_trigger(); /* Sort as many dependencies as possible before exiting initcalls */ flush_work(&deferred_probe_work); + initcalls_done = true; + + /* + * Trigger deferred probe again, this time we won't defer anything + * that is optional + */ + driver_deferred_probe_trigger(); + flush_work(&deferred_probe_work); + + if (deferred_probe_timeout > 0) { + schedule_delayed_work(&deferred_probe_timeout_work, + deferred_probe_timeout * HZ); + } return 0; } late_initcall(deferred_probe_initcall); diff --git a/include/linux/device.h b/include/linux/device.h index 575c5a35ece5..d2acc78d279b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -339,6 +339,8 @@ struct device *driver_find_device(struct device_driver *drv, struct device *start, void *data, int (*match)(struct device *dev, void *data)); +int driver_deferred_probe_check_state(struct device *dev); + /** * struct subsys_interface - interfaces to device functions * @name: name of the device function -- cgit v1.2.3 From 7930eb919feb59b8c799cb3085d0e9f7b5ae34d1 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Jul 2018 09:41:49 -0600 Subject: dt-bindings: pinctrl: add a 'pinctrl-use-default' property Pin setup may be optional in some cases such as the reset default works or the pin setup is done by the bootloader. In these cases, it is optional for the OS to support managing the pin controller and pin setup. In order to support this scenario, add a property 'pinctrl-use-default' to indicate that the pin configuration is optional. Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index ad9bbbba36e9..cef2b5855d60 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -103,6 +103,12 @@ Optional properties: #pinctrl-cells: Number of pin control cells in addition to the index within the pin controller device instance +pinctrl-use-default: Boolean. Indicates that the OS can use the boot default + pin configuration. This allows using an OS that does not have a + driver for the pin controller. This property can be set either + globally for the pin controller or in child nodes for individual + pin group control. + Pin controller devices should contain the pin configuration nodes that client devices reference. -- cgit v1.2.3 From d19c5e79d46efdf89306be99f3c8824cf58e35f6 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Jul 2018 09:41:50 -0600 Subject: pinctrl: Support stopping deferred probe after initcalls Pinctrl drivers are a common dependency which can prevent a system booting even if the default or bootloader configured settings can work. If a pinctrl node in DT indicates that the default pin setup can be used with the 'pinctrl-use-default' property, then only defer probe until initcalls are done. If the deferred probe timeout is enabled or loadable modules are disabled, then we'll stop deferring probe regardless of the DT property. This gives platforms the option to work without their pinctrl driver being enabled. Dropped the pinctrl specific deferring probe message as the driver core can print deferred probe related messages if needed. Reviewed-by: Linus Walleij Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/pinctrl/devicetree.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index c4aa411f5935..2969ff3162c3 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -111,17 +111,24 @@ static int dt_to_map_one_config(struct pinctrl *p, int ret; struct pinctrl_map *map; unsigned num_maps; + bool allow_default = false; /* Find the pin controller containing np_config */ np_pctldev = of_node_get(np_config); for (;;) { + if (!allow_default) + allow_default = of_property_read_bool(np_pctldev, + "pinctrl-use-default"); + np_pctldev = of_get_next_parent(np_pctldev); if (!np_pctldev || of_node_is_root(np_pctldev)) { - dev_info(p->dev, "could not find pctldev for node %pOF, deferring probe\n", - np_config); of_node_put(np_pctldev); - /* OK let's just assume this will appear later then */ - return -EPROBE_DEFER; + ret = driver_deferred_probe_check_state(p->dev); + /* keep deferring if modules are enabled unless we've timed out */ + if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV) + ret = -EPROBE_DEFER; + + return ret; } /* If we're creating a hog we can use the passed pctldev */ if (hog_pctldev && (np_pctldev == p->dev->of_node)) { -- cgit v1.2.3 From 78f307be3e0bc85f25dc05baa60f7435a88c2abf Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Jul 2018 09:41:51 -0600 Subject: iommu: Stop deferring probe at end of initcalls The IOMMU subsystem has its own mechanism to not defer probe if driver support is missing. Now that the driver core supports stopping deferring probe if drivers aren't built-in (and probed), use the driver core support so the IOMMU specific support can be removed. Acked-by: Joerg Roedel Cc: iommu@lists.linux-foundation.org Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/of_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 5c36a8b7656a..78ddf47dd67a 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -133,7 +133,7 @@ static int of_iommu_xlate(struct device *dev, * a proper probe-ordering dependency mechanism in future. */ if (!ops) - return -EPROBE_DEFER; + return driver_deferred_probe_check_state(dev); return ops->of_xlate(dev, iommu_spec); } -- cgit v1.2.3 From ac6bbf0cdf4206c517ac9789814c23e372ebce4d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Jul 2018 09:41:52 -0600 Subject: iommu: Remove IOMMU_OF_DECLARE Now that we use the driver core to stop deferred probe for missing drivers, IOMMU_OF_DECLARE can be removed. This is slightly less optimal than having a list of built-in drivers in that we'll now defer probe twice before giving up. This shouldn't have a significant impact on boot times as past discussions about deferred probe have given no evidence of deferred probe having a substantial impact. Cc: Robin Murphy Cc: Kukjin Kim Cc: Krzysztof Kozlowski Cc: Rob Clark Cc: Heiko Stuebner Cc: Frank Rowand Cc: linux-arm-kernel@lists.infradead.org Cc: iommu@lists.linux-foundation.org Cc: linux-samsung-soc@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: devicetree@vger.kernel.org Acked-by: Will Deacon Acked-by: Marek Szyprowski Acked-by: Joerg Roedel Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/arm-smmu-v3.c | 2 -- drivers/iommu/arm-smmu.c | 7 ------- drivers/iommu/exynos-iommu.c | 2 -- drivers/iommu/ipmmu-vmsa.c | 3 --- drivers/iommu/msm_iommu.c | 2 -- drivers/iommu/of_iommu.c | 19 +------------------ drivers/iommu/qcom_iommu.c | 2 -- drivers/iommu/rockchip-iommu.c | 2 -- include/asm-generic/vmlinux.lds.h | 2 -- include/linux/of_iommu.h | 4 ---- 10 files changed, 1 insertion(+), 44 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 1d647104bccc..22bdabd3d8e0 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2915,8 +2915,6 @@ static struct platform_driver arm_smmu_driver = { }; module_platform_driver(arm_smmu_driver); -IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3"); - MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations"); MODULE_AUTHOR("Will Deacon "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index f7a96bcf94a6..c73cfce1ccc0 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -2211,13 +2211,6 @@ static struct platform_driver arm_smmu_driver = { }; module_platform_driver(arm_smmu_driver); -IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1"); -IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2"); -IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400"); -IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401"); -IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500"); -IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2"); - MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations"); MODULE_AUTHOR("Will Deacon "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 85879cfec52f..b128cb4372d3 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -1390,5 +1390,3 @@ err_reg_driver: return ret; } core_initcall(exynos_iommu_init); - -IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu"); diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 40ae6e87cb88..f026aa16d5f1 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -1108,9 +1108,6 @@ static void __exit ipmmu_exit(void) subsys_initcall(ipmmu_init); module_exit(ipmmu_exit); -IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa"); -IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795"); - MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU"); MODULE_AUTHOR("Laurent Pinchart "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 0d3350463a3f..27377742600d 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -877,7 +877,5 @@ static void __exit msm_iommu_driver_exit(void) subsys_initcall(msm_iommu_driver_init); module_exit(msm_iommu_driver_exit); -IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu"); - MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Stepan Moskovchenko "); diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index 78ddf47dd67a..f7787e757244 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -27,9 +27,6 @@ #define NO_IOMMU 1 -static const struct of_device_id __iommu_of_table_sentinel - __used __section(__iommu_of_table_end); - /** * of_get_dma_window - Parse *dma-window property and returns 0 if found. * @@ -98,19 +95,6 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index, } EXPORT_SYMBOL_GPL(of_get_dma_window); -static bool of_iommu_driver_present(struct device_node *np) -{ - /* - * If the IOMMU still isn't ready by the time we reach init, assume - * it never will be. We don't want to defer indefinitely, nor attempt - * to dereference __iommu_of_table after it's been freed. - */ - if (system_state >= SYSTEM_RUNNING) - return false; - - return of_match_node(&__iommu_of_table, np); -} - static int of_iommu_xlate(struct device *dev, struct of_phandle_args *iommu_spec) { @@ -120,8 +104,7 @@ static int of_iommu_xlate(struct device *dev, ops = iommu_ops_from_fwnode(fwnode); if ((ops && !ops->of_xlate) || - !of_device_is_available(iommu_spec->np) || - (!ops && !of_iommu_driver_present(iommu_spec->np))) + !of_device_is_available(iommu_spec->np)) return NO_IOMMU; err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops); diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c index fe88a4880d3a..b48aee82d14b 100644 --- a/drivers/iommu/qcom_iommu.c +++ b/drivers/iommu/qcom_iommu.c @@ -945,7 +945,5 @@ static void __exit qcom_iommu_exit(void) module_init(qcom_iommu_init); module_exit(qcom_iommu_exit); -IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1"); - MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 054cd2c8e9c8..de8d3bf91b23 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1284,8 +1284,6 @@ static int __init rk_iommu_init(void) } subsys_initcall(rk_iommu_init); -IOMMU_OF_DECLARE(rk_iommu_of, "rockchip,iommu"); - MODULE_DESCRIPTION("IOMMU API for Rockchip"); MODULE_AUTHOR("Simon Xue and Daniel Kurtz "); MODULE_ALIAS("platform:rockchip-iommu"); diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index e373e2e10f6a..f173b5f30dbe 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -218,7 +218,6 @@ #define TIMER_OF_TABLES() OF_TABLE(CONFIG_TIMER_OF, timer) #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip) #define CLK_OF_TABLES() OF_TABLE(CONFIG_COMMON_CLK, clk) -#define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu) #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) @@ -601,7 +600,6 @@ CLK_OF_TABLES() \ RESERVEDMEM_OF_TABLES() \ TIMER_OF_TABLES() \ - IOMMU_OF_TABLES() \ CPU_METHOD_OF_TABLES() \ CPUIDLE_METHOD_OF_TABLES() \ KERNEL_DTB() \ diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h index 4fa654e4b5a9..f3d40dd7bb66 100644 --- a/include/linux/of_iommu.h +++ b/include/linux/of_iommu.h @@ -32,8 +32,4 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev, #endif /* CONFIG_OF_IOMMU */ -extern struct of_device_id __iommu_of_table; - -#define IOMMU_OF_DECLARE(name, compat) OF_DECLARE_1(iommu, name, compat, NULL) - #endif /* __OF_IOMMU_H */ -- cgit v1.2.3 From e01afc32502555beb2057ddd74401be38475d851 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 9 Jul 2018 09:41:53 -0600 Subject: PM / Domains: Stop deferring probe at the end of initcall All PM domain drivers must be built-in (at least those using DT), so there is no point deferring probe after initcalls are done. Continuing to defer probe may prevent booting successfully even if managing PM domains is not required. This can happen if the user failed to enable the driver or if power-domains are added to a platform's DT, but there is not yet a driver (e.g. a new DTB with an old kernel). Call the driver core function driver_deferred_probe_check_init_done() instead of just returning -EPROBE_DEFER to stop deferring probe when initcalls are done. Acked-by: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: Ulf Hansson Cc: Pavel Machek Cc: Len Brown Cc: Greg Kroah-Hartman Cc: linux-pm@vger.kernel.org Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/base/power/domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 4925af5c4cf0..8c12213875c6 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -2253,7 +2253,7 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device_node *np, mutex_unlock(&gpd_list_lock); dev_dbg(dev, "%s() failed to find PM domain: %ld\n", __func__, PTR_ERR(pd)); - return -EPROBE_DEFER; + return driver_deferred_probe_check_state(dev); } dev_dbg(dev, "adding to PM domain %s\n", pd->name); -- cgit v1.2.3 From 3ec78790ec9a1e23fd9b6c8681a7cd3b64d3ad23 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 15 Jul 2018 10:31:28 -0700 Subject: sysfs.h: fix non-kernel-doc comment Don't use "/**" to begin this comment block since it is not a kernel-doc comment block. Also adjust comment line to fit in 80 characters. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index b8bfdc173ec0..8e08a90b1d15 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -91,9 +91,9 @@ struct attribute_group { struct bin_attribute **bin_attrs; }; -/** - * Use these macros to make defining attributes easier. See include/linux/device.h - * for examples.. +/* + * Use these macros to make defining attributes easier. + * See include/linux/device.h for examples.. */ #define SYSFS_PREALLOC 010000 -- cgit v1.2.3 From 46d3a03781ea70e25360660ac53bbb838de11c97 Mon Sep 17 00:00:00 2001 From: Shaokun Zhang Date: Sun, 15 Jul 2018 18:08:56 +0800 Subject: driver core: remove unnecessary function extern declare device_private_init is called only in core.c, extern declare is unnecessary and make it static. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Signed-off-by: Shaokun Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 2 -- drivers/base/core.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index a75c3025fb78..7a419a7a6235 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -84,8 +84,6 @@ struct device_private { #define to_device_private_bus(obj) \ container_of(obj, struct device_private, knode_bus) -extern int device_private_init(struct device *dev); - /* initialisation functions */ extern int devices_init(void); extern int buses_init(void); diff --git a/drivers/base/core.c b/drivers/base/core.c index ceb8ce90aebb..9a6c71038616 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1736,7 +1736,7 @@ static void device_remove_sys_dev_entry(struct device *dev) } } -int device_private_init(struct device *dev) +static int device_private_init(struct device *dev) { dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); if (!dev->p) -- cgit v1.2.3 From 726e41097920a73e4c7c33385dcc0debb1281e18 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 10 Jul 2018 10:29:10 +1000 Subject: drivers: core: Remove glue dirs from sysfs earlier For devices with a class, we create a "glue" directory between the parent device and the new device with the class name. This directory is never "explicitely" removed when empty however, this is left to the implicit sysfs removal done by kobject_release() when the object loses its last reference via kobject_put(). This is problematic because as long as it's not been removed from sysfs, it is still present in the class kset and in sysfs directory structure. The presence in the class kset exposes a use after free bug fixed by the previous patch, but the presence in sysfs means that until the kobject is released, which can take a while (especially with kobject debugging), any attempt at re-creating such as binding a new device for that class/parent pair, will result in a sysfs duplicate file name error. This fixes it by instead doing an explicit kobject_del() when the glue dir is empty, by keeping track of the number of child devices of the gluedir. This is made easy by the fact that all glue dir operations are done with a global mutex, and there's already a function (cleanup_glue_dir) called in all the right places taking that mutex that can be enhanced for this. It appears that this was in fact the intent of the function, but the implementation was wrong. Signed-off-by: Benjamin Herrenschmidt Acked-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 2 ++ include/linux/kobject.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 9a6c71038616..cf8c605ec32e 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1597,6 +1597,8 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) return; mutex_lock(&gdp_mutex); + if (!kobject_has_children(glue_dir)) + kobject_del(glue_dir); kobject_put(glue_dir); mutex_unlock(&gdp_mutex); } diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 7f6f93c3df9c..270b40515e79 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -116,6 +116,23 @@ extern void kobject_put(struct kobject *kobj); extern const void *kobject_namespace(struct kobject *kobj); extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); +/** + * kobject_has_children - Returns whether a kobject has children. + * @kobj: the object to test + * + * This will return whether a kobject has other kobjects as children. + * + * It does NOT account for the presence of attribute files, only sub + * directories. It also assumes there is no concurrent addition or + * removal of such children, and thus relies on external locking. + */ +static inline bool kobject_has_children(struct kobject *kobj) +{ + WARN_ON_ONCE(kref_read(&kobj->kref) == 0); + + return kobj->sd && kobj->sd->dir.subdirs; +} + struct kobj_type { void (*release)(struct kobject *kobj); const struct sysfs_ops *sysfs_ops; -- cgit v1.2.3 From 3297c8fc65af5d40501ea7cddff1b195cae57e4e Mon Sep 17 00:00:00 2001 From: Pingfan Liu Date: Thu, 19 Jul 2018 13:14:58 +0800 Subject: drivers/base: stop new probing during shutdown There is a race window in device_shutdown(), which may cause -1. parent device shut down before child or -2. no shutdown on a new probing device. For 1st, taking the following scenario: device_shutdown new plugin device list_del_init(parent_dev); spin_unlock(list_lock); device_add(child) probe child shutdown parent_dev --> now child is on the tail of devices_kset For 2nd, taking the following scenario: device_shutdown new plugin device device_add(dev) device_lock(dev); ... device_unlock(dev); probe dev --> now, the new occurred dev has no opportunity to shutdown To fix this race issue, just prevent the new probing request. With this logic, device_shutdown() is more similar to dpm_prepare(). Signed-off-by: Pingfan Liu Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index cf8c605ec32e..5411af447418 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2811,6 +2811,9 @@ void device_shutdown(void) { struct device *dev, *parent; + wait_for_device_probe(); + device_block_probing(); + spin_lock(&devices_kset->list_lock); /* * Walk the devices list backward, shutting down each in turn. -- cgit v1.2.3 From e16f4f3e0b7daecd48d4f944ab4147c1a6cb16a8 Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Mon, 16 Jul 2018 13:37:44 +0200 Subject: base: core: Remove WARN_ON from link dependencies check In some cases the link between between customer and supplier already exist, for example when a device use its parent as a supplier. Do not warn about already existing dependencies because device_link_add() takes care of this case. Link: http://lkml.kernel.org/r/20180709111753eucas1p1f32e66fb2f7ea3216097cd72a132355d~-rzycA5Rg0378203782eucas1p1C@eucas1p1.samsung.com Reported-by: Marek Szyprowski Reviewed-by: Mark Brown Signed-off-by: Benjamin Gaignard Reviewed-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 5411af447418..2300d834d11f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -105,7 +105,7 @@ static int device_is_dependent(struct device *dev, void *target) struct device_link *link; int ret; - if (WARN_ON(dev == target)) + if (dev == target) return 1; ret = device_for_each_child(dev, target, device_is_dependent); @@ -113,7 +113,7 @@ static int device_is_dependent(struct device *dev, void *target) return ret; list_for_each_entry(link, &dev->links.consumers, s_node) { - if (WARN_ON(link->consumer == target)) + if (link->consumer == target) return 1; ret = device_is_dependent(link->consumer, target); -- cgit v1.2.3