From 5367601b52696004f363e4f6c0b228b5bbf7d8b7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Dec 2019 20:32:58 +0100 Subject: drivers/base: base.h: add proper copyright and header info base.h didn't have any copyright information in it, so update it with the correct information. Cc: "Rafael J. Wysocki" Link: https://lore.kernel.org/r/20191209193303.1694546-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/base/base.h b/drivers/base/base.h index 0d32544b6f91..80598b312940 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -1,4 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2001-2003 Patrick Mochel + * Copyright (c) 2004-2009 Greg Kroah-Hartman + * Copyright (c) 2008-2012 Novell Inc. + * Copyright (c) 2012-2019 Greg Kroah-Hartman + * Copyright (c) 2012-2019 Linux Foundation + * + * Core driver model functions and structures that should not be + * shared outside of the drivers/base/ directory. + * + */ #include /** -- cgit v1.2.3-59-g8ed1b From cf901a1c5dd8df18d2308188d094a01e1e7c2143 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Dec 2019 20:32:59 +0100 Subject: device.h: move devtmpfs prototypes out of the file The devtmpfs functions do not need to be in device.h as only the driver core uses them, so move them to the private .h file for the driver core. Cc: "Rafael J. Wysocki" Cc: Suzuki K Poulose Cc: Saravana Kannan Cc: Heikki Krogerus Link: https://lore.kernel.org/r/20191209193303.1694546-3-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 8 ++++++++ include/linux/device.h | 4 ---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 80598b312940..40fb069a8a7e 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -186,3 +186,11 @@ extern void device_links_unbind_consumers(struct device *dev); /* device pm support */ void device_pm_move_to_tail(struct device *dev); + +#ifdef CONFIG_DEVTMPFS +int devtmpfs_create_node(struct device *dev); +int devtmpfs_delete_node(struct device *dev); +#else +static inline int devtmpfs_create_node(struct device *dev) { return 0; } +static inline int devtmpfs_delete_node(struct device *dev) { return 0; } +#endif diff --git a/include/linux/device.h b/include/linux/device.h index 96ff76731e93..ba4c24f9cd8b 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1664,12 +1664,8 @@ extern void put_device(struct device *dev); extern bool kill_device(struct device *dev); #ifdef CONFIG_DEVTMPFS -extern int devtmpfs_create_node(struct device *dev); -extern int devtmpfs_delete_node(struct device *dev); extern int devtmpfs_mount(void); #else -static inline int devtmpfs_create_node(struct device *dev) { return 0; } -static inline int devtmpfs_delete_node(struct device *dev) { return 0; } static inline int devtmpfs_mount(void) { return 0; } #endif -- cgit v1.2.3-59-g8ed1b From af628aae8640c268938a0c9344b4ec0d102c0a0a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Dec 2019 20:33:00 +0100 Subject: device.h: move dev_printk()-like functions to dev_printk.h device.h has everything and the kitchen sink when it comes to struct device things, so split out the printk-specific things to a separate .h file to make things easier to maintain and manage over time. Cc: Suzuki K Poulose Cc: "Rafael J. Wysocki" Cc: Saravana Kannan Cc: Heikki Krogerus Link: https://lore.kernel.org/r/20191209193303.1694546-4-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- include/linux/dev_printk.h | 235 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/device.h | 217 +---------------------------------------- 2 files changed, 236 insertions(+), 216 deletions(-) create mode 100644 include/linux/dev_printk.h diff --git a/include/linux/dev_printk.h b/include/linux/dev_printk.h new file mode 100644 index 000000000000..5aad06b4ca7b --- /dev/null +++ b/include/linux/dev_printk.h @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dev_printk.h - printk messages helpers for devices + * + * Copyright (c) 2001-2003 Patrick Mochel + * Copyright (c) 2004-2009 Greg Kroah-Hartman + * Copyright (c) 2008-2009 Novell Inc. + * + */ + +#ifndef _DEVICE_PRINTK_H_ +#define _DEVICE_PRINTK_H_ + +#include +#include +#include + +#ifndef dev_fmt +#define dev_fmt(fmt) fmt +#endif + +struct device; + +#ifdef CONFIG_PRINTK + +__printf(3, 0) __cold +int dev_vprintk_emit(int level, const struct device *dev, + const char *fmt, va_list args); +__printf(3, 4) __cold +int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...); + +__printf(3, 4) __cold +void dev_printk(const char *level, const struct device *dev, + const char *fmt, ...); +__printf(2, 3) __cold +void _dev_emerg(const struct device *dev, const char *fmt, ...); +__printf(2, 3) __cold +void _dev_alert(const struct device *dev, const char *fmt, ...); +__printf(2, 3) __cold +void _dev_crit(const struct device *dev, const char *fmt, ...); +__printf(2, 3) __cold +void _dev_err(const struct device *dev, const char *fmt, ...); +__printf(2, 3) __cold +void _dev_warn(const struct device *dev, const char *fmt, ...); +__printf(2, 3) __cold +void _dev_notice(const struct device *dev, const char *fmt, ...); +__printf(2, 3) __cold +void _dev_info(const struct device *dev, const char *fmt, ...); + +#else + +static inline __printf(3, 0) +int dev_vprintk_emit(int level, const struct device *dev, + const char *fmt, va_list args) +{ return 0; } +static inline __printf(3, 4) +int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) +{ return 0; } + +static inline void __dev_printk(const char *level, const struct device *dev, + struct va_format *vaf) +{} +static inline __printf(3, 4) +void dev_printk(const char *level, const struct device *dev, + const char *fmt, ...) +{} + +static inline __printf(2, 3) +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, ...) +{} +static inline __printf(2, 3) +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, ...) +{} +static inline __printf(2, 3) +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, ...) +{} +static inline __printf(2, 3) +void _dev_info(const struct device *dev, const char *fmt, ...) +{} + +#endif + +/* + * #defines for all the dev_ macros to prefix with whatever + * possible use of #define dev_fmt(fmt) ... + */ + +#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, fmt, ...) \ + dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) +#elif defined(DEBUG) +#define dev_dbg(dev, fmt, ...) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) +#else +#define dev_dbg(dev, fmt, ...) \ +({ \ + if (0) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ +}) +#endif + +#ifdef CONFIG_PRINTK +#define dev_level_once(dev_level, dev, fmt, ...) \ +do { \ + static bool __print_once __read_mostly; \ + \ + if (!__print_once) { \ + __print_once = true; \ + dev_level(dev, fmt, ##__VA_ARGS__); \ + } \ +} while (0) +#else +#define dev_level_once(dev_level, dev, fmt, ...) \ +do { \ + if (0) \ + dev_level(dev, fmt, ##__VA_ARGS__); \ +} while (0) +#endif + +#define dev_emerg_once(dev, fmt, ...) \ + dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__) +#define dev_alert_once(dev, fmt, ...) \ + dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__) +#define dev_crit_once(dev, fmt, ...) \ + dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__) +#define dev_err_once(dev, fmt, ...) \ + dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__) +#define dev_warn_once(dev, fmt, ...) \ + dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__) +#define dev_notice_once(dev, fmt, ...) \ + dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__) +#define dev_info_once(dev, fmt, ...) \ + dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__) +#define dev_dbg_once(dev, fmt, ...) \ + dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__) + +#define dev_level_ratelimited(dev_level, dev, fmt, ...) \ +do { \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + if (__ratelimit(&_rs)) \ + dev_level(dev, fmt, ##__VA_ARGS__); \ +} while (0) + +#define dev_emerg_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__) +#define dev_alert_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__) +#define dev_crit_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__) +#define dev_err_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__) +#define dev_warn_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__) +#define dev_notice_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) +#define dev_info_ratelimited(dev, fmt, ...) \ + dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) +#if defined(CONFIG_DYNAMIC_DEBUG) +/* descriptor check is first to prevent flooding with "callbacks suppressed" */ +#define dev_dbg_ratelimited(dev, fmt, ...) \ +do { \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ + if (DYNAMIC_DEBUG_BRANCH(descriptor) && \ + __ratelimit(&_rs)) \ + __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \ + ##__VA_ARGS__); \ +} while (0) +#elif defined(DEBUG) +#define dev_dbg_ratelimited(dev, fmt, ...) \ +do { \ + static DEFINE_RATELIMIT_STATE(_rs, \ + DEFAULT_RATELIMIT_INTERVAL, \ + DEFAULT_RATELIMIT_BURST); \ + if (__ratelimit(&_rs)) \ + 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, dev_fmt(fmt), ##__VA_ARGS__); \ +} while (0) +#endif + +#ifdef VERBOSE_DEBUG +#define dev_vdbg dev_dbg +#else +#define dev_vdbg(dev, fmt, ...) \ +({ \ + if (0) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ +}) +#endif + +/* + * dev_WARN*() acts like dev_printk(), but with the key difference of + * using WARN/WARN_ONCE to include file/line information and a backtrace. + */ +#define dev_WARN(dev, format, arg...) \ + WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg); + +#define dev_WARN_ONCE(dev, condition, format, arg...) \ + WARN_ONCE(condition, "%s %s: " format, \ + dev_driver_string(dev), dev_name(dev), ## arg) + +#endif /* _DEVICE_PRINTK_H_ */ diff --git a/include/linux/device.h b/include/linux/device.h index ba4c24f9cd8b..758e7dccfcbb 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -12,6 +12,7 @@ #ifndef _DEVICE_H_ #define _DEVICE_H_ +#include #include #include #include @@ -22,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -1683,221 +1683,6 @@ void device_link_remove(void *consumer, struct device *supplier); void device_links_supplier_sync_state_pause(void); void device_links_supplier_sync_state_resume(void); -#ifndef dev_fmt -#define dev_fmt(fmt) fmt -#endif - -#ifdef CONFIG_PRINTK - -__printf(3, 0) __cold -int dev_vprintk_emit(int level, const struct device *dev, - const char *fmt, va_list args); -__printf(3, 4) __cold -int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...); - -__printf(3, 4) __cold -void dev_printk(const char *level, const struct device *dev, - const char *fmt, ...); -__printf(2, 3) __cold -void _dev_emerg(const struct device *dev, const char *fmt, ...); -__printf(2, 3) __cold -void _dev_alert(const struct device *dev, const char *fmt, ...); -__printf(2, 3) __cold -void _dev_crit(const struct device *dev, const char *fmt, ...); -__printf(2, 3) __cold -void _dev_err(const struct device *dev, const char *fmt, ...); -__printf(2, 3) __cold -void _dev_warn(const struct device *dev, const char *fmt, ...); -__printf(2, 3) __cold -void _dev_notice(const struct device *dev, const char *fmt, ...); -__printf(2, 3) __cold -void _dev_info(const struct device *dev, const char *fmt, ...); - -#else - -static inline __printf(3, 0) -int dev_vprintk_emit(int level, const struct device *dev, - const char *fmt, va_list args) -{ return 0; } -static inline __printf(3, 4) -int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) -{ return 0; } - -static inline void __dev_printk(const char *level, const struct device *dev, - struct va_format *vaf) -{} -static inline __printf(3, 4) -void dev_printk(const char *level, const struct device *dev, - const char *fmt, ...) -{} - -static inline __printf(2, 3) -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, ...) -{} -static inline __printf(2, 3) -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, ...) -{} -static inline __printf(2, 3) -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, ...) -{} -static inline __printf(2, 3) -void _dev_info(const struct device *dev, const char *fmt, ...) -{} - -#endif - -/* - * #defines for all the dev_ macros to prefix with whatever - * possible use of #define dev_fmt(fmt) ... - */ - -#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, fmt, ...) \ - dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) -#elif defined(DEBUG) -#define dev_dbg(dev, fmt, ...) \ - dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) -#else -#define dev_dbg(dev, fmt, ...) \ -({ \ - if (0) \ - dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ -}) -#endif - -#ifdef CONFIG_PRINTK -#define dev_level_once(dev_level, dev, fmt, ...) \ -do { \ - static bool __print_once __read_mostly; \ - \ - if (!__print_once) { \ - __print_once = true; \ - dev_level(dev, fmt, ##__VA_ARGS__); \ - } \ -} while (0) -#else -#define dev_level_once(dev_level, dev, fmt, ...) \ -do { \ - if (0) \ - dev_level(dev, fmt, ##__VA_ARGS__); \ -} while (0) -#endif - -#define dev_emerg_once(dev, fmt, ...) \ - dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__) -#define dev_alert_once(dev, fmt, ...) \ - dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__) -#define dev_crit_once(dev, fmt, ...) \ - dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__) -#define dev_err_once(dev, fmt, ...) \ - dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__) -#define dev_warn_once(dev, fmt, ...) \ - dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__) -#define dev_notice_once(dev, fmt, ...) \ - dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__) -#define dev_info_once(dev, fmt, ...) \ - dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__) -#define dev_dbg_once(dev, fmt, ...) \ - dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__) - -#define dev_level_ratelimited(dev_level, dev, fmt, ...) \ -do { \ - static DEFINE_RATELIMIT_STATE(_rs, \ - DEFAULT_RATELIMIT_INTERVAL, \ - DEFAULT_RATELIMIT_BURST); \ - if (__ratelimit(&_rs)) \ - dev_level(dev, fmt, ##__VA_ARGS__); \ -} while (0) - -#define dev_emerg_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__) -#define dev_alert_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__) -#define dev_crit_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__) -#define dev_err_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__) -#define dev_warn_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__) -#define dev_notice_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) -#define dev_info_ratelimited(dev, fmt, ...) \ - dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) -#if defined(CONFIG_DYNAMIC_DEBUG) -/* descriptor check is first to prevent flooding with "callbacks suppressed" */ -#define dev_dbg_ratelimited(dev, fmt, ...) \ -do { \ - static DEFINE_RATELIMIT_STATE(_rs, \ - DEFAULT_RATELIMIT_INTERVAL, \ - DEFAULT_RATELIMIT_BURST); \ - DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ - if (DYNAMIC_DEBUG_BRANCH(descriptor) && \ - __ratelimit(&_rs)) \ - __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \ - ##__VA_ARGS__); \ -} while (0) -#elif defined(DEBUG) -#define dev_dbg_ratelimited(dev, fmt, ...) \ -do { \ - static DEFINE_RATELIMIT_STATE(_rs, \ - DEFAULT_RATELIMIT_INTERVAL, \ - DEFAULT_RATELIMIT_BURST); \ - if (__ratelimit(&_rs)) \ - 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, dev_fmt(fmt), ##__VA_ARGS__); \ -} while (0) -#endif - -#ifdef VERBOSE_DEBUG -#define dev_vdbg dev_dbg -#else -#define dev_vdbg(dev, fmt, ...) \ -({ \ - if (0) \ - dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ -}) -#endif - -/* - * dev_WARN*() acts like dev_printk(), but with the key difference of - * using WARN/WARN_ONCE to include file/line information and a backtrace. - */ -#define dev_WARN(dev, format, arg...) \ - WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg); - -#define dev_WARN_ONCE(dev, condition, format, arg...) \ - WARN_ONCE(condition, "%s %s: " format, \ - dev_driver_string(dev), dev_name(dev), ## arg) - /* Create alias, so I can be autoloaded. */ #define MODULE_ALIAS_CHARDEV(major,minor) \ MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) -- cgit v1.2.3-59-g8ed1b From 5aee2bf2629d7db2619110f62b15cf742c116e0b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Dec 2019 20:33:01 +0100 Subject: device.h: move 'struct bus' stuff out to device/bus.h device.h has everything and the kitchen sink when it comes to struct device things, so split out the struct bus things things to a separate .h file to make things easier to maintain and manage over time. Cc: "Rafael J. Wysocki" Cc: Suzuki K Poulose Cc: Saravana Kannan Cc: Heikki Krogerus Link: https://lore.kernel.org/r/20191209193303.1694546-5-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 1 + include/linux/device.h | 265 +---------------------------------------- include/linux/device/bus.h | 288 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 290 insertions(+), 264 deletions(-) create mode 100644 include/linux/device/bus.h diff --git a/drivers/base/bus.c b/drivers/base/bus.c index a1d1e8256324..886e9054999a 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include diff --git a/include/linux/device.h b/include/linux/device.h index 758e7dccfcbb..22fd0b91d0fa 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -26,6 +26,7 @@ #include #include #include +#include #include struct device; @@ -35,7 +36,6 @@ struct driver_private; struct module; struct class; struct subsys_private; -struct bus_type; struct device_node; struct fwnode_handle; struct iommu_ops; @@ -44,269 +44,6 @@ struct iommu_fwspec; struct dev_pin_info; struct iommu_param; -struct bus_attribute { - struct attribute attr; - ssize_t (*show)(struct bus_type *bus, char *buf); - ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count); -}; - -#define BUS_ATTR_RW(_name) \ - struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) -#define BUS_ATTR_RO(_name) \ - struct bus_attribute bus_attr_##_name = __ATTR_RO(_name) -#define BUS_ATTR_WO(_name) \ - struct bus_attribute bus_attr_##_name = __ATTR_WO(_name) - -extern int __must_check bus_create_file(struct bus_type *, - struct bus_attribute *); -extern void bus_remove_file(struct bus_type *, struct bus_attribute *); - -/** - * struct bus_type - The bus type of the device - * - * @name: The name of the bus. - * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id). - * @dev_root: Default device to use as the parent. - * @bus_groups: Default attributes of the bus. - * @dev_groups: Default attributes of the devices on the bus. - * @drv_groups: Default attributes of the device drivers on the bus. - * @match: Called, perhaps multiple times, whenever a new device or driver - * is added for this bus. It should return a positive value if the - * given device can be handled by the given driver and zero - * otherwise. It may also return error code if determining that - * the driver supports the device is not possible. In case of - * -EPROBE_DEFER it will queue the device for deferred probing. - * @uevent: Called when a device is added, removed, or a few other things - * that generate uevents to add the environment variables. - * @probe: Called when a new device or driver add to this bus, and callback - * the specific driver's probe to initial the matched device. - * @sync_state: Called to sync device state to software state after all the - * state tracking consumers linked to this device (present at - * the time of late_initcall) have successfully bound to a - * driver. If the device has no consumers, this function will - * be called at late_initcall_sync level. If the device has - * consumers that are never bound to a driver, this function - * will never get called until they do. - * @remove: Called when a device removed from this bus. - * @shutdown: Called at shut-down time to quiesce the device. - * - * @online: Called to put the device back online (after offlining it). - * @offline: Called to put the device offline for hot-removal. May fail. - * - * @suspend: Called when a device on this bus wants to go to sleep mode. - * @resume: Called to bring a device on this bus out of sleep mode. - * @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. - * @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 - * driver implementations to a bus and allow the driver to do - * bus-specific setup - * @p: The private data of the driver core, only the driver core can - * touch this. - * @lock_key: Lock class key for use by the lock validator - * @need_parent_lock: When probing or removing a device on this bus, the - * device core should lock the device's parent. - * - * A bus is a channel between the processor and one or more devices. For the - * purposes of the device model, all devices are connected via a bus, even if - * it is an internal, virtual, "platform" bus. Buses can plug into each other. - * A USB controller is usually a PCI device, for example. The device model - * represents the actual connections between buses and the devices they control. - * A bus is represented by the bus_type structure. It contains the name, the - * default attributes, the bus' methods, PM operations, and the driver core's - * private data. - */ -struct bus_type { - const char *name; - const char *dev_name; - struct device *dev_root; - const struct attribute_group **bus_groups; - const struct attribute_group **dev_groups; - const struct attribute_group **drv_groups; - - int (*match)(struct device *dev, struct device_driver *drv); - int (*uevent)(struct device *dev, struct kobj_uevent_env *env); - int (*probe)(struct device *dev); - void (*sync_state)(struct device *dev); - int (*remove)(struct device *dev); - void (*shutdown)(struct device *dev); - - int (*online)(struct device *dev); - int (*offline)(struct device *dev); - - int (*suspend)(struct device *dev, pm_message_t state); - int (*resume)(struct device *dev); - - int (*num_vf)(struct device *dev); - - int (*dma_configure)(struct device *dev); - - const struct dev_pm_ops *pm; - - const struct iommu_ops *iommu_ops; - - struct subsys_private *p; - struct lock_class_key lock_key; - - bool need_parent_lock; -}; - -extern int __must_check bus_register(struct bus_type *bus); - -extern void bus_unregister(struct bus_type *bus); - -extern int __must_check bus_rescan_devices(struct bus_type *bus); - -/* iterator helpers for buses */ -struct subsys_dev_iter { - struct klist_iter ki; - const struct device_type *type; -}; -void subsys_dev_iter_init(struct subsys_dev_iter *iter, - struct bus_type *subsys, - struct device *start, - const struct device_type *type); -struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter); -void subsys_dev_iter_exit(struct subsys_dev_iter *iter); - -int device_match_name(struct device *dev, const void *name); -int device_match_of_node(struct device *dev, const void *np); -int device_match_fwnode(struct device *dev, const void *fwnode); -int device_match_devt(struct device *dev, const void *pdevt); -int device_match_acpi_dev(struct device *dev, const void *adev); -int device_match_any(struct device *dev, const void *unused); - -int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, - int (*fn)(struct device *dev, void *data)); -struct device *bus_find_device(struct bus_type *bus, struct device *start, - const void *data, - int (*match)(struct device *dev, const void *data)); -/** - * bus_find_device_by_name - device iterator for locating a particular device - * of a specific name. - * @bus: bus type - * @start: Device to begin with - * @name: name of the device to match - */ -static inline struct device *bus_find_device_by_name(struct bus_type *bus, - struct device *start, - const char *name) -{ - return bus_find_device(bus, start, name, device_match_name); -} - -/** - * bus_find_device_by_of_node : device iterator for locating a particular device - * matching the of_node. - * @bus: bus type - * @np: of_node of the device to match. - */ -static inline struct device * -bus_find_device_by_of_node(struct bus_type *bus, const struct device_node *np) -{ - return bus_find_device(bus, NULL, np, device_match_of_node); -} - -/** - * bus_find_device_by_fwnode : device iterator for locating a particular device - * matching the fwnode. - * @bus: bus type - * @fwnode: fwnode of the device to match. - */ -static inline struct device * -bus_find_device_by_fwnode(struct bus_type *bus, const struct fwnode_handle *fwnode) -{ - return bus_find_device(bus, NULL, fwnode, device_match_fwnode); -} - -/** - * bus_find_device_by_devt : device iterator for locating a particular device - * matching the device type. - * @bus: bus type - * @devt: device type of the device to match. - */ -static inline struct device *bus_find_device_by_devt(struct bus_type *bus, - dev_t devt) -{ - return bus_find_device(bus, NULL, &devt, device_match_devt); -} - -/** - * bus_find_next_device - Find the next device after a given device in a - * given bus. - * @bus: bus type - * @cur: device to begin the search with. - */ -static inline struct device * -bus_find_next_device(struct bus_type *bus,struct device *cur) -{ - return bus_find_device(bus, cur, NULL, device_match_any); -} - -#ifdef CONFIG_ACPI -struct acpi_device; - -/** - * bus_find_device_by_acpi_dev : device iterator for locating a particular device - * matching the ACPI COMPANION device. - * @bus: bus type - * @adev: ACPI COMPANION device to match. - */ -static inline struct device * -bus_find_device_by_acpi_dev(struct bus_type *bus, const struct acpi_device *adev) -{ - return bus_find_device(bus, NULL, adev, device_match_acpi_dev); -} -#else -static inline struct device * -bus_find_device_by_acpi_dev(struct bus_type *bus, const void *adev) -{ - return NULL; -} -#endif - -struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id, - struct device *hint); -int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, - void *data, int (*fn)(struct device_driver *, void *)); -void bus_sort_breadthfirst(struct bus_type *bus, - int (*compare)(const struct device *a, - const struct device *b)); -/* - * Bus notifiers: Get notified of addition/removal of devices - * and binding/unbinding of drivers to devices. - * In the long run, it should be a replacement for the platform - * notify hooks. - */ -struct notifier_block; - -extern int bus_register_notifier(struct bus_type *bus, - struct notifier_block *nb); -extern int bus_unregister_notifier(struct bus_type *bus, - struct notifier_block *nb); - -/* All 4 notifers below get called with the target struct device * - * as an argument. Note that those functions are likely to be called - * with the device lock held in the core, so be careful. - */ -#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ -#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device to be removed */ -#define BUS_NOTIFY_REMOVED_DEVICE 0x00000003 /* device removed */ -#define BUS_NOTIFY_BIND_DRIVER 0x00000004 /* driver about to be - bound */ -#define BUS_NOTIFY_BOUND_DRIVER 0x00000005 /* driver bound to device */ -#define BUS_NOTIFY_UNBIND_DRIVER 0x00000006 /* driver about to be - unbound */ -#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000007 /* driver is unbound - from the device */ -#define BUS_NOTIFY_DRIVER_NOT_BOUND 0x00000008 /* driver fails to be bound */ - -extern struct kset *bus_get_kset(struct bus_type *bus); -extern struct klist *bus_get_device_klist(struct bus_type *bus); - /** * enum probe_type - device driver probe type to try * Device drivers may opt in for special handling of their diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h new file mode 100644 index 000000000000..1ea5e1d1545b --- /dev/null +++ b/include/linux/device/bus.h @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * bus.h - the bus-specific portions of the driver model + * + * Copyright (c) 2001-2003 Patrick Mochel + * Copyright (c) 2004-2009 Greg Kroah-Hartman + * Copyright (c) 2008-2009 Novell Inc. + * Copyright (c) 2012-2019 Greg Kroah-Hartman + * Copyright (c) 2012-2019 Linux Foundation + * + * See Documentation/driver-api/driver-model/ for more information. + */ + +#ifndef _DEVICE_BUS_H_ +#define _DEVICE_BUS_H_ + +#include +#include +#include + +struct device_driver; +struct fwnode_handle; + +/** + * struct bus_type - The bus type of the device + * + * @name: The name of the bus. + * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id). + * @dev_root: Default device to use as the parent. + * @bus_groups: Default attributes of the bus. + * @dev_groups: Default attributes of the devices on the bus. + * @drv_groups: Default attributes of the device drivers on the bus. + * @match: Called, perhaps multiple times, whenever a new device or driver + * is added for this bus. It should return a positive value if the + * given device can be handled by the given driver and zero + * otherwise. It may also return error code if determining that + * the driver supports the device is not possible. In case of + * -EPROBE_DEFER it will queue the device for deferred probing. + * @uevent: Called when a device is added, removed, or a few other things + * that generate uevents to add the environment variables. + * @probe: Called when a new device or driver add to this bus, and callback + * the specific driver's probe to initial the matched device. + * @sync_state: Called to sync device state to software state after all the + * state tracking consumers linked to this device (present at + * the time of late_initcall) have successfully bound to a + * driver. If the device has no consumers, this function will + * be called at late_initcall_sync level. If the device has + * consumers that are never bound to a driver, this function + * will never get called until they do. + * @remove: Called when a device removed from this bus. + * @shutdown: Called at shut-down time to quiesce the device. + * + * @online: Called to put the device back online (after offlining it). + * @offline: Called to put the device offline for hot-removal. May fail. + * + * @suspend: Called when a device on this bus wants to go to sleep mode. + * @resume: Called to bring a device on this bus out of sleep mode. + * @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. + * @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 + * driver implementations to a bus and allow the driver to do + * bus-specific setup + * @p: The private data of the driver core, only the driver core can + * touch this. + * @lock_key: Lock class key for use by the lock validator + * @need_parent_lock: When probing or removing a device on this bus, the + * device core should lock the device's parent. + * + * A bus is a channel between the processor and one or more devices. For the + * purposes of the device model, all devices are connected via a bus, even if + * it is an internal, virtual, "platform" bus. Buses can plug into each other. + * A USB controller is usually a PCI device, for example. The device model + * represents the actual connections between buses and the devices they control. + * A bus is represented by the bus_type structure. It contains the name, the + * default attributes, the bus' methods, PM operations, and the driver core's + * private data. + */ +struct bus_type { + const char *name; + const char *dev_name; + struct device *dev_root; + const struct attribute_group **bus_groups; + const struct attribute_group **dev_groups; + const struct attribute_group **drv_groups; + + int (*match)(struct device *dev, struct device_driver *drv); + int (*uevent)(struct device *dev, struct kobj_uevent_env *env); + int (*probe)(struct device *dev); + void (*sync_state)(struct device *dev); + int (*remove)(struct device *dev); + void (*shutdown)(struct device *dev); + + int (*online)(struct device *dev); + int (*offline)(struct device *dev); + + int (*suspend)(struct device *dev, pm_message_t state); + int (*resume)(struct device *dev); + + int (*num_vf)(struct device *dev); + + int (*dma_configure)(struct device *dev); + + const struct dev_pm_ops *pm; + + const struct iommu_ops *iommu_ops; + + struct subsys_private *p; + struct lock_class_key lock_key; + + bool need_parent_lock; +}; + +extern int __must_check bus_register(struct bus_type *bus); + +extern void bus_unregister(struct bus_type *bus); + +extern int __must_check bus_rescan_devices(struct bus_type *bus); + +struct bus_attribute { + struct attribute attr; + ssize_t (*show)(struct bus_type *bus, char *buf); + ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count); +}; + +#define BUS_ATTR_RW(_name) \ + struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) +#define BUS_ATTR_RO(_name) \ + struct bus_attribute bus_attr_##_name = __ATTR_RO(_name) +#define BUS_ATTR_WO(_name) \ + struct bus_attribute bus_attr_##_name = __ATTR_WO(_name) + +extern int __must_check bus_create_file(struct bus_type *, + struct bus_attribute *); +extern void bus_remove_file(struct bus_type *, struct bus_attribute *); + +/* Generic device matching functions that all busses can use to match with */ +int device_match_name(struct device *dev, const void *name); +int device_match_of_node(struct device *dev, const void *np); +int device_match_fwnode(struct device *dev, const void *fwnode); +int device_match_devt(struct device *dev, const void *pdevt); +int device_match_acpi_dev(struct device *dev, const void *adev); +int device_match_any(struct device *dev, const void *unused); + +/* iterator helpers for buses */ +struct subsys_dev_iter { + struct klist_iter ki; + const struct device_type *type; +}; +void subsys_dev_iter_init(struct subsys_dev_iter *iter, + struct bus_type *subsys, + struct device *start, + const struct device_type *type); +struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter); +void subsys_dev_iter_exit(struct subsys_dev_iter *iter); + +int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, + int (*fn)(struct device *dev, void *data)); +struct device *bus_find_device(struct bus_type *bus, struct device *start, + const void *data, + int (*match)(struct device *dev, const void *data)); +/** + * bus_find_device_by_name - device iterator for locating a particular device + * of a specific name. + * @bus: bus type + * @start: Device to begin with + * @name: name of the device to match + */ +static inline struct device *bus_find_device_by_name(struct bus_type *bus, + struct device *start, + const char *name) +{ + return bus_find_device(bus, start, name, device_match_name); +} + +/** + * bus_find_device_by_of_node : device iterator for locating a particular device + * matching the of_node. + * @bus: bus type + * @np: of_node of the device to match. + */ +static inline struct device * +bus_find_device_by_of_node(struct bus_type *bus, const struct device_node *np) +{ + return bus_find_device(bus, NULL, np, device_match_of_node); +} + +/** + * bus_find_device_by_fwnode : device iterator for locating a particular device + * matching the fwnode. + * @bus: bus type + * @fwnode: fwnode of the device to match. + */ +static inline struct device * +bus_find_device_by_fwnode(struct bus_type *bus, const struct fwnode_handle *fwnode) +{ + return bus_find_device(bus, NULL, fwnode, device_match_fwnode); +} + +/** + * bus_find_device_by_devt : device iterator for locating a particular device + * matching the device type. + * @bus: bus type + * @devt: device type of the device to match. + */ +static inline struct device *bus_find_device_by_devt(struct bus_type *bus, + dev_t devt) +{ + return bus_find_device(bus, NULL, &devt, device_match_devt); +} + +/** + * bus_find_next_device - Find the next device after a given device in a + * given bus. + * @bus: bus type + * @cur: device to begin the search with. + */ +static inline struct device * +bus_find_next_device(struct bus_type *bus,struct device *cur) +{ + return bus_find_device(bus, cur, NULL, device_match_any); +} + +#ifdef CONFIG_ACPI +struct acpi_device; + +/** + * bus_find_device_by_acpi_dev : device iterator for locating a particular device + * matching the ACPI COMPANION device. + * @bus: bus type + * @adev: ACPI COMPANION device to match. + */ +static inline struct device * +bus_find_device_by_acpi_dev(struct bus_type *bus, const struct acpi_device *adev) +{ + return bus_find_device(bus, NULL, adev, device_match_acpi_dev); +} +#else +static inline struct device * +bus_find_device_by_acpi_dev(struct bus_type *bus, const void *adev) +{ + return NULL; +} +#endif + +struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id, + struct device *hint); +int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, + void *data, int (*fn)(struct device_driver *, void *)); +void bus_sort_breadthfirst(struct bus_type *bus, + int (*compare)(const struct device *a, + const struct device *b)); +/* + * Bus notifiers: Get notified of addition/removal of devices + * and binding/unbinding of drivers to devices. + * In the long run, it should be a replacement for the platform + * notify hooks. + */ +struct notifier_block; + +extern int bus_register_notifier(struct bus_type *bus, + struct notifier_block *nb); +extern int bus_unregister_notifier(struct bus_type *bus, + struct notifier_block *nb); + +/* All 4 notifers below get called with the target struct device * + * as an argument. Note that those functions are likely to be called + * with the device lock held in the core, so be careful. + */ +#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ +#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device to be removed */ +#define BUS_NOTIFY_REMOVED_DEVICE 0x00000003 /* device removed */ +#define BUS_NOTIFY_BIND_DRIVER 0x00000004 /* driver about to be + bound */ +#define BUS_NOTIFY_BOUND_DRIVER 0x00000005 /* driver bound to device */ +#define BUS_NOTIFY_UNBIND_DRIVER 0x00000006 /* driver about to be + unbound */ +#define BUS_NOTIFY_UNBOUND_DRIVER 0x00000007 /* driver is unbound + from the device */ +#define BUS_NOTIFY_DRIVER_NOT_BOUND 0x00000008 /* driver fails to be bound */ + +extern struct kset *bus_get_kset(struct bus_type *bus); +extern struct klist *bus_get_device_klist(struct bus_type *bus); + +#endif -- cgit v1.2.3-59-g8ed1b From a8ae608529ab1b71a3830895f98a107be90fed48 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Dec 2019 20:33:02 +0100 Subject: device.h: move 'struct class' stuff out to device/class.h device.h has everything and the kitchen sink when it comes to struct device things, so split out the struct class things things to a separate .h file to make things easier to maintain and manage over time. Cc: "Rafael J. Wysocki" Cc: Suzuki K Poulose Cc: Saravana Kannan Cc: Heikki Krogerus Link: https://lore.kernel.org/r/20191209193303.1694546-6-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 1 + include/linux/device.h | 241 +-------------------------------------- include/linux/device/class.h | 266 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 268 insertions(+), 240 deletions(-) create mode 100644 include/linux/device/class.h diff --git a/drivers/base/class.c b/drivers/base/class.c index d8a6a5864c2e..bcd410e6d70a 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -8,6 +8,7 @@ * Copyright (c) 2003-2004 IBM Corp. */ +#include #include #include #include diff --git a/include/linux/device.h b/include/linux/device.h index 22fd0b91d0fa..4c261fbd7053 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -27,6 +27,7 @@ #include #include #include +#include #include struct device; @@ -294,246 +295,6 @@ int subsys_system_register(struct bus_type *subsys, int subsys_virtual_register(struct bus_type *subsys, const struct attribute_group **groups); -/** - * struct class - device classes - * @name: Name of the class. - * @owner: The module owner. - * @class_groups: Default attributes of this class. - * @dev_groups: Default attributes of the devices that belong to the class. - * @dev_kobj: The kobject that represents this class and links it into the hierarchy. - * @dev_uevent: Called when a device is added, removed from this class, or a - * few other things that generate uevents to add the environment - * variables. - * @devnode: Callback to provide the devtmpfs. - * @class_release: Called to release this class. - * @dev_release: Called to release the device. - * @shutdown_pre: Called at shut-down time before driver shutdown. - * @ns_type: Callbacks so sysfs can detemine namespaces. - * @namespace: Namespace of the device belongs to this class. - * @get_ownership: Allows class to specify uid/gid of the sysfs directories - * for the devices belonging to the class. Usually tied to - * device's namespace. - * @pm: The default device power management operations of this class. - * @p: The private data of the driver core, no one other than the - * driver core can touch this. - * - * A class is a higher-level view of a device that abstracts out low-level - * implementation details. Drivers may see a SCSI disk or an ATA disk, but, - * at the class level, they are all simply disks. Classes allow user space - * to work with devices based on what they do, rather than how they are - * connected or how they work. - */ -struct class { - const char *name; - struct module *owner; - - const struct attribute_group **class_groups; - const struct attribute_group **dev_groups; - struct kobject *dev_kobj; - - int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); - char *(*devnode)(struct device *dev, umode_t *mode); - - void (*class_release)(struct class *class); - void (*dev_release)(struct device *dev); - - int (*shutdown_pre)(struct device *dev); - - const struct kobj_ns_type_operations *ns_type; - const void *(*namespace)(struct device *dev); - - void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid); - - const struct dev_pm_ops *pm; - - struct subsys_private *p; -}; - -struct class_dev_iter { - struct klist_iter ki; - const struct device_type *type; -}; - -extern struct kobject *sysfs_dev_block_kobj; -extern struct kobject *sysfs_dev_char_kobj; -extern int __must_check __class_register(struct class *class, - struct lock_class_key *key); -extern void class_unregister(struct class *class); - -/* This is a #define to keep the compiler from merging different - * instances of the __key variable */ -#define class_register(class) \ -({ \ - static struct lock_class_key __key; \ - __class_register(class, &__key); \ -}) - -struct class_compat; -struct class_compat *class_compat_register(const char *name); -void class_compat_unregister(struct class_compat *cls); -int class_compat_create_link(struct class_compat *cls, struct device *dev, - struct device *device_link); -void class_compat_remove_link(struct class_compat *cls, struct device *dev, - struct device *device_link); - -extern void class_dev_iter_init(struct class_dev_iter *iter, - struct class *class, - struct device *start, - const struct device_type *type); -extern struct device *class_dev_iter_next(struct class_dev_iter *iter); -extern void class_dev_iter_exit(struct class_dev_iter *iter); - -extern int class_for_each_device(struct class *class, struct device *start, - void *data, - int (*fn)(struct device *dev, void *data)); -extern struct device *class_find_device(struct class *class, - struct device *start, const void *data, - int (*match)(struct device *, const void *)); - -/** - * class_find_device_by_name - device iterator for locating a particular device - * of a specific name. - * @class: class type - * @name: name of the device to match - */ -static inline struct device *class_find_device_by_name(struct class *class, - const char *name) -{ - return class_find_device(class, NULL, name, device_match_name); -} - -/** - * class_find_device_by_of_node : device iterator for locating a particular device - * matching the of_node. - * @class: class type - * @np: of_node of the device to match. - */ -static inline struct device * -class_find_device_by_of_node(struct class *class, const struct device_node *np) -{ - return class_find_device(class, NULL, np, device_match_of_node); -} - -/** - * class_find_device_by_fwnode : device iterator for locating a particular device - * matching the fwnode. - * @class: class type - * @fwnode: fwnode of the device to match. - */ -static inline struct device * -class_find_device_by_fwnode(struct class *class, - const struct fwnode_handle *fwnode) -{ - return class_find_device(class, NULL, fwnode, device_match_fwnode); -} - -/** - * class_find_device_by_devt : device iterator for locating a particular device - * matching the device type. - * @class: class type - * @devt: device type of the device to match. - */ -static inline struct device *class_find_device_by_devt(struct class *class, - dev_t devt) -{ - return class_find_device(class, NULL, &devt, device_match_devt); -} - -#ifdef CONFIG_ACPI -struct acpi_device; -/** - * class_find_device_by_acpi_dev : device iterator for locating a particular - * device matching the ACPI_COMPANION device. - * @class: class type - * @adev: ACPI_COMPANION device to match. - */ -static inline struct device * -class_find_device_by_acpi_dev(struct class *class, const struct acpi_device *adev) -{ - return class_find_device(class, NULL, adev, device_match_acpi_dev); -} -#else -static inline struct device * -class_find_device_by_acpi_dev(struct class *class, const void *adev) -{ - return NULL; -} -#endif - -struct class_attribute { - struct attribute attr; - ssize_t (*show)(struct class *class, struct class_attribute *attr, - char *buf); - ssize_t (*store)(struct class *class, struct class_attribute *attr, - const char *buf, size_t count); -}; - -#define CLASS_ATTR_RW(_name) \ - struct class_attribute class_attr_##_name = __ATTR_RW(_name) -#define CLASS_ATTR_RO(_name) \ - struct class_attribute class_attr_##_name = __ATTR_RO(_name) -#define CLASS_ATTR_WO(_name) \ - struct class_attribute class_attr_##_name = __ATTR_WO(_name) - -extern int __must_check class_create_file_ns(struct class *class, - const struct class_attribute *attr, - const void *ns); -extern void class_remove_file_ns(struct class *class, - const struct class_attribute *attr, - const void *ns); - -static inline int __must_check class_create_file(struct class *class, - const struct class_attribute *attr) -{ - return class_create_file_ns(class, attr, NULL); -} - -static inline void class_remove_file(struct class *class, - const struct class_attribute *attr) -{ - return class_remove_file_ns(class, attr, NULL); -} - -/* Simple class attribute that is just a static string */ -struct class_attribute_string { - struct class_attribute attr; - char *str; -}; - -/* Currently read-only only */ -#define _CLASS_ATTR_STRING(_name, _mode, _str) \ - { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } -#define CLASS_ATTR_STRING(_name, _mode, _str) \ - struct class_attribute_string class_attr_##_name = \ - _CLASS_ATTR_STRING(_name, _mode, _str) - -extern ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, - char *buf); - -struct class_interface { - struct list_head node; - struct class *class; - - int (*add_dev) (struct device *, struct class_interface *); - void (*remove_dev) (struct device *, struct class_interface *); -}; - -extern int __must_check class_interface_register(struct class_interface *); -extern void class_interface_unregister(struct class_interface *); - -extern struct class * __must_check __class_create(struct module *owner, - const char *name, - struct lock_class_key *key); -extern void class_destroy(struct class *cls); - -/* This is a #define to keep the compiler from merging different - * instances of the __key variable */ -#define class_create(owner, name) \ -({ \ - static struct lock_class_key __key; \ - __class_create(owner, name, &__key); \ -}) - /* * The type of device, "struct device" is embedded in. A class * or bus can contain devices of different types diff --git a/include/linux/device/class.h b/include/linux/device/class.h new file mode 100644 index 000000000000..e8d470c457d1 --- /dev/null +++ b/include/linux/device/class.h @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The class-specific portions of the driver model + * + * Copyright (c) 2001-2003 Patrick Mochel + * Copyright (c) 2004-2009 Greg Kroah-Hartman + * Copyright (c) 2008-2009 Novell Inc. + * Copyright (c) 2012-2019 Greg Kroah-Hartman + * Copyright (c) 2012-2019 Linux Foundation + * + * See Documentation/driver-api/driver-model/ for more information. + */ + +#ifndef _DEVICE_CLASS_H_ +#define _DEVICE_CLASS_H_ + +#include +#include +#include +#include + +struct device; +struct fwnode_handle; + +/** + * struct class - device classes + * @name: Name of the class. + * @owner: The module owner. + * @class_groups: Default attributes of this class. + * @dev_groups: Default attributes of the devices that belong to the class. + * @dev_kobj: The kobject that represents this class and links it into the hierarchy. + * @dev_uevent: Called when a device is added, removed from this class, or a + * few other things that generate uevents to add the environment + * variables. + * @devnode: Callback to provide the devtmpfs. + * @class_release: Called to release this class. + * @dev_release: Called to release the device. + * @shutdown_pre: Called at shut-down time before driver shutdown. + * @ns_type: Callbacks so sysfs can detemine namespaces. + * @namespace: Namespace of the device belongs to this class. + * @get_ownership: Allows class to specify uid/gid of the sysfs directories + * for the devices belonging to the class. Usually tied to + * device's namespace. + * @pm: The default device power management operations of this class. + * @p: The private data of the driver core, no one other than the + * driver core can touch this. + * + * A class is a higher-level view of a device that abstracts out low-level + * implementation details. Drivers may see a SCSI disk or an ATA disk, but, + * at the class level, they are all simply disks. Classes allow user space + * to work with devices based on what they do, rather than how they are + * connected or how they work. + */ +struct class { + const char *name; + struct module *owner; + + const struct attribute_group **class_groups; + const struct attribute_group **dev_groups; + struct kobject *dev_kobj; + + int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env); + char *(*devnode)(struct device *dev, umode_t *mode); + + void (*class_release)(struct class *class); + void (*dev_release)(struct device *dev); + + int (*shutdown_pre)(struct device *dev); + + const struct kobj_ns_type_operations *ns_type; + const void *(*namespace)(struct device *dev); + + void (*get_ownership)(struct device *dev, kuid_t *uid, kgid_t *gid); + + const struct dev_pm_ops *pm; + + struct subsys_private *p; +}; + +struct class_dev_iter { + struct klist_iter ki; + const struct device_type *type; +}; + +extern struct kobject *sysfs_dev_block_kobj; +extern struct kobject *sysfs_dev_char_kobj; +extern int __must_check __class_register(struct class *class, + struct lock_class_key *key); +extern void class_unregister(struct class *class); + +/* This is a #define to keep the compiler from merging different + * instances of the __key variable */ +#define class_register(class) \ +({ \ + static struct lock_class_key __key; \ + __class_register(class, &__key); \ +}) + +struct class_compat; +struct class_compat *class_compat_register(const char *name); +void class_compat_unregister(struct class_compat *cls); +int class_compat_create_link(struct class_compat *cls, struct device *dev, + struct device *device_link); +void class_compat_remove_link(struct class_compat *cls, struct device *dev, + struct device *device_link); + +extern void class_dev_iter_init(struct class_dev_iter *iter, + struct class *class, + struct device *start, + const struct device_type *type); +extern struct device *class_dev_iter_next(struct class_dev_iter *iter); +extern void class_dev_iter_exit(struct class_dev_iter *iter); + +extern int class_for_each_device(struct class *class, struct device *start, + void *data, + int (*fn)(struct device *dev, void *data)); +extern struct device *class_find_device(struct class *class, + struct device *start, const void *data, + int (*match)(struct device *, const void *)); + +/** + * class_find_device_by_name - device iterator for locating a particular device + * of a specific name. + * @class: class type + * @name: name of the device to match + */ +static inline struct device *class_find_device_by_name(struct class *class, + const char *name) +{ + return class_find_device(class, NULL, name, device_match_name); +} + +/** + * class_find_device_by_of_node : device iterator for locating a particular device + * matching the of_node. + * @class: class type + * @np: of_node of the device to match. + */ +static inline struct device * +class_find_device_by_of_node(struct class *class, const struct device_node *np) +{ + return class_find_device(class, NULL, np, device_match_of_node); +} + +/** + * class_find_device_by_fwnode : device iterator for locating a particular device + * matching the fwnode. + * @class: class type + * @fwnode: fwnode of the device to match. + */ +static inline struct device * +class_find_device_by_fwnode(struct class *class, + const struct fwnode_handle *fwnode) +{ + return class_find_device(class, NULL, fwnode, device_match_fwnode); +} + +/** + * class_find_device_by_devt : device iterator for locating a particular device + * matching the device type. + * @class: class type + * @devt: device type of the device to match. + */ +static inline struct device *class_find_device_by_devt(struct class *class, + dev_t devt) +{ + return class_find_device(class, NULL, &devt, device_match_devt); +} + +#ifdef CONFIG_ACPI +struct acpi_device; +/** + * class_find_device_by_acpi_dev : device iterator for locating a particular + * device matching the ACPI_COMPANION device. + * @class: class type + * @adev: ACPI_COMPANION device to match. + */ +static inline struct device * +class_find_device_by_acpi_dev(struct class *class, const struct acpi_device *adev) +{ + return class_find_device(class, NULL, adev, device_match_acpi_dev); +} +#else +static inline struct device * +class_find_device_by_acpi_dev(struct class *class, const void *adev) +{ + return NULL; +} +#endif + +struct class_attribute { + struct attribute attr; + ssize_t (*show)(struct class *class, struct class_attribute *attr, + char *buf); + ssize_t (*store)(struct class *class, struct class_attribute *attr, + const char *buf, size_t count); +}; + +#define CLASS_ATTR_RW(_name) \ + struct class_attribute class_attr_##_name = __ATTR_RW(_name) +#define CLASS_ATTR_RO(_name) \ + struct class_attribute class_attr_##_name = __ATTR_RO(_name) +#define CLASS_ATTR_WO(_name) \ + struct class_attribute class_attr_##_name = __ATTR_WO(_name) + +extern int __must_check class_create_file_ns(struct class *class, + const struct class_attribute *attr, + const void *ns); +extern void class_remove_file_ns(struct class *class, + const struct class_attribute *attr, + const void *ns); + +static inline int __must_check class_create_file(struct class *class, + const struct class_attribute *attr) +{ + return class_create_file_ns(class, attr, NULL); +} + +static inline void class_remove_file(struct class *class, + const struct class_attribute *attr) +{ + return class_remove_file_ns(class, attr, NULL); +} + +/* Simple class attribute that is just a static string */ +struct class_attribute_string { + struct class_attribute attr; + char *str; +}; + +/* Currently read-only only */ +#define _CLASS_ATTR_STRING(_name, _mode, _str) \ + { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } +#define CLASS_ATTR_STRING(_name, _mode, _str) \ + struct class_attribute_string class_attr_##_name = \ + _CLASS_ATTR_STRING(_name, _mode, _str) + +extern ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, + char *buf); + +struct class_interface { + struct list_head node; + struct class *class; + + int (*add_dev) (struct device *, struct class_interface *); + void (*remove_dev) (struct device *, struct class_interface *); +}; + +extern int __must_check class_interface_register(struct class_interface *); +extern void class_interface_unregister(struct class_interface *); + +extern struct class * __must_check __class_create(struct module *owner, + const char *name, + struct lock_class_key *key); +extern void class_destroy(struct class *cls); + +/* This is a #define to keep the compiler from merging different + * instances of the __key variable */ +#define class_create(owner, name) \ +({ \ + static struct lock_class_key __key; \ + __class_create(owner, name, &__key); \ +}) + + +#endif /* _DEVICE_CLASS_H_ */ -- cgit v1.2.3-59-g8ed1b From 4c002c978b7f2f2306d53de051c054504af920a9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 9 Dec 2019 20:33:03 +0100 Subject: device.h: move 'struct driver' stuff out to device/driver.h device.h has everything and the kitchen sink when it comes to struct device things, so split out the struct driver things things to a separate .h file to make things easier to maintain and manage over time. Cc: "Rafael J. Wysocki" Cc: Suzuki K Poulose Cc: Saravana Kannan Cc: Heikki Krogerus Link: https://lore.kernel.org/r/20191209193303.1694546-7-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 1 + include/linux/device.h | 272 +-------------------------------------- include/linux/device/driver.h | 292 ++++++++++++++++++++++++++++++++++++++++++ init/main.c | 2 +- 4 files changed, 295 insertions(+), 272 deletions(-) create mode 100644 include/linux/device/driver.h diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 4e5ca632f35e..57c68769e157 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -8,6 +8,7 @@ * Copyright (c) 2007 Novell Inc. */ +#include #include #include #include diff --git a/include/linux/device.h b/include/linux/device.h index 4c261fbd7053..0cd7c647c16c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -28,6 +28,7 @@ #include #include #include +#include #include struct device; @@ -45,227 +46,6 @@ struct iommu_fwspec; struct dev_pin_info; struct iommu_param; -/** - * enum probe_type - device driver probe type to try - * Device drivers may opt in for special handling of their - * respective probe routines. This tells the core what to - * expect and prefer. - * - * @PROBE_DEFAULT_STRATEGY: Used by drivers that work equally well - * whether probed synchronously or asynchronously. - * @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which - * probing order is not essential for booting the system may - * opt into executing their probes asynchronously. - * @PROBE_FORCE_SYNCHRONOUS: Use this to annotate drivers that need - * their probe routines to run synchronously with driver and - * device registration (with the exception of -EPROBE_DEFER - * handling - re-probing always ends up being done asynchronously). - * - * Note that the end goal is to switch the kernel to use asynchronous - * probing by default, so annotating drivers with - * %PROBE_PREFER_ASYNCHRONOUS is a temporary measure that allows us - * to speed up boot process while we are validating the rest of the - * drivers. - */ -enum probe_type { - PROBE_DEFAULT_STRATEGY, - PROBE_PREFER_ASYNCHRONOUS, - PROBE_FORCE_SYNCHRONOUS, -}; - -/** - * struct device_driver - The basic device driver structure - * @name: Name of the device driver. - * @bus: The bus which the device of this driver belongs to. - * @owner: The module owner. - * @mod_name: Used for built-in modules. - * @suppress_bind_attrs: Disables bind/unbind via sysfs. - * @probe_type: Type of the probe (synchronous or asynchronous) to use. - * @of_match_table: The open firmware table. - * @acpi_match_table: The ACPI match table. - * @probe: Called to query the existence of a specific device, - * whether this driver can work with it, and bind the driver - * to a specific device. - * @sync_state: Called to sync device state to software state after all the - * state tracking consumers linked to this device (present at - * the time of late_initcall) have successfully bound to a - * driver. If the device has no consumers, this function will - * be called at late_initcall_sync level. If the device has - * consumers that are never bound to a driver, this function - * will never get called until they do. - * @remove: Called when the device is removed from the system to - * unbind a device from this driver. - * @shutdown: Called at shut-down time to quiesce the device. - * @suspend: Called to put the device to sleep mode. Usually to a - * low power state. - * @resume: Called to bring a device from sleep mode. - * @groups: Default attributes that get created by the driver core - * automatically. - * @dev_groups: Additional attributes attached to device instance once the - * it is bound to the driver. - * @pm: Power management operations of the device which matched - * this driver. - * @coredump: Called when sysfs entry is written to. The device driver - * is expected to call the dev_coredump API resulting in a - * uevent. - * @p: Driver core's private data, no one other than the driver - * core can touch this. - * - * The device driver-model tracks all of the drivers known to the system. - * The main reason for this tracking is to enable the driver core to match - * up drivers with new devices. Once drivers are known objects within the - * system, however, a number of other things become possible. Device drivers - * can export information and configuration variables that are independent - * of any specific device. - */ -struct device_driver { - const char *name; - struct bus_type *bus; - - struct module *owner; - const char *mod_name; /* used for built-in modules */ - - bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ - enum probe_type probe_type; - - const struct of_device_id *of_match_table; - const struct acpi_device_id *acpi_match_table; - - int (*probe) (struct device *dev); - void (*sync_state)(struct device *dev); - int (*remove) (struct device *dev); - void (*shutdown) (struct device *dev); - int (*suspend) (struct device *dev, pm_message_t state); - int (*resume) (struct device *dev); - const struct attribute_group **groups; - const struct attribute_group **dev_groups; - - const struct dev_pm_ops *pm; - void (*coredump) (struct device *dev); - - struct driver_private *p; -}; - - -extern int __must_check driver_register(struct device_driver *drv); -extern void driver_unregister(struct device_driver *drv); - -extern struct device_driver *driver_find(const char *name, - struct bus_type *bus); -extern int driver_probe_done(void); -extern void wait_for_device_probe(void); - -/* sysfs interface for exporting driver attributes */ - -struct driver_attribute { - struct attribute attr; - ssize_t (*show)(struct device_driver *driver, char *buf); - ssize_t (*store)(struct device_driver *driver, const char *buf, - size_t count); -}; - -#define DRIVER_ATTR_RW(_name) \ - struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) -#define DRIVER_ATTR_RO(_name) \ - struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) -#define DRIVER_ATTR_WO(_name) \ - struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) - -extern int __must_check driver_create_file(struct device_driver *driver, - const struct driver_attribute *attr); -extern void driver_remove_file(struct device_driver *driver, - const struct driver_attribute *attr); - -extern int __must_check driver_for_each_device(struct device_driver *drv, - struct device *start, - void *data, - int (*fn)(struct device *dev, - void *)); -struct device *driver_find_device(struct device_driver *drv, - struct device *start, const void *data, - int (*match)(struct device *dev, const void *data)); - -/** - * driver_find_device_by_name - device iterator for locating a particular device - * of a specific name. - * @drv: the driver we're iterating - * @name: name of the device to match - */ -static inline struct device *driver_find_device_by_name(struct device_driver *drv, - const char *name) -{ - return driver_find_device(drv, NULL, name, device_match_name); -} - -/** - * driver_find_device_by_of_node- device iterator for locating a particular device - * by of_node pointer. - * @drv: the driver we're iterating - * @np: of_node pointer to match. - */ -static inline struct device * -driver_find_device_by_of_node(struct device_driver *drv, - const struct device_node *np) -{ - return driver_find_device(drv, NULL, np, device_match_of_node); -} - -/** - * driver_find_device_by_fwnode- device iterator for locating a particular device - * by fwnode pointer. - * @drv: the driver we're iterating - * @fwnode: fwnode pointer to match. - */ -static inline struct device * -driver_find_device_by_fwnode(struct device_driver *drv, - const struct fwnode_handle *fwnode) -{ - return driver_find_device(drv, NULL, fwnode, device_match_fwnode); -} - -/** - * driver_find_device_by_devt- device iterator for locating a particular device - * by devt. - * @drv: the driver we're iterating - * @devt: devt pointer to match. - */ -static inline struct device *driver_find_device_by_devt(struct device_driver *drv, - dev_t devt) -{ - return driver_find_device(drv, NULL, &devt, device_match_devt); -} - -static inline struct device *driver_find_next_device(struct device_driver *drv, - struct device *start) -{ - return driver_find_device(drv, start, NULL, device_match_any); -} - -#ifdef CONFIG_ACPI -/** - * driver_find_device_by_acpi_dev : device iterator for locating a particular - * device matching the ACPI_COMPANION device. - * @drv: the driver we're iterating - * @adev: ACPI_COMPANION device to match. - */ -static inline struct device * -driver_find_device_by_acpi_dev(struct device_driver *drv, - const struct acpi_device *adev) -{ - return driver_find_device(drv, NULL, adev, device_match_acpi_dev); -} -#else -static inline struct device * -driver_find_device_by_acpi_dev(struct device_driver *drv, const void *adev) -{ - return NULL; -} -#endif - -void driver_deferred_probe_add(struct device *dev); -int driver_deferred_probe_check_state(struct device *dev); -int driver_deferred_probe_check_state_continue(struct device *dev); - /** * struct subsys_interface - interfaces to device functions * @name: name of the device function @@ -1018,8 +798,6 @@ static inline struct device_node *dev_of_node(struct device *dev) return dev->of_node; } -void driver_init(void); - /* * High level routines for use by the bus drivers */ @@ -1193,52 +971,4 @@ extern long sysfs_deprecated; #define sysfs_deprecated 0 #endif -/** - * module_driver() - Helper macro for drivers that don't do anything - * special in module init/exit. This eliminates a lot of boilerplate. - * Each module may only use this macro once, and calling it replaces - * module_init() and module_exit(). - * - * @__driver: driver name - * @__register: register function for this driver type - * @__unregister: unregister function for this driver type - * @...: Additional arguments to be passed to __register and __unregister. - * - * Use this macro to construct bus specific macros for registering - * drivers, and do not use it on its own. - */ -#define module_driver(__driver, __register, __unregister, ...) \ -static int __init __driver##_init(void) \ -{ \ - return __register(&(__driver) , ##__VA_ARGS__); \ -} \ -module_init(__driver##_init); \ -static void __exit __driver##_exit(void) \ -{ \ - __unregister(&(__driver) , ##__VA_ARGS__); \ -} \ -module_exit(__driver##_exit); - -/** - * builtin_driver() - Helper macro for drivers that don't do anything - * special in init and have no exit. This eliminates some boilerplate. - * Each driver may only use this macro once, and calling it replaces - * device_initcall (or in some cases, the legacy __initcall). This is - * meant to be a direct parallel of module_driver() above but without - * the __exit stuff that is not used for builtin cases. - * - * @__driver: driver name - * @__register: register function for this driver type - * @...: Additional arguments to be passed to __register - * - * Use this macro to construct bus specific macros for registering - * drivers, and do not use it on its own. - */ -#define builtin_driver(__driver, __register, ...) \ -static int __init __driver##_init(void) \ -{ \ - return __register(&(__driver) , ##__VA_ARGS__); \ -} \ -device_initcall(__driver##_init); - #endif /* _DEVICE_H_ */ diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h new file mode 100644 index 000000000000..1188260f9a02 --- /dev/null +++ b/include/linux/device/driver.h @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The driver-specific portions of the driver model + * + * Copyright (c) 2001-2003 Patrick Mochel + * Copyright (c) 2004-2009 Greg Kroah-Hartman + * Copyright (c) 2008-2009 Novell Inc. + * Copyright (c) 2012-2019 Greg Kroah-Hartman + * Copyright (c) 2012-2019 Linux Foundation + * + * See Documentation/driver-api/driver-model/ for more information. + */ + +#ifndef _DEVICE_DRIVER_H_ +#define _DEVICE_DRIVER_H_ + +#include +#include +#include +#include + +/** + * enum probe_type - device driver probe type to try + * Device drivers may opt in for special handling of their + * respective probe routines. This tells the core what to + * expect and prefer. + * + * @PROBE_DEFAULT_STRATEGY: Used by drivers that work equally well + * whether probed synchronously or asynchronously. + * @PROBE_PREFER_ASYNCHRONOUS: Drivers for "slow" devices which + * probing order is not essential for booting the system may + * opt into executing their probes asynchronously. + * @PROBE_FORCE_SYNCHRONOUS: Use this to annotate drivers that need + * their probe routines to run synchronously with driver and + * device registration (with the exception of -EPROBE_DEFER + * handling - re-probing always ends up being done asynchronously). + * + * Note that the end goal is to switch the kernel to use asynchronous + * probing by default, so annotating drivers with + * %PROBE_PREFER_ASYNCHRONOUS is a temporary measure that allows us + * to speed up boot process while we are validating the rest of the + * drivers. + */ +enum probe_type { + PROBE_DEFAULT_STRATEGY, + PROBE_PREFER_ASYNCHRONOUS, + PROBE_FORCE_SYNCHRONOUS, +}; + +/** + * struct device_driver - The basic device driver structure + * @name: Name of the device driver. + * @bus: The bus which the device of this driver belongs to. + * @owner: The module owner. + * @mod_name: Used for built-in modules. + * @suppress_bind_attrs: Disables bind/unbind via sysfs. + * @probe_type: Type of the probe (synchronous or asynchronous) to use. + * @of_match_table: The open firmware table. + * @acpi_match_table: The ACPI match table. + * @probe: Called to query the existence of a specific device, + * whether this driver can work with it, and bind the driver + * to a specific device. + * @sync_state: Called to sync device state to software state after all the + * state tracking consumers linked to this device (present at + * the time of late_initcall) have successfully bound to a + * driver. If the device has no consumers, this function will + * be called at late_initcall_sync level. If the device has + * consumers that are never bound to a driver, this function + * will never get called until they do. + * @remove: Called when the device is removed from the system to + * unbind a device from this driver. + * @shutdown: Called at shut-down time to quiesce the device. + * @suspend: Called to put the device to sleep mode. Usually to a + * low power state. + * @resume: Called to bring a device from sleep mode. + * @groups: Default attributes that get created by the driver core + * automatically. + * @dev_groups: Additional attributes attached to device instance once the + * it is bound to the driver. + * @pm: Power management operations of the device which matched + * this driver. + * @coredump: Called when sysfs entry is written to. The device driver + * is expected to call the dev_coredump API resulting in a + * uevent. + * @p: Driver core's private data, no one other than the driver + * core can touch this. + * + * The device driver-model tracks all of the drivers known to the system. + * The main reason for this tracking is to enable the driver core to match + * up drivers with new devices. Once drivers are known objects within the + * system, however, a number of other things become possible. Device drivers + * can export information and configuration variables that are independent + * of any specific device. + */ +struct device_driver { + const char *name; + struct bus_type *bus; + + struct module *owner; + const char *mod_name; /* used for built-in modules */ + + bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ + enum probe_type probe_type; + + const struct of_device_id *of_match_table; + const struct acpi_device_id *acpi_match_table; + + int (*probe) (struct device *dev); + void (*sync_state)(struct device *dev); + int (*remove) (struct device *dev); + void (*shutdown) (struct device *dev); + int (*suspend) (struct device *dev, pm_message_t state); + int (*resume) (struct device *dev); + const struct attribute_group **groups; + const struct attribute_group **dev_groups; + + const struct dev_pm_ops *pm; + void (*coredump) (struct device *dev); + + struct driver_private *p; +}; + + +extern int __must_check driver_register(struct device_driver *drv); +extern void driver_unregister(struct device_driver *drv); + +extern struct device_driver *driver_find(const char *name, + struct bus_type *bus); +extern int driver_probe_done(void); +extern void wait_for_device_probe(void); + +/* sysfs interface for exporting driver attributes */ + +struct driver_attribute { + struct attribute attr; + ssize_t (*show)(struct device_driver *driver, char *buf); + ssize_t (*store)(struct device_driver *driver, const char *buf, + size_t count); +}; + +#define DRIVER_ATTR_RW(_name) \ + struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) +#define DRIVER_ATTR_RO(_name) \ + struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) +#define DRIVER_ATTR_WO(_name) \ + struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) + +extern int __must_check driver_create_file(struct device_driver *driver, + const struct driver_attribute *attr); +extern void driver_remove_file(struct device_driver *driver, + const struct driver_attribute *attr); + +extern int __must_check driver_for_each_device(struct device_driver *drv, + struct device *start, + void *data, + int (*fn)(struct device *dev, + void *)); +struct device *driver_find_device(struct device_driver *drv, + struct device *start, const void *data, + int (*match)(struct device *dev, const void *data)); + +/** + * driver_find_device_by_name - device iterator for locating a particular device + * of a specific name. + * @drv: the driver we're iterating + * @name: name of the device to match + */ +static inline struct device *driver_find_device_by_name(struct device_driver *drv, + const char *name) +{ + return driver_find_device(drv, NULL, name, device_match_name); +} + +/** + * driver_find_device_by_of_node- device iterator for locating a particular device + * by of_node pointer. + * @drv: the driver we're iterating + * @np: of_node pointer to match. + */ +static inline struct device * +driver_find_device_by_of_node(struct device_driver *drv, + const struct device_node *np) +{ + return driver_find_device(drv, NULL, np, device_match_of_node); +} + +/** + * driver_find_device_by_fwnode- device iterator for locating a particular device + * by fwnode pointer. + * @drv: the driver we're iterating + * @fwnode: fwnode pointer to match. + */ +static inline struct device * +driver_find_device_by_fwnode(struct device_driver *drv, + const struct fwnode_handle *fwnode) +{ + return driver_find_device(drv, NULL, fwnode, device_match_fwnode); +} + +/** + * driver_find_device_by_devt- device iterator for locating a particular device + * by devt. + * @drv: the driver we're iterating + * @devt: devt pointer to match. + */ +static inline struct device *driver_find_device_by_devt(struct device_driver *drv, + dev_t devt) +{ + return driver_find_device(drv, NULL, &devt, device_match_devt); +} + +static inline struct device *driver_find_next_device(struct device_driver *drv, + struct device *start) +{ + return driver_find_device(drv, start, NULL, device_match_any); +} + +#ifdef CONFIG_ACPI +/** + * driver_find_device_by_acpi_dev : device iterator for locating a particular + * device matching the ACPI_COMPANION device. + * @drv: the driver we're iterating + * @adev: ACPI_COMPANION device to match. + */ +static inline struct device * +driver_find_device_by_acpi_dev(struct device_driver *drv, + const struct acpi_device *adev) +{ + return driver_find_device(drv, NULL, adev, device_match_acpi_dev); +} +#else +static inline struct device * +driver_find_device_by_acpi_dev(struct device_driver *drv, const void *adev) +{ + return NULL; +} +#endif + +void driver_deferred_probe_add(struct device *dev); +int driver_deferred_probe_check_state(struct device *dev); +int driver_deferred_probe_check_state_continue(struct device *dev); +void driver_init(void); + +/** + * module_driver() - Helper macro for drivers that don't do anything + * special in module init/exit. This eliminates a lot of boilerplate. + * Each module may only use this macro once, and calling it replaces + * module_init() and module_exit(). + * + * @__driver: driver name + * @__register: register function for this driver type + * @__unregister: unregister function for this driver type + * @...: Additional arguments to be passed to __register and __unregister. + * + * Use this macro to construct bus specific macros for registering + * drivers, and do not use it on its own. + */ +#define module_driver(__driver, __register, __unregister, ...) \ +static int __init __driver##_init(void) \ +{ \ + return __register(&(__driver) , ##__VA_ARGS__); \ +} \ +module_init(__driver##_init); \ +static void __exit __driver##_exit(void) \ +{ \ + __unregister(&(__driver) , ##__VA_ARGS__); \ +} \ +module_exit(__driver##_exit); + +/** + * builtin_driver() - Helper macro for drivers that don't do anything + * special in init and have no exit. This eliminates some boilerplate. + * Each driver may only use this macro once, and calling it replaces + * device_initcall (or in some cases, the legacy __initcall). This is + * meant to be a direct parallel of module_driver() above but without + * the __exit stuff that is not used for builtin cases. + * + * @__driver: driver name + * @__register: register function for this driver type + * @...: Additional arguments to be passed to __register + * + * Use this macro to construct bus specific macros for registering + * drivers, and do not use it on its own. + */ +#define builtin_driver(__driver, __register, ...) \ +static int __init __driver##_init(void) \ +{ \ + return __register(&(__driver) , ##__VA_ARGS__); \ +} \ +device_initcall(__driver##_init); + +#endif /* _DEVICE_DRIVER_H_ */ diff --git a/init/main.c b/init/main.c index ec3a1463ac69..22840d3048b3 100644 --- a/init/main.c +++ b/init/main.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3-59-g8ed1b From adc92dd4550ee038a9794eae1c05d88721a3a737 Mon Sep 17 00:00:00 2001 From: "Daniel W. S. Almeida" Date: Thu, 26 Dec 2019 22:00:33 -0300 Subject: debugfs: Fix warnings when building documentation Fix the following warnings: fs/debugfs/inode.c:423: WARNING: Inline literal start-string without end-string. fs/debugfs/inode.c:502: WARNING: Inline literal start-string without end-string. fs/debugfs/inode.c:534: WARNING: Inline literal start-string without end-string. fs/debugfs/inode.c:627: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:496: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:502: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:581: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:587: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:846: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:852: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:899: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:905: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:1091: WARNING: Inline literal start-string without end-string. fs/debugfs/file.c:1097: WARNING: Inline literal start-string without end-string By replacing %ERR_PTR with ERR_PTR. Signed-off-by: Daniel W. S. Almeida Link: https://lore.kernel.org/r/20191227010035.854913-1-dwlsalmeida@gmail.com Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/file.c | 21 ++++++++++----------- fs/debugfs/inode.c | 9 ++++----- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index dede25247b81..8be46add9105 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -496,10 +496,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n"); * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will + * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will * be returned. */ struct dentry *debugfs_create_u32(const char *name, umode_t mode, @@ -581,10 +581,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_ulong_wo, NULL, debugfs_ulong_set, "%llu\n"); * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will + * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will * be returned. */ struct dentry *debugfs_create_ulong(const char *name, umode_t mode, @@ -846,10 +846,10 @@ static const struct file_operations fops_bool_wo = { * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will + * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will * be returned. */ struct dentry *debugfs_create_bool(const char *name, umode_t mode, @@ -899,10 +899,10 @@ static const struct file_operations fops_blob = { * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will + * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will * be returned. */ struct dentry *debugfs_create_blob(const char *name, umode_t mode, @@ -1091,10 +1091,10 @@ static const struct file_operations fops_regset32 = { * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * - * If debugfs is not enabled in the kernel, the value %ERR_PTR(-ENODEV) will + * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will * be returned. */ struct dentry *debugfs_create_regset32(const char *name, umode_t mode, @@ -1158,4 +1158,3 @@ struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, &debugfs_devm_entry_ops); } EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile); - diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index f4d8df5e4714..dc6cffc4feba 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -423,7 +423,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode, * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * * If debugfs is not enabled in the kernel, the value -%ENODEV will be @@ -502,7 +502,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_unsafe); * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * * If debugfs is not enabled in the kernel, the value -%ENODEV will be @@ -534,7 +534,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file_size); * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the file is * to be removed (no automatic cleanup happens if your module is unloaded, - * you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) will be + * you are responsible here.) If an error occurs, ERR_PTR(-ERROR) will be * returned. * * If debugfs is not enabled in the kernel, the value -%ENODEV will be @@ -627,7 +627,7 @@ EXPORT_SYMBOL(debugfs_create_automount); * This function will return a pointer to a dentry if it succeeds. This * pointer must be passed to the debugfs_remove() function when the symbolic * link is to be removed (no automatic cleanup happens if your module is - * unloaded, you are responsible here.) If an error occurs, %ERR_PTR(-ERROR) + * unloaded, you are responsible here.) If an error occurs, ERR_PTR(-ERROR) * will be returned. * * If debugfs is not enabled in the kernel, the value -%ENODEV will be @@ -906,4 +906,3 @@ static int __init debugfs_init(void) return retval; } core_initcall(debugfs_init); - -- cgit v1.2.3-59-g8ed1b From e2f373320779eb0cece04a11621e9cf518e1c7b1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 18 Dec 2019 23:43:07 +0900 Subject: drivers/component: remove modular code drivers/base/Makefile always adds component.o to obj-y, like this: obj-y := component.o core.o bus.o dd.o syscore.o \ Hence it is never compiled as a module. Remove useless modular code. Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20191218144307.19243-1-masahiroy@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/base/component.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/base/component.c b/drivers/base/component.c index 532a3a5d8f63..3a09036e772a 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -775,5 +774,3 @@ void component_del(struct device *dev, const struct component_ops *ops) kfree(component); } EXPORT_SYMBOL_GPL(component_del); - -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From ef9ffc1e5f1ac73ecd2fb3b70db2a3b2472ff2f7 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 18 Nov 2019 12:54:31 +0100 Subject: component: do not dereference opaque pointer in debugfs The match data does not have to be a struct device pointer, and indeed very often is not. Attempt to treat it as such easily results in a crash. For the components that are not registered, we don't know which device is missing. Once it it is there, we can use the struct component to get the device and whether it's bound or not. Fixes: 59e73854b5fd ('component: add debugfs support') Signed-off-by: Lubomir Rintel Cc: stable Cc: Arnaud Pouliquen Link: https://lore.kernel.org/r/20191118115431.63626-1-lkundrak@v3.sk Signed-off-by: Greg Kroah-Hartman --- drivers/base/component.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/base/component.c b/drivers/base/component.c index 3a09036e772a..c7879f5ae2fb 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -101,11 +101,11 @@ static int component_devices_show(struct seq_file *s, void *data) seq_printf(s, "%-40s %20s\n", "device name", "status"); seq_puts(s, "-------------------------------------------------------------\n"); for (i = 0; i < match->num; i++) { - struct device *d = (struct device *)match->compare[i].data; + struct component *component = match->compare[i].component; - seq_printf(s, "%-40s %20s\n", dev_name(d), - match->compare[i].component ? - "registered" : "not registered"); + seq_printf(s, "%-40s %20s\n", + component ? dev_name(component->dev) : "(unknown)", + component ? (component->bound ? "bound" : "not bound") : "not registered"); } mutex_unlock(&component_mutex); -- cgit v1.2.3-59-g8ed1b From 5bf33f04eb5c3e6c55988046c88a5986430c7b4a Mon Sep 17 00:00:00 2001 From: Mateusz Nosek Date: Mon, 30 Dec 2019 20:16:28 +0100 Subject: fs/kernfs/dir.c: Clean code by removing always true condition Previously there was an additional check if variable pos is not null. However, this check happens after entering while loop and only then, which can happen only if pos is not null. Therefore the additional check is redundant and can be removed. Signed-off-by: Mateusz Nosek Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20191230191628.21099-1-mateusznosek0@gmail.com Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 9d96e6871e1a..9aec80b9d7c6 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1266,7 +1266,7 @@ void kernfs_activate(struct kernfs_node *kn) pos = NULL; while ((pos = kernfs_next_descendant_post(pos, kn))) { - if (!pos || (pos->flags & KERNFS_ACTIVATED)) + if (pos->flags & KERNFS_ACTIVATED) continue; WARN_ON_ONCE(pos->parent && RB_EMPTY_NODE(&pos->rb)); -- cgit v1.2.3-59-g8ed1b From 39cc539f90d035a293240c9443af50be55ee81b8 Mon Sep 17 00:00:00 2001 From: Simon Schwartz Date: Tue, 10 Dec 2019 17:41:37 -0500 Subject: driver core: platform: Prevent resouce overflow from causing infinite loops num_resources in the platform_device struct is declared as a u32. The for loops that iterate over num_resources use an int as the counter, which can cause infinite loops on architectures with smaller ints. Change the loop counters to u32. Signed-off-by: Simon Schwartz Link: https://lore.kernel.org/r/2201ce63a2a171ffd2ed14e867875316efcf71db.camel@theschwartz.xyz Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index cf6b6b722e5c..864b53b3d598 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -48,7 +49,7 @@ EXPORT_SYMBOL_GPL(platform_bus); struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num) { - int i; + u32 i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; @@ -255,7 +256,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name) { - int i; + u32 i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; @@ -501,7 +502,8 @@ EXPORT_SYMBOL_GPL(platform_device_add_properties); */ int platform_device_add(struct platform_device *pdev) { - int i, ret; + u32 i; + int ret; if (!pdev) return -EINVAL; @@ -590,7 +592,7 @@ EXPORT_SYMBOL_GPL(platform_device_add); */ void platform_device_del(struct platform_device *pdev) { - int i; + u32 i; if (!IS_ERR_OR_NULL(pdev)) { device_del(&pdev->dev); -- cgit v1.2.3-59-g8ed1b From 264d25275a46fce5da501874fa48a2ae5ec571c8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 27 Nov 2019 12:24:53 -0800 Subject: driver core: Fix test_async_driver_probe if NUMA is disabled Since commit 57ea974fb871 ("driver core: Rewrite test_async_driver_probe to cover serialization and NUMA affinity"), running the test with NUMA disabled results in warning messages similar to the following. test_async_driver test_async_driver.12: NUMA node mismatch -1 != 0 If CONFIG_NUMA=n, dev_to_node(dev) returns -1, and numa_node_id() returns 0. Both are widely used, so it appears risky to change return values. Augment the check with IS_ENABLED(CONFIG_NUMA) instead to fix the problem. Cc: Alexander Duyck Fixes: 57ea974fb871 ("driver core: Rewrite test_async_driver_probe to cover serialization and NUMA affinity") Signed-off-by: Guenter Roeck Cc: stable Acked-by: Alexander Duyck Link: https://lore.kernel.org/r/20191127202453.28087-1-linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman --- drivers/base/test/test_async_driver_probe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c index f4b1d8e54daf..3bb7beb127a9 100644 --- a/drivers/base/test/test_async_driver_probe.c +++ b/drivers/base/test/test_async_driver_probe.c @@ -44,7 +44,8 @@ static int test_probe(struct platform_device *pdev) * performing an async init on that node. */ if (dev->driver->probe_type == PROBE_PREFER_ASYNCHRONOUS) { - if (dev_to_node(dev) != numa_node_id()) { + if (IS_ENABLED(CONFIG_NUMA) && + dev_to_node(dev) != numa_node_id()) { dev_warn(dev, "NUMA node mismatch %d != %d\n", dev_to_node(dev), numa_node_id()); atomic_inc(&warnings); -- cgit v1.2.3-59-g8ed1b From 7c35e699c88bd60734277b26962783c60e04b494 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 6 Dec 2019 14:22:19 +0100 Subject: driver core: Print device when resources present in really_probe() If a device already has devres items attached before probing, a warning backtrace is printed. However, this backtrace does not reveal the offending device, leaving the user uninformed. Furthermore, using WARN_ON() causes systems with panic-on-warn to reboot. Fix this by replacing the WARN_ON() by a dev_crit() message. Abort probing the device, to prevent doing more damage to the device's resources. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20191206132219.28908-1-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index d811e60610d3..b25bcab2a26b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -516,7 +516,10 @@ static int really_probe(struct device *dev, struct device_driver *drv) atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", drv->bus->name, __func__, drv->name, dev_name(dev)); - WARN_ON(!list_empty(&dev->devres_head)); + if (!list_empty(&dev->devres_head)) { + dev_crit(dev, "Resources present before probing\n"); + return -EBUSY; + } re_probe: dev->driver = drv; -- cgit v1.2.3-59-g8ed1b From a37f4958f7b63d2b3cd17a76151fdfc29ce1da5f Mon Sep 17 00:00:00 2001 From: Eric Snowberg Date: Sat, 7 Dec 2019 11:16:03 -0500 Subject: debugfs: Return -EPERM when locked down When lockdown is enabled, debugfs_is_locked_down returns 1. It will then trigger the following: WARNING: CPU: 48 PID: 3747 CPU: 48 PID: 3743 Comm: bash Not tainted 5.4.0-1946.x86_64 #1 Hardware name: Oracle Corporation ORACLE SERVER X7-2/ASM, MB, X7-2, BIOS 41060400 05/20/2019 RIP: 0010:do_dentry_open+0x343/0x3a0 Code: 00 40 08 00 45 31 ff 48 c7 43 28 40 5b e7 89 e9 02 ff ff ff 48 8b 53 28 4c 8b 72 70 4d 85 f6 0f 84 10 fe ff ff e9 f5 fd ff ff <0f> 0b 41 bf ea ff ff ff e9 3b ff ff ff 41 bf e6 ff ff ff e9 b4 fe RSP: 0018:ffffb8740dde7ca0 EFLAGS: 00010202 RAX: ffffffff89e88a40 RBX: ffff928c8e6b6f00 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff928dbfd97778 RDI: ffff9285cff685c0 RBP: ffffb8740dde7cc8 R08: 0000000000000821 R09: 0000000000000030 R10: 0000000000000057 R11: ffffb8740dde7a98 R12: ffff926ec781c900 R13: ffff928c8e6b6f10 R14: ffffffff8936e190 R15: 0000000000000001 FS: 00007f45f6777740(0000) GS:ffff928dbfd80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fff95e0d5d8 CR3: 0000001ece562006 CR4: 00000000007606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: vfs_open+0x2d/0x30 path_openat+0x2d4/0x1680 ? tty_mode_ioctl+0x298/0x4c0 do_filp_open+0x93/0x100 ? strncpy_from_user+0x57/0x1b0 ? __alloc_fd+0x46/0x150 do_sys_open+0x182/0x230 __x64_sys_openat+0x20/0x30 do_syscall_64+0x60/0x1b0 entry_SYSCALL_64_after_hwframe+0x170/0x1d5 RIP: 0033:0x7f45f5e5ce02 Code: 25 00 00 41 00 3d 00 00 41 00 74 4c 48 8d 05 25 59 2d 00 8b 00 85 c0 75 6d 89 f2 b8 01 01 00 00 48 89 fe bf 9c ff ff ff 0f 05 <48> 3d 00 f0 ff ff 0f 87 a2 00 00 00 48 8b 4c 24 28 64 48 33 0c 25 RSP: 002b:00007fff95e0d2e0 EFLAGS: 00000246 ORIG_RAX: 0000000000000101 RAX: ffffffffffffffda RBX: 0000561178c069b0 RCX: 00007f45f5e5ce02 RDX: 0000000000000241 RSI: 0000561178c08800 RDI: 00000000ffffff9c RBP: 00007fff95e0d3e0 R08: 0000000000000020 R09: 0000000000000005 R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000003 R14: 0000000000000001 R15: 0000561178c08800 Change the return type to int and return -EPERM when lockdown is enabled to remove the warning above. Also rename debugfs_is_locked_down to debugfs_locked_down to make it sound less like it returns a boolean. Fixes: 5496197f9b08 ("debugfs: Restrict debugfs when the kernel is locked down") Signed-off-by: Eric Snowberg Reviewed-by: Matthew Wilcox (Oracle) Cc: stable Acked-by: James Morris Link: https://lore.kernel.org/r/20191207161603.35907-1-eric.snowberg@oracle.com Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/file.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 8be46add9105..634b09d18b77 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -142,18 +142,21 @@ EXPORT_SYMBOL_GPL(debugfs_file_put); * We also need to exclude any file that has ways to write or alter it as root * can bypass the permissions check. */ -static bool debugfs_is_locked_down(struct inode *inode, - struct file *filp, - const struct file_operations *real_fops) +static int debugfs_locked_down(struct inode *inode, + struct file *filp, + const struct file_operations *real_fops) { if ((inode->i_mode & 07777) == 0444 && !(filp->f_mode & FMODE_WRITE) && !real_fops->unlocked_ioctl && !real_fops->compat_ioctl && !real_fops->mmap) - return false; + return 0; - return security_locked_down(LOCKDOWN_DEBUGFS); + if (security_locked_down(LOCKDOWN_DEBUGFS)) + return -EPERM; + + return 0; } static int open_proxy_open(struct inode *inode, struct file *filp) @@ -168,7 +171,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp) real_fops = debugfs_real_fops(filp); - r = debugfs_is_locked_down(inode, filp, real_fops); + r = debugfs_locked_down(inode, filp, real_fops); if (r) goto out; @@ -298,7 +301,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp) real_fops = debugfs_real_fops(filp); - r = debugfs_is_locked_down(inode, filp, real_fops); + r = debugfs_locked_down(inode, filp, real_fops); if (r) goto out; -- cgit v1.2.3-59-g8ed1b From f3c19481820cca412a768ae1d6737f59b68acfed Mon Sep 17 00:00:00 2001 From: Zeng Tao Date: Fri, 17 Jan 2020 09:52:52 +0800 Subject: cpu-topology: Don't error on more than CONFIG_NR_CPUS CPUs in device tree When the kernel is configured with CONFIG_NR_CPUS smaller than the number of CPU nodes in the device tree(DT), all the CPU nodes parsing done to fetch topology information will fail. This is not reasonable as it is legal to have all the physical CPUs in the system in the DT. Let us just skip such CPU DT nodes that are not used in the kernel rather than returning an error. Reviewed-by: Sudeep Holla Signed-off-by: Zeng Tao Link: https://lore.kernel.org/r/1579225973-32423-1-git-send-email-prime.zeng@hisilicon.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/arch_topology.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 1eb81f113786..6119e11a9f95 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -248,6 +248,16 @@ core_initcall(free_raw_capacity); #endif #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV) +/* + * This function returns the logic cpu number of the node. + * There are basically three kinds of return values: + * (1) logic cpu number which is > 0. + * (2) -ENODEV when the device tree(DT) node is valid and found in the DT but + * there is no possible logical CPU in the kernel to match. This happens + * when CONFIG_NR_CPUS is configure to be smaller than the number of + * CPU nodes in DT. We need to just ignore this case. + * (3) -1 if the node does not exist in the device tree + */ static int __init get_cpu_for_node(struct device_node *node) { struct device_node *cpu_node; @@ -261,7 +271,8 @@ static int __init get_cpu_for_node(struct device_node *node) if (cpu >= 0) topology_parse_cpu_capacity(cpu_node, cpu); else - pr_crit("Unable to find CPU node for %pOF\n", cpu_node); + pr_info("CPU node for %pOF exist but the possible cpu range is :%*pbl\n", + cpu_node, cpumask_pr_args(cpu_possible_mask)); of_node_put(cpu_node); return cpu; @@ -286,9 +297,8 @@ static int __init parse_core(struct device_node *core, int package_id, cpu_topology[cpu].package_id = package_id; cpu_topology[cpu].core_id = core_id; cpu_topology[cpu].thread_id = i; - } else { - pr_err("%pOF: Can't get CPU for thread\n", - t); + } else if (cpu != -ENODEV) { + pr_err("%pOF: Can't get CPU for thread\n", t); of_node_put(t); return -EINVAL; } @@ -307,7 +317,7 @@ static int __init parse_core(struct device_node *core, int package_id, cpu_topology[cpu].package_id = package_id; cpu_topology[cpu].core_id = core_id; - } else if (leaf) { + } else if (leaf && cpu != -ENODEV) { pr_err("%pOF: Can't get CPU for leaf core\n", core); return -EINVAL; } -- cgit v1.2.3-59-g8ed1b From 0707cfa5c3ef58effb143db9db6d6e20503f9dec Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 16 Jan 2020 17:57:58 +0000 Subject: driver core: platform: fix u32 greater or equal to zero comparison Currently the check that a u32 variable i is >= 0 is always true because the unsigned variable will never be negative, causing the loop to run forever. Fix this by changing the pre-decrement check to a zero check on i followed by a decrement of i. Addresses-Coverity: ("Unsigned compared against 0") Fixes: 39cc539f90d0 ("driver core: platform: Prevent resouce overflow from causing infinite loops") Signed-off-by: Colin Ian King Reviewed-by: Rafael J. Wysocki Link: https://lore.kernel.org/r/20200116175758.88396-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 864b53b3d598..7fa654f1288b 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -571,7 +571,7 @@ int platform_device_add(struct platform_device *pdev) pdev->id = PLATFORM_DEVID_AUTO; } - while (--i >= 0) { + while (i--) { struct resource *r = &pdev->resource[i]; if (r->parent) release_resource(r); -- cgit v1.2.3-59-g8ed1b From c9d6b287d786db3a6bf3d99c1d99cd7e1d639485 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 15 Jan 2020 19:41:49 +0100 Subject: devtmpfs: fix theoretical stale pointer deref in devtmpfsd() After complete(&setup_done), devtmpfs_init proceeds and may actually return, invalidating the *err pointer, before devtmpfsd() proceeds to reading back *err. This is of course completely theoretical since the error conditions never trigger in practice, and even if they did, nobody cares about the exit value from a kernel thread, so it doesn't matter if we happen to read back some garbage from some other stack frame. Still, this isn't a pattern that should be copy-pasted, so fix it. Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20200115184154.3492-2-linux@rasmusvillemoes.dk Signed-off-by: Greg Kroah-Hartman --- drivers/base/devtmpfs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 6cdbf1531238..ccb046fe12b7 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -390,12 +390,13 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, static int devtmpfsd(void *p) { - int *err = p; - *err = ksys_unshare(CLONE_NEWNS); - if (*err) + int err; + + err = ksys_unshare(CLONE_NEWNS); + if (err) goto out; - *err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); - if (*err) + err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); + if (err) goto out; ksys_chdir("/.."); /* will traverse into overmounted root */ ksys_chroot("."); @@ -421,8 +422,9 @@ static int devtmpfsd(void *p) } return 0; out: + *(int *)p = err; complete(&setup_done); - return *err; + return err; } /* -- cgit v1.2.3-59-g8ed1b From 0ff0e95e9909e6ddefc8caa3948f20c0cb3dd6fb Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 15 Jan 2020 19:41:50 +0100 Subject: devtmpfs: factor out setup part of devtmpfsd() Factor out the setup part of devtmpfsd() to make it a bit easier to see that we always call setup_done() exactly once (provided of course the kthread is succesfully created). Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20200115184154.3492-3-linux@rasmusvillemoes.dk Signed-off-by: Greg Kroah-Hartman --- drivers/base/devtmpfs.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index ccb046fe12b7..963889331bb4 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -388,7 +388,7 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, return handle_remove(name, dev); } -static int devtmpfsd(void *p) +static int devtmpfs_setup(void *p) { int err; @@ -400,7 +400,18 @@ static int devtmpfsd(void *p) goto out; ksys_chdir("/.."); /* will traverse into overmounted root */ ksys_chroot("."); +out: + *(int *)p = err; complete(&setup_done); + return err; +} + +static int devtmpfsd(void *p) +{ + int err = devtmpfs_setup(p); + + if (err) + return err; while (1) { spin_lock(&req_lock); while (requests) { @@ -421,10 +432,6 @@ static int devtmpfsd(void *p) schedule(); } return 0; -out: - *(int *)p = err; - complete(&setup_done); - return err; } /* -- cgit v1.2.3-59-g8ed1b From 21766d11d151c82eb41c09338c8e149da6019a8b Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 15 Jan 2020 19:41:51 +0100 Subject: devtmpfs: simplify initialization of mount_dev Avoid a bit of ifdeffery by using the IS_ENABLED() helper. Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20200115184154.3492-4-linux@rasmusvillemoes.dk Signed-off-by: Greg Kroah-Hartman --- drivers/base/devtmpfs.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 963889331bb4..693390d9c545 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -30,11 +30,7 @@ static struct task_struct *thread; -#if defined CONFIG_DEVTMPFS_MOUNT -static int mount_dev = 1; -#else -static int mount_dev; -#endif +static int mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT); static DEFINE_SPINLOCK(req_lock); -- cgit v1.2.3-59-g8ed1b From fad1db8a351cc913bbfb9ee4fe7ca4939cb19f2e Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 15 Jan 2020 19:41:52 +0100 Subject: devtmpfs: initify a bit devtmpfs_mount() is only called from prepare_namespace() in init/do_mounts.c, which is an __init function, so devtmpfs_mount() can also be moved to .init.text. Then the mount_dev static variable is only referenced from __init functions (devtmpfs_mount and its initializer function mount_param). Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20200115184154.3492-5-linux@rasmusvillemoes.dk Signed-off-by: Greg Kroah-Hartman --- drivers/base/devtmpfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 693390d9c545..56632fb22fc0 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -30,7 +30,7 @@ static struct task_struct *thread; -static int mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT); +static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT); static DEFINE_SPINLOCK(req_lock); @@ -355,7 +355,7 @@ static int handle_remove(const char *nodename, struct device *dev) * If configured, or requested by the commandline, devtmpfs will be * auto-mounted after the kernel mounted the root filesystem. */ -int devtmpfs_mount(void) +int __init devtmpfs_mount(void) { int err; -- cgit v1.2.3-59-g8ed1b From 72a9cc952f123948ca1d1011a12e5e1312140b68 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 15 Jan 2020 19:41:53 +0100 Subject: devtmpfs: factor out common tail of devtmpfs_{create,delete}_node There's some common boilerplate in devtmpfs_{create,delete}_node, put that in a little helper. Signed-off-by: Rasmus Villemoes Link: https://lore.kernel.org/r/20200115184154.3492-6-linux@rasmusvillemoes.dk Signed-off-by: Greg Kroah-Hartman --- drivers/base/devtmpfs.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 56632fb22fc0..5995c437cbdf 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -89,6 +89,23 @@ static inline int is_blockdev(struct device *dev) static inline int is_blockdev(struct device *dev) { return 0; } #endif +static int devtmpfs_submit_req(struct req *req, const char *tmp) +{ + init_completion(&req->done); + + spin_lock(&req_lock); + req->next = requests; + requests = req; + spin_unlock(&req_lock); + + wake_up_process(thread); + wait_for_completion(&req->done); + + kfree(tmp); + + return req->err; +} + int devtmpfs_create_node(struct device *dev) { const char *tmp = NULL; @@ -113,19 +130,7 @@ int devtmpfs_create_node(struct device *dev) req.dev = dev; - init_completion(&req.done); - - spin_lock(&req_lock); - req.next = requests; - requests = &req; - spin_unlock(&req_lock); - - wake_up_process(thread); - wait_for_completion(&req.done); - - kfree(tmp); - - return req.err; + return devtmpfs_submit_req(&req, tmp); } int devtmpfs_delete_node(struct device *dev) @@ -143,18 +148,7 @@ int devtmpfs_delete_node(struct device *dev) req.mode = 0; req.dev = dev; - init_completion(&req.done); - - spin_lock(&req_lock); - req.next = requests; - requests = &req; - spin_unlock(&req_lock); - - wake_up_process(thread); - wait_for_completion(&req.done); - - kfree(tmp); - return req.err; + return devtmpfs_submit_req(&req, tmp); } static int dev_mkdir(const char *name, umode_t mode) -- cgit v1.2.3-59-g8ed1b From 85db1cde825344cc1419d3adadaf4187154ad687 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 15 Jan 2020 17:35:47 +0100 Subject: firmware: Rename FW_OPT_NOFALLBACK to FW_OPT_NOFALLBACK_SYSFS This is a preparation patch for adding a new platform fallback mechanism, which will have its own enable/disable FW_OPT_xxx option. Note this also fixes a typo in one of the re-wordwrapped comments: enfoce -> enforce. Acked-by: Luis Chamberlain Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20200115163554.101315-4-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_loader/fallback.c | 11 ++++++----- drivers/base/firmware_loader/firmware.h | 16 ++++++++-------- drivers/base/firmware_loader/main.c | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 62ee90b4db56..8704e1bae175 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -606,7 +606,7 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) return false; } - if ((opt_flags & FW_OPT_NOFALLBACK)) + if ((opt_flags & FW_OPT_NOFALLBACK_SYSFS)) return false; /* Also permit LSMs and IMA to fail firmware sysfs fallback */ @@ -630,10 +630,11 @@ static bool fw_run_sysfs_fallback(enum fw_opt opt_flags) * interface. Userspace is in charge of loading the firmware through the sysfs * loading interface. This sysfs fallback mechanism may be disabled completely * on a system by setting the proc sysctl value ignore_sysfs_fallback to true. - * If this false we check if the internal API caller set the @FW_OPT_NOFALLBACK - * flag, if so it would also disable the fallback mechanism. A system may want - * to enfoce the sysfs fallback mechanism at all times, it can do this by - * setting ignore_sysfs_fallback to false and force_sysfs_fallback to true. + * If this is false we check if the internal API caller set the + * @FW_OPT_NOFALLBACK_SYSFS flag, if so it would also disable the fallback + * mechanism. A system may want to enforce the sysfs fallback mechanism at all + * times, it can do this by setting ignore_sysfs_fallback to false and + * force_sysfs_fallback to true. * Enabling force_sysfs_fallback is functionally equivalent to build a kernel * with CONFIG_FW_LOADER_USER_HELPER_FALLBACK. **/ diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 7ecd590e67fe..8656e5239a80 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -27,16 +27,16 @@ * firmware file lookup on storage is avoided. Used for calls where the * file may be too big, or where the driver takes charge of its own * firmware caching mechanism. - * @FW_OPT_NOFALLBACK: Disable the fallback mechanism. Takes precedence over - * &FW_OPT_UEVENT and &FW_OPT_USERHELPER. + * @FW_OPT_NOFALLBACK_SYSFS: Disable the sysfs fallback mechanism. Takes + * precedence over &FW_OPT_UEVENT and &FW_OPT_USERHELPER. */ enum fw_opt { - FW_OPT_UEVENT = BIT(0), - FW_OPT_NOWAIT = BIT(1), - FW_OPT_USERHELPER = BIT(2), - FW_OPT_NO_WARN = BIT(3), - FW_OPT_NOCACHE = BIT(4), - FW_OPT_NOFALLBACK = BIT(5), + FW_OPT_UEVENT = BIT(0), + FW_OPT_NOWAIT = BIT(1), + FW_OPT_USERHELPER = BIT(2), + FW_OPT_NO_WARN = BIT(3), + FW_OPT_NOCACHE = BIT(4), + FW_OPT_NOFALLBACK_SYSFS = BIT(5), }; enum fw_status { diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 249add8c5e05..57133a9dad09 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -877,7 +877,7 @@ int request_firmware_direct(const struct firmware **firmware_p, __module_get(THIS_MODULE); ret = _request_firmware(firmware_p, name, device, NULL, 0, FW_OPT_UEVENT | FW_OPT_NO_WARN | - FW_OPT_NOFALLBACK); + FW_OPT_NOFALLBACK_SYSFS); module_put(THIS_MODULE); return ret; } -- cgit v1.2.3-59-g8ed1b